
PLUGIN_REQUIRED_PATCHES -   11/26/97

This patch file makes the tclplugin 2.0.5beta work with the Tcl/Tk
8.0p2 dash-patches. It should be applied by running the "patch"
program in the top-level directory of a clean tclplugin-2.0.5beta
release, using the command "patch -p0 <PLUGIN_REQUIRED_PATCHES"

Probably (and hopefully) this patch will work unchanged with later
plugins (2.0.6, 2.0.7 .....) as well.

If you are using Solaris, don't be surprised if the patch utility
does not work. This is a known problem. Better install GNU patch
version 2.1 or later.

*** generic/tkCanvPs.c.orig	Sat Nov 15 03:23:41 1997
--- generic/tkCanvPs.c	Sun Nov 23 01:51:31 1997
***************
*** 68,73 ****
--- 68,75 ----
  				 * the pre-pass that collects font information,
  				 * so the Postscript generated isn't
  				 * relevant. */
+     int prolog;			/* Non-zero means output should contain
+ 				   the file prolog.ps in the header. */
  } TkPostscriptInfo;
  
  /*
***************
*** 99,104 ****
--- 101,108 ----
  	"", Tk_Offset(TkPostscriptInfo, pageXString), 0},
      {TK_CONFIG_STRING, "-pagey", (char *) NULL, (char *) NULL,
  	"", Tk_Offset(TkPostscriptInfo, pageYString), 0},
+     {TK_CONFIG_BOOLEAN, "-prolog", (char *) NULL, (char *) NULL,
+ 	"", Tk_Offset(TkPostscriptInfo, prolog), 0},
      {TK_CONFIG_BOOLEAN, "-rotate", (char *) NULL, (char *) NULL,
  	"", Tk_Offset(TkPostscriptInfo, rotate), 0},
      {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
***************
*** 460,472 ****
  					 * to know that argv[1] is
  					 * "postscript". */
  {
!     TkPostscriptInfo psInfo, *oldInfoPtr;
      int result;
      Tk_Item *itemPtr;
  #define STRING_LENGTH 400
      char string[STRING_LENGTH+1], *p;
      time_t now;
      size_t length;
      int deltaX = 0, deltaY = 0;		/* Offset of lower-left corner of
  					 * area to be marked up, measured
  					 * in canvas units from the positioning
--- 464,478 ----
  					 * to know that argv[1] is
  					 * "postscript". */
  {
!     TkPostscriptInfo psInfo;
!     Tk_PostscriptInfo oldInfoPtr;
      int result;
      Tk_Item *itemPtr;
  #define STRING_LENGTH 400
      char string[STRING_LENGTH+1], *p;
      time_t now;
      size_t length;
+     Tk_Window tkwin = canvasPtr->tkwin;
      int deltaX = 0, deltaY = 0;		/* Offset of lower-left corner of
  					 * area to be marked up, measured
  					 * in canvas units from the positioning
***************
*** 486,493 ****
       *----------------------------------------------------------------
       */
  
!     oldInfoPtr = canvasPtr->psInfoPtr;
!     canvasPtr->psInfoPtr = &psInfo;
      psInfo.x = canvasPtr->xOrigin;
      psInfo.y = canvasPtr->yOrigin;
      psInfo.width = -1;
--- 492,499 ----
       *----------------------------------------------------------------
       */
  
!     oldInfoPtr = canvasPtr->psInfo;
!     canvasPtr->psInfo = (Tk_PostscriptInfo) &psInfo;
      psInfo.x = canvasPtr->xOrigin;
      psInfo.y = canvasPtr->yOrigin;
      psInfo.width = -1;
***************
*** 509,516 ****
      psInfo.channelName = NULL;
      psInfo.chan = NULL;
      psInfo.prepass = 0;
      Tcl_InitHashTable(&psInfo.fontTable, TCL_STRING_KEYS);
!     result = Tk_ConfigureWidget(canvasPtr->interp, canvasPtr->tkwin,
  	    configSpecs, argc-2, argv+2, (char *) &psInfo,
  	    TK_CONFIG_ARGV_ONLY);
      if (result != TCL_OK) {
--- 515,523 ----
      psInfo.channelName = NULL;
      psInfo.chan = NULL;
      psInfo.prepass = 0;
+     psInfo.prolog = 1;
      Tcl_InitHashTable(&psInfo.fontTable, TCL_STRING_KEYS);
!     result = Tk_ConfigureWidget(interp, tkwin,
  	    configSpecs, argc-2, argv+2, (char *) &psInfo,
  	    TK_CONFIG_ARGV_ONLY);
      if (result != TCL_OK) {
***************
*** 518,558 ****
      }
  
      if (psInfo.width == -1) {
! 	psInfo.width = Tk_Width(canvasPtr->tkwin);
      }
      if (psInfo.height == -1) {
! 	psInfo.height = Tk_Height(canvasPtr->tkwin);
      }
      psInfo.x2 = psInfo.x + psInfo.width;
      psInfo.y2 = psInfo.y + psInfo.height;
  
      if (psInfo.pageXString != NULL) {
! 	if (GetPostscriptPoints(canvasPtr->interp, psInfo.pageXString,
  		&psInfo.pageX) != TCL_OK) {
  	    goto cleanup;
  	}
      }
      if (psInfo.pageYString != NULL) {
! 	if (GetPostscriptPoints(canvasPtr->interp, psInfo.pageYString,
  		&psInfo.pageY) != TCL_OK) {
  	    goto cleanup;
  	}
      }
      if (psInfo.pageWidthString != NULL) {
! 	if (GetPostscriptPoints(canvasPtr->interp, psInfo.pageWidthString,
  		&psInfo.scale) != TCL_OK) {
  	    goto cleanup;
  	}
  	psInfo.scale /= psInfo.width;
      } else if (psInfo.pageHeightString != NULL) {
! 	if (GetPostscriptPoints(canvasPtr->interp, psInfo.pageHeightString,
  		&psInfo.scale) != TCL_OK) {
  	    goto cleanup;
  	}
  	psInfo.scale /= psInfo.height;
      } else {
! 	psInfo.scale = (72.0/25.4)*WidthMMOfScreen(Tk_Screen(canvasPtr->tkwin));
! 	psInfo.scale /= WidthOfScreen(Tk_Screen(canvasPtr->tkwin));
      }
      switch (psInfo.pageAnchor) {
  	case TK_ANCHOR_NW:
--- 525,565 ----
      }
  
      if (psInfo.width == -1) {
! 	psInfo.width = Tk_Width(tkwin);
      }
      if (psInfo.height == -1) {
! 	psInfo.height = Tk_Height(tkwin);
      }
      psInfo.x2 = psInfo.x + psInfo.width;
      psInfo.y2 = psInfo.y + psInfo.height;
  
      if (psInfo.pageXString != NULL) {
! 	if (GetPostscriptPoints(interp, psInfo.pageXString,
  		&psInfo.pageX) != TCL_OK) {
  	    goto cleanup;
  	}
      }
      if (psInfo.pageYString != NULL) {
! 	if (GetPostscriptPoints(interp, psInfo.pageYString,
  		&psInfo.pageY) != TCL_OK) {
  	    goto cleanup;
  	}
      }
      if (psInfo.pageWidthString != NULL) {
! 	if (GetPostscriptPoints(interp, psInfo.pageWidthString,
  		&psInfo.scale) != TCL_OK) {
  	    goto cleanup;
  	}
  	psInfo.scale /= psInfo.width;
      } else if (psInfo.pageHeightString != NULL) {
! 	if (GetPostscriptPoints(interp, psInfo.pageHeightString,
  		&psInfo.scale) != TCL_OK) {
  	    goto cleanup;
  	}
  	psInfo.scale /= psInfo.height;
      } else {
! 	psInfo.scale = (72.0/25.4)*WidthMMOfScreen(Tk_Screen(tkwin));
! 	psInfo.scale /= WidthOfScreen(Tk_Screen(tkwin));
      }
      switch (psInfo.pageAnchor) {
  	case TK_ANCHOR_NW:
***************
*** 600,606 ****
  	} else if (strncmp(psInfo.colorMode, "color", length) == 0) {
  	    psInfo.colorLevel = 2;
  	} else {
! 	    Tcl_AppendResult(canvasPtr->interp, "bad color mode \"",
  		    psInfo.colorMode, "\": must be monochrome, ",
  		    "gray, or color", (char *) NULL);
  	    goto cleanup;
--- 607,613 ----
  	} else if (strncmp(psInfo.colorMode, "color", length) == 0) {
  	    psInfo.colorLevel = 2;
  	} else {
! 	    Tcl_AppendResult(interp, "bad color mode \"",
  		    psInfo.colorMode, "\": must be monochrome, ",
  		    "gray, or color", (char *) NULL);
  	    goto cleanup;
***************
*** 614,620 ****
           */
  
          if (psInfo.channelName != NULL) {
!             Tcl_AppendResult(canvasPtr->interp, "can't specify both -file",
                      " and -channel", (char *) NULL);
              result = TCL_ERROR;
              goto cleanup;
--- 621,627 ----
           */
  
          if (psInfo.channelName != NULL) {
!             Tcl_AppendResult(interp, "can't specify both -file",
                      " and -channel", (char *) NULL);
              result = TCL_ERROR;
              goto cleanup;
***************
*** 625,642 ****
           * the -file specification.
           */
  
!         if (Tcl_IsSafe(canvasPtr->interp)) {
!             Tcl_AppendResult(canvasPtr->interp, "can't specify -file in a",
                      " safe interpreter", (char *) NULL);
              result = TCL_ERROR;
              goto cleanup;
          }
          
! 	p = Tcl_TranslateFileName(canvasPtr->interp, psInfo.fileName, &buffer);
  	if (p == NULL) {
  	    goto cleanup;
  	}
! 	psInfo.chan = Tcl_OpenFileChannel(canvasPtr->interp, p, "w", 0666);
  	Tcl_DStringFree(&buffer);
  	if (psInfo.chan == NULL) {
  	    goto cleanup;
--- 632,649 ----
           * the -file specification.
           */
  
!         if (Tcl_IsSafe(interp)) {
!             Tcl_AppendResult(interp, "can't specify -file in a",
                      " safe interpreter", (char *) NULL);
              result = TCL_ERROR;
              goto cleanup;
          }
          
! 	p = Tcl_TranslateFileName(interp, psInfo.fileName, &buffer);
  	if (p == NULL) {
  	    goto cleanup;
  	}
! 	psInfo.chan = Tcl_OpenFileChannel(interp, p, "w", 0666);
  	Tcl_DStringFree(&buffer);
  	if (psInfo.chan == NULL) {
  	    goto cleanup;
***************
*** 651,664 ****
           * is open for writing.
           */
  
!         psInfo.chan = Tcl_GetChannel(canvasPtr->interp, psInfo.channelName,
                  &mode);
          if (psInfo.chan == (Tcl_Channel) NULL) {
              result = TCL_ERROR;
              goto cleanup;
          }
          if ((mode & TCL_WRITABLE) == 0) {
!             Tcl_AppendResult(canvasPtr->interp, "channel \"",
                      psInfo.channelName, "\" wasn't opened for writing",
                      (char *) NULL);
              result = TCL_ERROR;
--- 658,671 ----
           * is open for writing.
           */
  
!         psInfo.chan = Tcl_GetChannel(interp, psInfo.channelName,
                  &mode);
          if (psInfo.chan == (Tcl_Channel) NULL) {
              result = TCL_ERROR;
              goto cleanup;
          }
          if ((mode & TCL_WRITABLE) == 0) {
!             Tcl_AppendResult(interp, "channel \"",
                      psInfo.channelName, "\" wasn't opened for writing",
                      (char *) NULL);
              result = TCL_ERROR;
***************
*** 686,694 ****
  	if (itemPtr->typePtr->postscriptProc == NULL) {
  	    continue;
  	}
! 	result = (*itemPtr->typePtr->postscriptProc)(canvasPtr->interp,
  		(Tk_Canvas) canvasPtr, itemPtr, 1);
! 	Tcl_ResetResult(canvasPtr->interp);
  	if (result != TCL_OK) {
  	    /*
  	     * An error just occurred.  Just skip out of this loop.
--- 693,701 ----
  	if (itemPtr->typePtr->postscriptProc == NULL) {
  	    continue;
  	}
! 	result = (*itemPtr->typePtr->postscriptProc)(interp,
  		(Tk_Canvas) canvasPtr, itemPtr, 1);
! 	Tcl_ResetResult(interp);
  	if (result != TCL_OK) {
  	    /*
  	     * An error just occurred.  Just skip out of this loop.
***************
*** 708,728 ****
       *--------------------------------------------------------
       */
  
!     Tcl_AppendResult(canvasPtr->interp, "%!PS-Adobe-3.0 EPSF-3.0\n",
  	    "%%Creator: Tk Canvas Widget\n", (char *) NULL);
  #if !(defined(__WIN32__) || defined(MAC_TCL))
      if (!Tcl_IsSafe(interp)) {
  	struct passwd *pwPtr = getpwuid(getuid());
! 	Tcl_AppendResult(canvasPtr->interp, "%%For: ",
  		(pwPtr != NULL) ? pwPtr->pw_gecos : "Unknown", "\n",
  		(char *) NULL);
  	endpwent();
      }
  #endif /* __WIN32__ || MAC_TCL */
!     Tcl_AppendResult(canvasPtr->interp, "%%Title: Window ",
! 	    Tk_PathName(canvasPtr->tkwin), "\n", (char *) NULL);
      time(&now);
!     Tcl_AppendResult(canvasPtr->interp, "%%CreationDate: ",
  	    ctime(&now), (char *) NULL);
      if (!psInfo.rotate) {
  	sprintf(string, "%d %d %d %d",
--- 715,736 ----
       *--------------------------------------------------------
       */
  
!     if (psInfo.prolog) {
!     Tcl_AppendResult(interp, "%!PS-Adobe-3.0 EPSF-3.0\n",
  	    "%%Creator: Tk Canvas Widget\n", (char *) NULL);
  #if !(defined(__WIN32__) || defined(MAC_TCL))
      if (!Tcl_IsSafe(interp)) {
  	struct passwd *pwPtr = getpwuid(getuid());
! 	Tcl_AppendResult(interp, "%%For: ",
  		(pwPtr != NULL) ? pwPtr->pw_gecos : "Unknown", "\n",
  		(char *) NULL);
  	endpwent();
      }
  #endif /* __WIN32__ || MAC_TCL */
!     Tcl_AppendResult(interp, "%%Title: Window ",
! 	    Tk_PathName(tkwin), "\n", (char *) NULL);
      time(&now);
!     Tcl_AppendResult(interp, "%%CreationDate: ",
  	    ctime(&now), (char *) NULL);
      if (!psInfo.rotate) {
  	sprintf(string, "%d %d %d %d",
***************
*** 740,760 ****
  		(int) (psInfo.pageY + psInfo.scale*(deltaX + psInfo.width)
  			+ 1.0));
      }
!     Tcl_AppendResult(canvasPtr->interp, "%%BoundingBox: ", string,
  	    "\n", (char *) NULL);
!     Tcl_AppendResult(canvasPtr->interp, "%%Pages: 1\n", 
  	    "%%DocumentData: Clean7Bit\n", (char *) NULL);
!     Tcl_AppendResult(canvasPtr->interp, "%%Orientation: ",
  	    psInfo.rotate ? "Landscape\n" : "Portrait\n", (char *) NULL);
      p = "%%DocumentNeededResources: font ";
      for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
  	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
! 	Tcl_AppendResult(canvasPtr->interp, p,
  		Tcl_GetHashKey(&psInfo.fontTable, hPtr),
  		"\n", (char *) NULL);
  	p = "%%+ font ";
      }
!     Tcl_AppendResult(canvasPtr->interp, "%%EndComments\n\n", (char *) NULL);
  
      /*
       * Insert the prolog
--- 748,768 ----
  		(int) (psInfo.pageY + psInfo.scale*(deltaX + psInfo.width)
  			+ 1.0));
      }
!     Tcl_AppendResult(interp, "%%BoundingBox: ", string,
  	    "\n", (char *) NULL);
!     Tcl_AppendResult(interp, "%%Pages: 1\n", 
  	    "%%DocumentData: Clean7Bit\n", (char *) NULL);
!     Tcl_AppendResult(interp, "%%Orientation: ",
  	    psInfo.rotate ? "Landscape\n" : "Portrait\n", (char *) NULL);
      p = "%%DocumentNeededResources: font ";
      for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
  	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
! 	Tcl_AppendResult(interp, p,
  		Tcl_GetHashKey(&psInfo.fontTable, hPtr),
  		"\n", (char *) NULL);
  	p = "%%+ font ";
      }
!     Tcl_AppendResult(interp, "%%EndComments\n\n", (char *) NULL);
  
      /*
       * Insert the prolog
***************
*** 764,771 ****
      }
  
      if (psInfo.chan != NULL) {
! 	Tcl_Write(psInfo.chan, canvasPtr->interp->result, -1);
! 	Tcl_ResetResult(canvasPtr->interp);
      }
  
      /*
--- 772,779 ----
      }
  
      if (psInfo.chan != NULL) {
! 	Tcl_Write(psInfo.chan, interp->result, -1);
! 	Tcl_ResetResult(interp);
      }
  
      /*
***************
*** 775,788 ****
       */
  
      sprintf(string, "/CL %d def\n", psInfo.colorLevel);
!     Tcl_AppendResult(canvasPtr->interp, "%%BeginSetup\n", string,
  	    (char *) NULL);
      for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
  	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
! 	Tcl_AppendResult(canvasPtr->interp, "%%IncludeResource: font ",
  		Tcl_GetHashKey(&psInfo.fontTable, hPtr), "\n", (char *) NULL);
      }
!     Tcl_AppendResult(canvasPtr->interp, "%%EndSetup\n\n", (char *) NULL);
  
      /*
       *-----------------------------------------------------------
--- 783,796 ----
       */
  
      sprintf(string, "/CL %d def\n", psInfo.colorLevel);
!     Tcl_AppendResult(interp, "%%BeginSetup\n", string,
  	    (char *) NULL);
      for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
  	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
! 	Tcl_AppendResult(interp, "%%IncludeResource: font ",
  		Tcl_GetHashKey(&psInfo.fontTable, hPtr), "\n", (char *) NULL);
      }
!     Tcl_AppendResult(interp, "%%EndSetup\n\n", (char *) NULL);
  
      /*
       *-----------------------------------------------------------
***************
*** 792,818 ****
       *-----------------------------------------------------------
       */
  
!     Tcl_AppendResult(canvasPtr->interp, "%%Page: 1 1\n", "save\n",
  	    (char *) NULL);
      sprintf(string, "%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY);
!     Tcl_AppendResult(canvasPtr->interp, string, (char *) NULL);
      if (psInfo.rotate) {
! 	Tcl_AppendResult(canvasPtr->interp, "90 rotate\n", (char *) NULL);
      }
      sprintf(string, "%.4g %.4g scale\n", psInfo.scale, psInfo.scale);
!     Tcl_AppendResult(canvasPtr->interp, string, (char *) NULL);
      sprintf(string, "%d %d translate\n", deltaX - psInfo.x, deltaY);
!     Tcl_AppendResult(canvasPtr->interp, string, (char *) NULL);
      sprintf(string, "%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g",
! 	    psInfo.x, Tk_CanvasPsY((Tk_Canvas) canvasPtr, (double) psInfo.y),
! 	    psInfo.x2, Tk_CanvasPsY((Tk_Canvas) canvasPtr, (double) psInfo.y),
! 	    psInfo.x2, Tk_CanvasPsY((Tk_Canvas) canvasPtr, (double) psInfo.y2),
! 	    psInfo.x, Tk_CanvasPsY((Tk_Canvas) canvasPtr, (double) psInfo.y2));
!     Tcl_AppendResult(canvasPtr->interp, string,
  	" lineto closepath clip newpath\n", (char *) NULL);
      if (psInfo.chan != NULL) {
! 	Tcl_Write(psInfo.chan, canvasPtr->interp->result, -1);
! 	Tcl_ResetResult(canvasPtr->interp);
      }
  
      /*
--- 800,831 ----
       *-----------------------------------------------------------
       */
  
!     Tcl_AppendResult(interp, "%%Page: 1 1\n", "save\n",
  	    (char *) NULL);
      sprintf(string, "%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY);
!     Tcl_AppendResult(interp, string, (char *) NULL);
      if (psInfo.rotate) {
! 	Tcl_AppendResult(interp, "90 rotate\n", (char *) NULL);
      }
      sprintf(string, "%.4g %.4g scale\n", psInfo.scale, psInfo.scale);
!     Tcl_AppendResult(interp, string, (char *) NULL);
      sprintf(string, "%d %d translate\n", deltaX - psInfo.x, deltaY);
!     Tcl_AppendResult(interp, string, (char *) NULL);
      sprintf(string, "%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g",
! 	    psInfo.x,
! 	    Tk_PostscriptY((double) psInfo.y, (Tk_PostscriptInfo) &psInfo),
! 	    psInfo.x2,
! 	    Tk_PostscriptY((double) psInfo.y, (Tk_PostscriptInfo) &psInfo),
! 	    psInfo.x2, 
! 	    Tk_PostscriptY((double) psInfo.y2, (Tk_PostscriptInfo) &psInfo),
! 	    psInfo.x,
! 	    Tk_PostscriptY((double) psInfo.y2, (Tk_PostscriptInfo) &psInfo));
!     Tcl_AppendResult(interp, string,
  	" lineto closepath clip newpath\n", (char *) NULL);
+     }
      if (psInfo.chan != NULL) {
! 	Tcl_Write(psInfo.chan, interp->result, -1);
! 	Tcl_ResetResult(interp);
      }
  
      /*
***************
*** 832,852 ****
  	if (itemPtr->typePtr->postscriptProc == NULL) {
  	    continue;
  	}
! 	Tcl_AppendResult(canvasPtr->interp, "gsave\n", (char *) NULL);
! 	result = (*itemPtr->typePtr->postscriptProc)(canvasPtr->interp,
  		(Tk_Canvas) canvasPtr, itemPtr, 0);
  	if (result != TCL_OK) {
  	    char msg[100];
  
  	    sprintf(msg, "\n    (generating Postscript for item %d)",
  		    itemPtr->id);
! 	    Tcl_AddErrorInfo(canvasPtr->interp, msg);
  	    goto cleanup;
  	}
! 	Tcl_AppendResult(canvasPtr->interp, "grestore\n", (char *) NULL);
  	if (psInfo.chan != NULL) {
! 	    Tcl_Write(psInfo.chan, canvasPtr->interp->result, -1);
! 	    Tcl_ResetResult(canvasPtr->interp);
  	}
      }
  
--- 845,868 ----
  	if (itemPtr->typePtr->postscriptProc == NULL) {
  	    continue;
  	}
! 	if (itemPtr->state == TK_STATE_HIDDEN) {
! 	    continue;
! 	}
! 	Tcl_AppendResult(interp, "gsave\n", (char *) NULL);
! 	result = (*itemPtr->typePtr->postscriptProc)(interp,
  		(Tk_Canvas) canvasPtr, itemPtr, 0);
  	if (result != TCL_OK) {
  	    char msg[100];
  
  	    sprintf(msg, "\n    (generating Postscript for item %d)",
  		    itemPtr->id);
! 	    Tcl_AddErrorInfo(interp, msg);
  	    goto cleanup;
  	}
! 	Tcl_AppendResult(interp, "grestore\n", (char *) NULL);
  	if (psInfo.chan != NULL) {
! 	    Tcl_Write(psInfo.chan, interp->result, -1);
! 	    Tcl_ResetResult(interp);
  	}
      }
  
***************
*** 857,867 ****
       *---------------------------------------------------------------------
       */
  
!     Tcl_AppendResult(canvasPtr->interp, "restore showpage\n\n",
! 	    "%%Trailer\nend\n%%EOF\n", (char *) NULL);
      if (psInfo.chan != NULL) {
! 	Tcl_Write(psInfo.chan, canvasPtr->interp->result, -1);
! 	Tcl_ResetResult(canvasPtr->interp);
      }
  
      /*
--- 873,885 ----
       *---------------------------------------------------------------------
       */
  
!     if (psInfo.prolog) {
! 	Tcl_AppendResult(interp, "restore showpage\n\n",
! 		"%%Trailer\nend\n%%EOF\n", (char *) NULL);
!     }
      if (psInfo.chan != NULL) {
! 	Tcl_Write(psInfo.chan, interp->result, -1);
! 	Tcl_ResetResult(interp);
      }
  
      /*
***************
*** 894,913 ****
  	ckfree(psInfo.fileName);
      }
      if ((psInfo.chan != NULL) && (psInfo.channelName == NULL)) {
! 	Tcl_Close(canvasPtr->interp, psInfo.chan);
      }
      if (psInfo.channelName != NULL) {
          ckfree(psInfo.channelName);
      }
      Tcl_DeleteHashTable(&psInfo.fontTable);
!     canvasPtr->psInfoPtr = oldInfoPtr;
      return result;
  }
  
  /*
   *--------------------------------------------------------------
   *
!  * Tk_CanvasPsColor --
   *
   *	This procedure is called by individual canvas items when
   *	they want to set a color value for output.  Given information
--- 912,931 ----
  	ckfree(psInfo.fileName);
      }
      if ((psInfo.chan != NULL) && (psInfo.channelName == NULL)) {
! 	Tcl_Close(interp, psInfo.chan);
      }
      if (psInfo.channelName != NULL) {
          ckfree(psInfo.channelName);
      }
      Tcl_DeleteHashTable(&psInfo.fontTable);
!     canvasPtr->psInfo = (Tk_PostscriptInfo) oldInfoPtr;
      return result;
  }
  
  /*
   *--------------------------------------------------------------
   *
!  * Tk_PostscriptColor --
   *
   *	This procedure is called by individual canvas items when
   *	they want to set a color value for output.  Given information
***************
*** 927,940 ****
   */
  
  int
! Tk_CanvasPsColor(interp, canvas, colorPtr)
!     Tcl_Interp *interp;			/* Interpreter for returning Postscript
! 					 * or error message. */
!     Tk_Canvas canvas;			/* Information about canvas. */
      XColor *colorPtr;			/* Information about color. */
  {
!     TkCanvas *canvasPtr = (TkCanvas *) canvas;
!     TkPostscriptInfo *psInfoPtr = canvasPtr->psInfoPtr;
      int tmp;
      double red, green, blue;
      char string[200];
--- 945,956 ----
   */
  
  int
! Tk_PostscriptColor(interp, psInfo, colorPtr)
!     Tcl_Interp *interp;
!     Tk_PostscriptInfo psInfo ;		/* Postscript info. */
      XColor *colorPtr;			/* Information about color. */
  {
!     TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
      int tmp;
      double red, green, blue;
      char string[200];
***************
*** 988,994 ****
  /*
   *--------------------------------------------------------------
   *
!  * Tk_CanvasPsFont --
   *
   *	This procedure is called by individual canvas items when
   *	they want to output text.  Given information about an X
--- 1004,1010 ----
  /*
   *--------------------------------------------------------------
   *
!  * Tk_PostscriptFont --
   *
   *	This procedure is called by individual canvas items when
   *	they want to output text.  Given information about an X
***************
*** 1009,1023 ****
   */
  
  int
! Tk_CanvasPsFont(interp, canvas, tkfont)
!     Tcl_Interp *interp;			/* Interpreter for returning Postscript
! 					 * or error message. */
!     Tk_Canvas canvas;			/* Information about canvas. */
      Tk_Font tkfont;			/* Information about font in which text
  					 * is to be printed. */
  {
!     TkCanvas *canvasPtr = (TkCanvas *) canvas;
!     TkPostscriptInfo *psInfoPtr = canvasPtr->psInfoPtr;
      char *end;
      char pointString[20];
      Tcl_DString ds;
--- 1025,1037 ----
   */
  
  int
! Tk_PostscriptFont(interp, psInfo, tkfont)
!     Tcl_Interp *interp;
!     Tk_PostscriptInfo psInfo;		/* Postscript Info. */
      Tk_Font tkfont;			/* Information about font in which text
  					 * is to be printed. */
  {
!     TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
      char *end;
      char pointString[20];
      Tcl_DString ds;
***************
*** 1082,1088 ****
  /*
   *--------------------------------------------------------------
   *
!  * Tk_CanvasPsBitmap --
   *
   *	This procedure is called to output the contents of a
   *	sub-region of a bitmap in proper image data format for
--- 1096,1102 ----
  /*
   *--------------------------------------------------------------
   *
!  * Tk_PostscriptBitmap --
   *
   *	This procedure is called to output the contents of a
   *	sub-region of a bitmap in proper image data format for
***************
*** 1102,1119 ****
   */
  
  int
! Tk_CanvasPsBitmap(interp, canvas, bitmap, startX, startY, width, height)
!     Tcl_Interp *interp;			/* Interpreter for returning Postscript
! 					 * or error message. */
!     Tk_Canvas canvas;			/* Information about canvas. */
      Pixmap bitmap;			/* Bitmap for which to generate
  					 * Postscript. */
      int startX, startY;			/* Coordinates of upper-left corner
  					 * of rectangular region to output. */
      int width, height;			/* Height of rectangular region. */
  {
!     TkCanvas *canvasPtr = (TkCanvas *) canvas;
!     TkPostscriptInfo *psInfoPtr = canvasPtr->psInfoPtr;
      XImage *imagePtr;
      int charsInLine, x, y, lastX, lastY, value, mask;
      unsigned int totalWidth, totalHeight;
--- 1116,1133 ----
   */
  
  int
! Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, startX, startY, width,
! 	height)
!     Tcl_Interp *interp;
!     Tk_Window tkwin;
!     Tk_PostscriptInfo psInfo;		/* Postscript info. */
      Pixmap bitmap;			/* Bitmap for which to generate
  					 * Postscript. */
      int startX, startY;			/* Coordinates of upper-left corner
  					 * of rectangular region to output. */
      int width, height;			/* Height of rectangular region. */
  {
!     TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
      XImage *imagePtr;
      int charsInLine, x, y, lastX, lastY, value, mask;
      unsigned int totalWidth, totalHeight;
***************
*** 1134,1143 ****
       * it shouldn't matter here.
       */
  
!     XGetGeometry(Tk_Display(Tk_CanvasTkwin(canvas)), bitmap, &dummyRoot,
  	    (int *) &dummyX, (int *) &dummyY, (unsigned int *) &totalWidth,
  	    (unsigned int *) &totalHeight, &dummyBorderwidth, &dummyDepth);
!     imagePtr = XGetImage(Tk_Display(canvasPtr->tkwin), bitmap, 0, 0,
  	    totalWidth, totalHeight, 1, XYPixmap);
      Tcl_AppendResult(interp, "<", (char *) NULL);
      mask = 0x80;
--- 1148,1157 ----
       * it shouldn't matter here.
       */
  
!     XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
  	    (int *) &dummyX, (int *) &dummyY, (unsigned int *) &totalWidth,
  	    (unsigned int *) &totalHeight, &dummyBorderwidth, &dummyDepth);
!     imagePtr = XGetImage(Tk_Display(tkwin), bitmap, 0, 0,
  	    totalWidth, totalHeight, 1, XYPixmap);
      Tcl_AppendResult(interp, "<", (char *) NULL);
      mask = 0x80;
***************
*** 1179,1185 ****
  /*
   *--------------------------------------------------------------
   *
!  * Tk_CanvasPsStipple --
   *
   *	This procedure is called by individual canvas items when
   *	they have created a path that they'd like to be filled with
--- 1193,1199 ----
  /*
   *--------------------------------------------------------------
   *
!  * Tk_PostscriptStipple --
   *
   *	This procedure is called by individual canvas items when
   *	they have created a path that they'd like to be filled with
***************
*** 1201,1214 ****
   */
  
  int
! Tk_CanvasPsStipple(interp, canvas, bitmap)
!     Tcl_Interp *interp;			/* Interpreter for returning Postscript
  					 * or error message. */
-     Tk_Canvas canvas;			/* Information about canvas. */
      Pixmap bitmap;			/* Bitmap to use for stippling. */
  {
!     TkCanvas *canvasPtr = (TkCanvas *) canvas;
!     TkPostscriptInfo *psInfoPtr = canvasPtr->psInfoPtr;
      int width, height;
      char string[100];
      Window dummyRoot;
--- 1215,1228 ----
   */
  
  int
! Tk_PostscriptStipple(interp, tkwin, psInfo, bitmap)
!     Tcl_Interp *interp;
!     Tk_Window tkwin;
!     Tk_PostscriptInfo psInfo;		/* Interpreter for returning Postscript
  					 * or error message. */
      Pixmap bitmap;			/* Bitmap to use for stippling. */
  {
!     TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
      int width, height;
      char string[100];
      Window dummyRoot;
***************
*** 1227,1238 ****
       * it shouldn't matter here.
       */
  
!     XGetGeometry(Tk_Display(Tk_CanvasTkwin(canvas)), bitmap, &dummyRoot,
  	    (int *) &dummyX, (int *) &dummyY, (unsigned *) &width,
  	    (unsigned *) &height, &dummyBorderwidth, &dummyDepth);
      sprintf(string, "%d %d ", width, height);
      Tcl_AppendResult(interp, string, (char *) NULL);
!     if (Tk_CanvasPsBitmap(interp, (Tk_Canvas) canvasPtr, bitmap, 0, 0,
  	    width, height) != TCL_OK) {
  	return TCL_ERROR;
      }
--- 1241,1252 ----
       * it shouldn't matter here.
       */
  
!     XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
  	    (int *) &dummyX, (int *) &dummyY, (unsigned *) &width,
  	    (unsigned *) &height, &dummyBorderwidth, &dummyDepth);
      sprintf(string, "%d %d ", width, height);
      Tcl_AppendResult(interp, string, (char *) NULL);
!     if (Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, 0, 0,
  	    width, height) != TCL_OK) {
  	return TCL_ERROR;
      }
***************
*** 1243,1251 ****
  /*
   *--------------------------------------------------------------
   *
!  * Tk_CanvasPsY --
   *
!  *	Given a y-coordinate in canvas coordinates, this procedure
   *	returns a y-coordinate to use for Postscript output.
   *
   * Results:
--- 1257,1265 ----
  /*
   *--------------------------------------------------------------
   *
!  * Tk_PostscriptY --
   *
!  *	Given a y-coordinate in local coordinates, this procedure
   *	returns a y-coordinate to use for Postscript output.
   *
   * Results:
***************
*** 1259,1270 ****
   */
  
  double
! Tk_CanvasPsY(canvas, y)
!     Tk_Canvas canvas;			/* Token for canvas on whose behalf
! 					 * Postscript is being generated. */
      double y;				/* Y-coordinate in canvas coords. */
  {
!     TkPostscriptInfo *psInfoPtr = ((TkCanvas *) canvas)->psInfoPtr;
  
      return psInfoPtr->y2 - y;
  }
--- 1273,1283 ----
   */
  
  double
! Tk_PostscriptY(y, psInfo)
      double y;				/* Y-coordinate in canvas coords. */
+     Tk_PostscriptInfo psInfo;		/* Postscript info */
  {
!     TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
  
      return psInfoPtr->y2 - y;
  }
***************
*** 1272,1278 ****
  /*
   *--------------------------------------------------------------
   *
!  * Tk_CanvasPsPath --
   *
   *	Given an array of points for a path, generate Postscript
   *	commands to create the path.
--- 1285,1291 ----
  /*
   *--------------------------------------------------------------
   *
!  * Tk_PostscriptPath --
   *
   *	Given an array of points for a path, generate Postscript
   *	commands to create the path.
***************
*** 1287,1315 ****
   */
  
  void
! Tk_CanvasPsPath(interp, canvas, coordPtr, numPoints)
!     Tcl_Interp *interp;			/* Put generated Postscript in this
! 					 * interpreter's result field. */
!     Tk_Canvas canvas;			/* Canvas on whose behalf Postscript
  					 * is being generated. */
      double *coordPtr;			/* Pointer to first in array of
  					 * 2*numPoints coordinates giving
  					 * points for path. */
      int numPoints;			/* Number of points at *coordPtr. */
  {
!     TkPostscriptInfo *psInfoPtr = ((TkCanvas *) canvas)->psInfoPtr;
      char buffer[200];
  
      if (psInfoPtr->prepass) {
  	return;
      }
      sprintf(buffer, "%.15g %.15g moveto\n", coordPtr[0],
! 	    Tk_CanvasPsY(canvas, coordPtr[1]));
      Tcl_AppendResult(interp, buffer, (char *) NULL);
      for (numPoints--, coordPtr += 2; numPoints > 0;
  	    numPoints--, coordPtr += 2) {
  	sprintf(buffer, "%.15g %.15g lineto\n", coordPtr[0],
! 		Tk_CanvasPsY(canvas, coordPtr[1]));
  	Tcl_AppendResult(interp, buffer, (char *) NULL);
      }
  }
--- 1300,1327 ----
   */
  
  void
! Tk_PostscriptPath(interp, psInfo, coordPtr, numPoints)
!     Tcl_Interp *interp;
!     Tk_PostscriptInfo psInfo;		/* Canvas on whose behalf Postscript
  					 * is being generated. */
      double *coordPtr;			/* Pointer to first in array of
  					 * 2*numPoints coordinates giving
  					 * points for path. */
      int numPoints;			/* Number of points at *coordPtr. */
  {
!     TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
      char buffer[200];
  
      if (psInfoPtr->prepass) {
  	return;
      }
      sprintf(buffer, "%.15g %.15g moveto\n", coordPtr[0],
! 	    Tk_PostscriptY(coordPtr[1], psInfo));
      Tcl_AppendResult(interp, buffer, (char *) NULL);
      for (numPoints--, coordPtr += 2; numPoints > 0;
  	    numPoints--, coordPtr += 2) {
  	sprintf(buffer, "%.15g %.15g lineto\n", coordPtr[0],
! 		Tk_PostscriptY(coordPtr[1], psInfo));
  	Tcl_AppendResult(interp, buffer, (char *) NULL);
      }
  }
***************
*** 1382,1386 ****
--- 1394,1681 ----
  	goto error;
      }
      *doublePtr = d;
+     return TCL_OK;
+ }
+ 
+ /*
+  *--------------------------------------------------------------
+  *
+  * TkImageGetColor --
+  *
+  *	This procedure converts a pixel value to three floating
+  *      point numbers, representing the amount of red, green, and 
+  *      blue in that pixel on the screen.  It makes use of colormap
+  *      data passed as an argument, and should work for all Visual
+  *      types.
+  *
+  * Results:
+  *	Returns red, green, and blue color values in the range 
+  *      0 to 1.  There are no error returns.
+  *
+  * Side effects:
+  *	None.
+  *
+  *--------------------------------------------------------------
+  */
+ 
+ static void
+ TkImageGetColor(cdata, pixel, red, green, blue)
+     TkColormapData *cdata;              /* Colormap data */
+     unsigned long pixel;                /* Pixel value to look up */
+     double *red, *green, *blue;         /* Color data to return */
+ {
+     if (cdata->separated) {
+         int r = (pixel & cdata->red_mask) >> cdata->red_shift;
+         int g = (pixel & cdata->green_mask) >> cdata->green_shift;
+         int b = (pixel & cdata->blue_mask) >> cdata->blue_shift;
+         *red = cdata->colors[r].red / 65535.0;
+         *green = cdata->colors[g].green / 65535.0;
+         *blue = cdata->colors[b].blue / 65535.0;
+     } else {
+         *red = cdata->colors[pixel].red / 65535.0;
+         *green = cdata->colors[pixel].green / 65535.0;
+         *blue = cdata->colors[pixel].blue / 65535.0;
+     }
+ }
+ 
+ /*
+  *--------------------------------------------------------------
+  *
+  * TkPostscriptImage --
+  *
+  *	This procedure is called to output the contents of an
+  *	image in Postscript, using a format appropriate for the 
+  *      current color mode (i.e. one bit per pixel in monochrome, 
+  *      one byte per pixel in gray, and three bytes per pixel in
+  *      color).
+  *
+  * Results:
+  *	Returns a standard Tcl return value.  If an error occurs
+  *	then an error message will be left in interp->result.
+  *	If no error occurs, then additional Postscript will be
+  *	appended to interp->result.
+  *
+  * Side effects:
+  *	None.
+  *
+  *--------------------------------------------------------------
+  */
+ 
+ int
+ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
+     Tcl_Interp *interp;
+     Tk_Window tkwin;
+     Tk_PostscriptInfo psInfo;	/* postscript info */
+     XImage *ximage;		/* Image to draw */
+     int x, y;			/* First pixel to output */
+     int width, height;		/* Width and height of area */
+ {
+     TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
+     char buffer[256];
+     int xx, yy, band, maxRows;
+     double red, green, blue;
+     int bytesPerLine=0, maxWidth=0;
+     int level = psInfoPtr->colorLevel;
+     Colormap cmap;
+     int i, depth, ncolors;
+     Visual *visual;
+     TkColormapData cdata;
+ 
+     if (psInfoPtr->prepass) {
+ 	return TCL_OK;
+     }
+ 
+     cmap = Tk_Colormap(tkwin);
+     depth = Tk_Depth(tkwin);
+     visual = Tk_Visual(tkwin);
+ 
+     /*
+      * Obtain information about the colormap, ie the mapping between
+      * pixel values and RGB values.  The code below should work
+      * for all Visual types.
+      */
+ 
+     ncolors = visual->map_entries;
+     cdata.colors = (XColor *) ckalloc(sizeof(XColor) * ncolors);
+     cdata.ncolors = ncolors;
+ 
+     if (visual->class == DirectColor || visual->class == TrueColor) {
+ 	cdata.separated = 1;
+ 	cdata.red_mask = visual->red_mask;
+ 	cdata.green_mask = visual->green_mask;
+ 	cdata.blue_mask = visual->blue_mask;
+ 	cdata.red_shift = 0;
+ 	cdata.green_shift = 0;
+ 	cdata.blue_shift = 0;
+ 	while ((0x0001 & (cdata.red_mask >> cdata.red_shift)) == 0)
+ 	    cdata.red_shift ++;
+ 	while ((0x0001 & (cdata.green_mask >> cdata.green_shift)) == 0)
+ 	    cdata.green_shift ++;
+ 	while ((0x0001 & (cdata.blue_mask >> cdata.blue_shift)) == 0)
+ 	    cdata.blue_shift ++;
+ 	for (i = 0; i < ncolors; i ++)
+ 	    cdata.colors[i].pixel =
+ 		((i << cdata.red_shift) & cdata.red_mask) |
+ 		((i << cdata.green_shift) & cdata.green_mask) |
+ 		((i << cdata.blue_shift) & cdata.blue_mask);
+     } else {
+ 	cdata.separated=0;
+ 	for (i = 0; i < ncolors; i ++)
+ 	    cdata.colors[i].pixel = i;
+     }
+     if (visual->class == StaticGray || visual->class == GrayScale)
+ 	cdata.color = 0;
+     else
+ 	cdata.color = 1;
+ 
+     XQueryColors(Tk_Display(tkwin), cmap, cdata.colors, ncolors);
+ 
+     /*
+      * Figure out which color level to use (possibly lower than the 
+      * one specified by the user).  For example, if the user specifies
+      * color with monochrome screen, use gray or monochrome mode instead. 
+      */
+ 
+     if (!cdata.color && level == 2) {
+         level = 1;
+     }
+ 
+     if (!cdata.color && cdata.ncolors == 2) {
+         level = 0;
+     }
+ 
+     /*
+      * Check that at least one row of the image can be represented
+      * with a string less than 64 KB long (this is a limit in the 
+      * Postscript interpreter).
+      */
+     
+     switch (level)
+     {
+         case 0: bytesPerLine = (width + 7) / 8;  maxWidth = 240000;  break;
+         case 1: bytesPerLine = width;  maxWidth = 60000;  break;
+         case 2: bytesPerLine = 3 * width;  maxWidth = 20000;  break;
+     }
+ 
+     if (bytesPerLine > 60000) {
+         Tcl_ResetResult(interp);
+         sprintf(buffer,
+                 "Can't generate Postscript for images more than %d pixels wide",
+                 maxWidth);
+         Tcl_AppendResult(interp, buffer, (char *) NULL);
+ 	ckfree((char *) cdata.colors);
+         return TCL_ERROR;
+     }
+ 
+     maxRows = 60000 / bytesPerLine;
+ 
+     for (band = height-1; band >= 0; band -= maxRows) {
+         int rows = (band >= maxRows) ? maxRows : band + 1;
+         int lineLen = 0;
+         switch (level) {
+             case 0:
+                 sprintf(buffer, "%d %d 1 matrix {\n<", width, rows);
+                 Tcl_AppendResult(interp, buffer, (char *) NULL);
+                 break;
+             case 1:
+                 sprintf(buffer, "%d %d 8 matrix {\n<", width, rows);
+                 Tcl_AppendResult(interp, buffer, (char *) NULL);
+                 break;
+             case 2:
+                 sprintf(buffer, "%d %d 8 matrix {\n<",
+                         width, rows);
+                 Tcl_AppendResult(interp, buffer, (char *) NULL);
+                 break;
+         }
+         for (yy = band; yy > band - rows; yy--) {
+             switch (level) {
+                 case 0: {
+                     /*
+                      * Generate data for image in monochrome mode.
+                      * No attempt at dithering is made--instead, just
+                      * set a threshold.
+                      */
+                     unsigned char mask=0x80;
+                     unsigned char data=0x00;
+                     for (xx = x; xx< x+width; xx++) {
+                         TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
+                                         &red, &green, &blue);
+                         if (0.30 * red + 0.59 * green + 0.11 * blue > 0.5)
+                             data |= mask;
+                         mask >>= 1;
+                         if (mask == 0) {
+                             sprintf(buffer, "%02X", data);
+                             Tcl_AppendResult(interp, buffer, (char *) NULL);
+                             lineLen += 2;
+                             if (lineLen > 60) {
+                                 lineLen = 0;
+                                 Tcl_AppendResult(interp, "\n", (char *) NULL);
+                             }
+                             mask=0x80;
+                             data=0x00;
+                         }
+                     }
+                     if ((width % 8) != 0) {
+                         sprintf(buffer, "%02X", data);
+                         Tcl_AppendResult(interp, buffer, (char *) NULL);
+                         mask=0x80;
+                         data=0x00;
+                     }
+                     break;
+                 }
+                 case 1: {
+                     /*
+                      * Generate data in gray mode--in this case, take a 
+                      * weighted sum of the red, green, and blue values.
+                      */
+                     for (xx = x; xx < x+width; xx ++) {
+                         TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
+                                         &red, &green, &blue);
+                         sprintf(buffer, "%02X", (int) floor(0.5 + 255.0 *
+                                                             (0.30 * red +
+                                                              0.59 * green +
+                                                              0.11 * blue)));
+                         Tcl_AppendResult(interp, buffer, (char *) NULL);
+                         lineLen += 2;
+                         if (lineLen > 60) {
+                             lineLen = 0;
+                             Tcl_AppendResult(interp, "\n", (char *) NULL);
+                         }
+                     }
+                     break;
+                 }
+                 case 2: {
+                     /*
+                      * Finally, color mode.  Here, just output the red, green,
+                      * and blue values directly.
+                      */
+                     for (xx = x; xx < x+width; xx++) {
+                         TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
+                                         &red, &green, &blue);
+                         sprintf(buffer, "%02X%02X%02X",
+                                 (int) floor(0.5 + 255.0 * red),
+                                 (int) floor(0.5 + 255.0 * green),
+                                 (int) floor(0.5 + 255.0 * blue));
+                         Tcl_AppendResult(interp, buffer, (char *) NULL);
+                         lineLen += 6;
+                         if (lineLen > 60) {
+                             lineLen = 0;
+                             Tcl_AppendResult(interp, "\n", (char *) NULL);
+                         }
+                     }
+                     break;
+                 }
+             }
+         }
+         switch (level) {
+             case 0: sprintf(buffer, ">\n} image\n"); break;
+             case 1: sprintf(buffer, ">\n} image\n"); break;
+             case 2: sprintf(buffer, ">\n} false 3 colorimage\n"); break;
+         }
+         Tcl_AppendResult(interp, buffer, (char *) NULL);
+         sprintf(buffer, "0 %d translate\n", rows);
+         Tcl_AppendResult(interp, buffer, (char *) NULL);
+     }
+     ckfree((char *) cdata.colors);
      return TCL_OK;
  }
