From aecc31b92a3ea5c855f7bc90136e6cd6d5abe723 Mon Sep 17 00:00:00 2001 From: "Peter W. Draper" Date: Sat, 15 Jun 2013 19:35:57 +0100 Subject: [PATCH] rtd: revert patches for printing, currently does not work when not using X11 shared memory the problem is in the offset handling - somewhere --- rtd/generic/RtdImage.C | 14 +- rtd/generic/tkCanvas.h-tk8.4.11 | 259 ++++++++++++++++---------------- rtd/generic/tkCanvasPsImage.c | 227 ++++++++++++++++++++++++++++ 3 files changed, 363 insertions(+), 137 deletions(-) create mode 100644 rtd/generic/tkCanvasPsImage.c diff --git a/rtd/generic/RtdImage.C b/rtd/generic/RtdImage.C index d6e4e7e..801e1c6 100644 --- a/rtd/generic/RtdImage.C +++ b/rtd/generic/RtdImage.C @@ -146,6 +146,9 @@ extern "C" int gethostname(char *name, unsigned int namelen); #endif /* NEED_GETHOSTNAME_PROTO */ #endif +// local extension to enable postscript printing for images +extern "C" void TkCanvasPsImage_Init(); + // generated code for bitmaps used in tcl scripts void defineRtdBitmaps(Tcl_Interp*); @@ -179,7 +182,6 @@ static Tk_ConfigSpec configSpecs_[] = { {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; - /* * Initialize the image control structure with pointers to the handler * functions @@ -191,12 +193,7 @@ static Tk_ImageType rtdImageType = { TkImage::DisplayImage, /* displayProc */ TkImage::FreeImage, /* freeProc */ TkImage::DeleteImage, /* deleteProc */ - -#if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 - // XXX RtdImage::Postscript, /* postscriptProc */ - (Tk_ImagePostscriptProc *) NULL, /* postscriptProc */ -#endif - + (Tk_ImagePostscriptProc *) NULL, /* postscriptProc, use generic */ (Tk_ImageType *) NULL /* nextPtr */ }; @@ -332,6 +329,9 @@ int Rtd_Init(Tcl_Interp* interp) { // Initialize the local packages that rtd depends on + // PWD: enable postscript printing for images (local ext) + TkCanvasPsImage_Init(); + // initialize the tclutil package if (Tclutil_Init(interp) == TCL_ERROR) { return TCL_ERROR; diff --git a/rtd/generic/tkCanvas.h-tk8.4.11 b/rtd/generic/tkCanvas.h-tk8.4.11 index f868c55..259c7cd 100644 --- a/rtd/generic/tkCanvas.h-tk8.4.11 +++ b/rtd/generic/tkCanvas.h-tk8.4.11 @@ -1,17 +1,16 @@ /* * tkCanvas.h -- * - * Declarations shared among all the files that implement - * canvas widgets. + * Declarations shared among all the files that implement canvas widgets. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1995 Sun Microsystems, Inc. * Copyright (c) 1998 by Scriptics Corporation. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvas.h-tk8.4.11,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ + * RCS: @(#) $Id: tkCanvas.h,v 1.13 2007/12/13 15:24:13 dgp Exp $ */ #ifndef _TKCANVAS @@ -21,40 +20,45 @@ #include "tk.h" #endif +#include "tclUnixPort.h" + #ifndef USE_OLD_TAG_SEARCH typedef struct TagSearchExpr_s TagSearchExpr; struct TagSearchExpr_s { - TagSearchExpr *next; /* for linked lists of expressions - used in bindings */ - Tk_Uid uid; /* the uid of the whole expression */ - Tk_Uid *uids; /* expresion compiled to an array of uids */ - int allocated; /* available space for array of uids */ - int length; /* length of expression */ - int index; /* current position in expression evaluation */ - int match; /* this expression matches event's item's tags*/ + TagSearchExpr *next; /* For linked lists of expressions - used in + * bindings. */ + Tk_Uid uid; /* The uid of the whole expression. */ + Tk_Uid *uids; /* Expresion compiled to an array of uids. */ + int allocated; /* Available space for array of uids. */ + int length; /* Length of expression. */ + int index; /* Current position in expression + * evaluation. */ + int match; /* This expression matches event's item's + * tags. */ }; #endif /* not USE_OLD_TAG_SEARCH */ /* - * The record below describes a canvas widget. It is made available - * to the item procedures so they can access certain shared fields such - * as the overall displacement and scale factor for the canvas. + * The record below describes a canvas widget. It is made available to the + * item functions so they can access certain shared fields such as the overall + * displacement and scale factor for the canvas. */ typedef struct TkCanvas { - Tk_Window tkwin; /* Window that embodies the canvas. NULL - * means that the window has been destroyed - * but the data structures haven't yet been - * cleaned up.*/ - Display *display; /* Display containing widget; needed, among + Tk_Window tkwin; /* Window that embodies the canvas. NULL means + * that the window has been destroyed but the + * data structures haven't yet been cleaned + * up.*/ + Display *display; /* Display containing widget; needed, among * other things, to release resources after * tkwin has already gone away. */ Tcl_Interp *interp; /* Interpreter associated with canvas. */ Tcl_Command widgetCmd; /* Token for canvas's widget command. */ - Tk_Item *firstItemPtr; /* First in list of all items in canvas, - * or NULL if canvas empty. */ - Tk_Item *lastItemPtr; /* Last in list of all items in canvas, - * or NULL if canvas empty. */ + Tk_Item *firstItemPtr; /* First in list of all items in canvas, or + * NULL if canvas empty. */ + Tk_Item *lastItemPtr; /* Last in list of all items in canvas, or + * NULL if canvas empty. */ /* * Information used when displaying widget: @@ -64,39 +68,39 @@ typedef struct TkCanvas { Tk_3DBorder bgBorder; /* Used for canvas background. */ int relief; /* Indicates whether window as a whole is * raised, sunken, or flat. */ - int highlightWidth; /* Width in pixels of highlight to draw - * around widget when it has the focus. - * <= 0 means don't draw a highlight. */ + int highlightWidth; /* Width in pixels of highlight to draw around + * widget when it has the focus. <= 0 means + * don't draw a highlight. */ XColor *highlightBgColorPtr; - /* Color for drawing traversal highlight - * area when highlight is off. */ + /* Color for drawing traversal highlight area + * when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ int inset; /* Total width of all borders, including * traversal highlight and 3-D border. - * Indicates how much interior stuff must - * be offset from outside edges to leave - * room for borders. */ + * Indicates how much interior stuff must be + * offset from outside edges to leave room for + * borders. */ GC pixmapGC; /* Used to copy bits from a pixmap to the * screen and also to clear the pixmap. */ int width, height; /* Dimensions to request for canvas window, * specified in pixels. */ - int redrawX1, redrawY1; /* Upper left corner of area to redraw, - * in pixel coordinates. Border pixels - * are included. Only valid if - * REDRAW_PENDING flag is set. */ - int redrawX2, redrawY2; /* Lower right corner of area to redraw, - * in integer canvas coordinates. Border - * pixels will *not* be redrawn. */ - int confine; /* Non-zero means constrain view to keep - * as much of canvas visible as possible. */ + int redrawX1, redrawY1; /* Upper left corner of area to redraw, in + * pixel coordinates. Border pixels are + * included. Only valid if REDRAW_PENDING flag + * is set. */ + int redrawX2, redrawY2; /* Lower right corner of area to redraw, in + * integer canvas coordinates. Border pixels + * will *not* be redrawn. */ + int confine; /* Non-zero means constrain view to keep as + * much of canvas visible as possible. */ /* * Information used to manage the selection and insertion cursor: */ - Tk_CanvasTextInfo textInfo; /* Contains lots of fields; see tk.h for - * details. This structure is shared with - * the code that implements individual items. */ + Tk_CanvasTextInfo textInfo; /* Contains lots of fields; see tk.h for + * details. This structure is shared with the + * code that implements individual items. */ int insertOnTime; /* Number of milliseconds cursor should spend * in "on" state for each blink. */ int insertOffTime; /* Number of milliseconds cursor should spend @@ -106,7 +110,7 @@ typedef struct TkCanvas { * off. */ /* - * Transformation applied to canvas as a whole: to compute screen + * Transformation applied to canvas as a whole: to compute screen * coordinates (X,Y) from canvas coordinates (x,y), do the following: * * X = x - xOrigin; @@ -118,65 +122,63 @@ typedef struct TkCanvas { * canvas pixel units. */ int drawableXOrigin, drawableYOrigin; /* During redisplay, these fields give the - * canvas coordinates corresponding to - * the upper-left corner of the drawable - * where items are actually being drawn - * (typically a pixmap smaller than the - * whole window). */ + * canvas coordinates corresponding to the + * upper-left corner of the drawable where + * items are actually being drawn (typically a + * pixmap smaller than the whole window). */ /* * Information used for event bindings associated with items. */ Tk_BindingTable bindingTable; - /* Table of all bindings currently defined - * for this canvas. NULL means that no - * bindings exist, so the table hasn't been - * created. Each "object" used for this - * table is either a Tk_Uid for a tag or - * the address of an item named by id. */ + /* Table of all bindings currently defined for + * this canvas. NULL means that no bindings + * exist, so the table hasn't been created. + * Each "object" used for this table is either + * a Tk_Uid for a tag or the address of an + * item named by id. */ Tk_Item *currentItemPtr; /* The item currently containing the mouse * pointer, or NULL if none. */ Tk_Item *newCurrentPtr; /* The item that is about to become the - * current one, or NULL. This field is - * used to detect deletions of the new - * current item pointer that occur during - * Leave processing of the previous current - * item. */ - double closeEnough; /* The mouse is assumed to be inside an - * item if it is this close to it. */ - XEvent pickEvent; /* The event upon which the current choice - * of currentItem is based. Must be saved - * so that if the currentItem is deleted, - * can pick another. */ - int state; /* Last known modifier state. Used to - * defer picking a new current object - * while buttons are down. */ + * current one, or NULL. This field is used to + * detect deletions of the new current item + * pointer that occur during Leave processing + * of the previous current item. */ + double closeEnough; /* The mouse is assumed to be inside an item + * if it is this close to it. */ + XEvent pickEvent; /* The event upon which the current choice of + * currentItem is based. Must be saved so that + * if the currentItem is deleted, can pick + * another. */ + int state; /* Last known modifier state. Used to defer + * picking a new current object while buttons + * are down. */ /* * Information used for managing scrollbars: */ char *xScrollCmd; /* Command prefix for communicating with - * horizontal scrollbar. NULL means no - * horizontal scrollbar. Malloc'ed*/ + * horizontal scrollbar. NULL means no + * horizontal scrollbar. Malloc'ed. */ char *yScrollCmd; /* Command prefix for communicating with - * vertical scrollbar. NULL means no - * vertical scrollbar. Malloc'ed*/ + * vertical scrollbar. NULL means no vertical + * scrollbar. Malloc'ed. */ int scrollX1, scrollY1, scrollX2, scrollY2; /* These four coordinates define the region * that is the 100% area for scrolling (i.e. * these numbers determine the size and * location of the sliders on scrollbars). * Units are pixels in canvas coords. */ - char *regionString; /* The option string from which scrollX1 - * etc. are derived. Malloc'ed. */ + char *regionString; /* The option string from which scrollX1 etc. + * are derived. Malloc'ed. */ int xScrollIncrement; /* If >0, defines a grid for horizontal - * scrolling. This is the size of the "unit", + * scrolling. This is the size of the "unit", * and the left edge of the screen will always * lie on an even unit boundary. */ int yScrollIncrement; /* If >0, defines a grid for horizontal - * scrolling. This is the size of the "unit", + * scrolling. This is the size of the "unit", * and the left edge of the screen will always * lie on an even unit boundary. */ @@ -197,11 +199,11 @@ typedef struct TkCanvas { */ Tk_Item *hotPtr; /* Pointer to "hot" item (one that's been - * recently used. NULL means there's no - * hot item. */ + * recently used. NULL means there's no hot + * item. */ Tk_Item *hotPrevPtr; /* Pointer to predecessor to hotPtr (NULL - * means item is first in list). This is - * only a hint and may not really be hotPtr's + * means item is first in list). This is only + * a hint and may not really be hotPtr's * predecessor. */ /* @@ -209,61 +211,61 @@ typedef struct TkCanvas { */ Tk_Cursor cursor; /* Current cursor for window, or None. */ - char *takeFocus; /* Value of -takefocus option; not used in - * the C code, but used by keyboard traversal - * scripts. Malloc'ed, but may be NULL. */ - double pixelsPerMM; /* Scale factor between MM and pixels; - * used when converting coordinates. */ - int flags; /* Various flags; see below for + char *takeFocus; /* Value of -takefocus option; not used in the + * C code, but used by keyboard traversal + * scripts. Malloc'ed, but may be NULL. */ + double pixelsPerMM; /* Scale factor between MM and pixels; used + * when converting coordinates. */ + int flags; /* Various flags; see below for * definitions. */ - int nextId; /* Number to use as id for next item - * created in widget. */ - Tk_PostscriptInfo psInfo; - /* Pointer to information used for generating - * Postscript for the canvas. NULL means - * no Postscript is currently being - * generated. */ + int nextId; /* Number to use as id for next item created + * in widget. */ + Tk_PostscriptInfo psInfo; /* Pointer to information used for generating + * Postscript for the canvas. NULL means no + * Postscript is currently being generated. */ Tcl_HashTable idTable; /* Table of integer indices. */ + /* * Additional information, added by the 'dash'-patch */ - VOID *reserved1; - Tk_State canvas_state; /* state of canvas */ - VOID *reserved2; - VOID *reserved3; + + void *reserved1; + Tk_State canvas_state; /* State of canvas. */ + void *reserved2; + void *reserved3; Tk_TSOffset tsoffset; #ifndef USE_OLD_TAG_SEARCH - TagSearchExpr *bindTagExprs; /* linked list of tag expressions used in bindings */ + TagSearchExpr *bindTagExprs;/* Linked list of tag expressions used in + * bindings. */ #endif } TkCanvas; /* * Flag bits for canvases: * - * REDRAW_PENDING - 1 means a DoWhenIdle handler has already - * been created to redraw some or all of the - * canvas. + * REDRAW_PENDING - 1 means a DoWhenIdle handler has already been + * created to redraw some or all of the canvas. * REDRAW_BORDERS - 1 means that the borders need to be redrawn * during the next redisplay operation. * REPICK_NEEDED - 1 means DisplayCanvas should pick a new * current item before redrawing the canvas. - * GOT_FOCUS - 1 means the focus is currently in this - * widget, so should draw the insertion cursor - * and traversal highlight. + * GOT_FOCUS - 1 means the focus is currently in this widget, + * so should draw the insertion cursor and + * traversal highlight. * CURSOR_ON - 1 means the insertion cursor is in the "on" - * phase of its blink cycle. 0 means either - * we don't have the focus or the cursor is in - * the "off" phase of its cycle. - * UPDATE_SCROLLBARS - 1 means the scrollbars should get updated - * as part of the next display operation. - * LEFT_GRABBED_ITEM - 1 means that the mouse left the current - * item while a grab was in effect, so we - * didn't change canvasPtr->currentItemPtr. + * phase of its blink cycle. 0 means either we + * don't have the focus or the cursor is in the + * "off" phase of its cycle. + * UPDATE_SCROLLBARS - 1 means the scrollbars should get updated as + * part of the next display operation. + * LEFT_GRABBED_ITEM - 1 means that the mouse left the current item + * while a grab was in effect, so we didn't + * change canvasPtr->currentItemPtr. * REPICK_IN_PROGRESS - 1 means PickCurrentItem is currently - * executing. If it should be called recursively, + * executing. If it should be called recursively, * it should simply return immediately. - * BBOX_NOT_EMPTY - 1 means that the bounding box of the area - * that should be redrawn is not empty. + * BBOX_NOT_EMPTY - 1 means that the bounding box of the area that + * should be redrawn is not empty. */ #define REDRAW_PENDING 1 @@ -279,8 +281,8 @@ typedef struct TkCanvas { /* * Flag bits for canvas items (redraw_flags): * - * FORCE_REDRAW - 1 means that the new coordinates of some - * item are not yet registered using + * FORCE_REDRAW - 1 means that the new coordinates of some item + * are not yet registered using * Tk_CanvasEventuallyRedraw(). It should still * be done by the general canvas code. */ @@ -288,20 +290,17 @@ typedef struct TkCanvas { #define FORCE_REDRAW 8 /* - * Canvas-related procedures that are shared among Tk modules but not - * exported to the outside world: + * Canvas-related functions that are shared among Tk modules but not exported + * to the outside world: */ -extern int TkCanvPostscriptCmd _ANSI_ARGS_((TkCanvas *canvasPtr, - Tcl_Interp *interp, int argc, CONST char **argv)); - +MODULE_SCOPE int TkCanvPostscriptCmd(TkCanvas *canvasPtr, + Tcl_Interp *interp, int argc, CONST char **argv); +MODULE_SCOPE int TkCanvTranslatePath(TkCanvas *canvPtr, + int numVertex, double *coordPtr, int closed, + XPoint *outPtr); /* - * Other procedures that are shared among Tk canvas modules but not exported - * to the outside world: + * Standard item types provided by Tk: */ -extern int TkCanvTranslatePath _ANSI_ARGS_((TkCanvas *canvPtr, - int numVertex, double *coordPtr, int closed, - XPoint *outPtr)); - #endif /* _TKCANVAS */ diff --git a/rtd/generic/tkCanvasPsImage.c b/rtd/generic/tkCanvasPsImage.c new file mode 100644 index 0000000..d901b54 --- /dev/null +++ b/rtd/generic/tkCanvasPsImage.c @@ -0,0 +1,227 @@ +/* + * E.S.O. - VLT project / ESO Archive + * + * "@(#) $Id: tkCanvasPsImage.c,v 1.2 2005/02/02 01:43:02 brighton Exp $" + * + * TkCanvasPsImage.C - Implement Tk postscript output for images + * + * The code here was taken from a version of the Tk canvasps patch, which + * was modified by Peter Draper of Starlink to only access the visible + * portion of an image (required, to avoid problems with large or zoomed + * in images). + * + * To avoid having to patch the Tk sources, I gathered all the necessary + * code in this file, including some private struct typedefs from the Tk + * source files, which are not available in any include files. + * + * NOTE: This code is Tk4.2 specific. If you upgrade to a newer version, + * you will have to redo it, based on the latest Tk sources and/or Tk + * canvasps patch. + * + * PWD (again): Redone for tk8.4 as the default printing (at least there is + * some now) includes the empty padding once more. Using a new image + * postscript proc will not work as there isn't enough information passed in + * to determine the canvas viewport. + * + * To enable this extension, call TkCanvasPsImage_Init(). + * + * who when what + * -------------- -------- ---------------------------------------- + * Allan Brighton 19/06/98 Created + * Peter W. Draper 05/05/06 Added support for tk8.4 as zoomed images + * generate massive postscript files full of + * padding around the rtdimage. + */ + +#include +#ifdef HAVE_TKCANVAS_H +#include "tclInt.h" +#include "tkCanvas.h" +#else +// The structure we need hasn't changed for a long time, so just include a local copy. +#include "tkCanvas.h-tk8.4.11" +#define HAVE_TKCANVAS_H +#endif + +/* Local prototypes */ +static int RtdImageToPostscript( Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int prepass ); + +/* Private function we add to Tk. */ +Tk_ItemType *getTkImageType(); + + +/* + * -------------------------------------------------------------- + * + * TkCanvasPsImage_Init -- + * + * This procedure is called to initialize the canvas image + * postscript extension by setting a field in the canvas + * image type control struct, causing our postscript routine + * to be called for canvas images. + * + * Results: + * None. + * + * Side effects: + * None. + * + * -------------------------------------------------------------- + */ + +void +TkCanvasPsImage_Init() +{ + /* Need to access the Tk Image type and supercede the Postscript + * command. */ + Tk_ItemType *tkImageType = getTkImageType(); + tkImageType->postscriptProc = RtdImageToPostscript; +} + +/* + * Note we do it this way, rather than by defining an image postscript proc, + * as we do not have the necessary handles to canvases etc. passed to a + * postscript proc. + */ + +/* + * The structure below defines the record for each image item (lifted from + * tkCanvImg.c). + */ + +typedef struct ImageItem { + Tk_Item header; /* Generic stuff that's the same for all + * types. MUST BE FIRST IN STRUCTURE. */ + Tk_Canvas canvas; /* Canvas containing the image. */ + double x, y; /* Coordinates of positioning point for + * image. */ + Tk_Anchor anchor; /* Where to anchor image relative to + * (x,y). */ + char *imageString; /* String describing -image option (malloc-ed). + * NULL means no image right now. */ + char *activeImageString; /* String describing -activeimage option. + * NULL means no image right now. */ + char *disabledImageString; /* String describing -disabledimage option. + * NULL means no image right now. */ + Tk_Image image; /* Image to display in window, or NULL if + * no image at present. */ + Tk_Image activeImage; /* Image to display in window, or NULL if + * no image at present. */ + Tk_Image disabledImage; /* Image to display in window, or NULL if + * no image at present. */ +} ImageItem; + +/* + *-------------------------------------------------------------- + * + * RtdImageToPostscript -- + * + * This procedure is called to generate Postscript for + * image items. + * + * Results: + * The return value is a standard Tcl result. If an error + * occurs in generating Postscript then an error message is + * left in interp->result, replacing whatever used to be there. + * If no error occurs, then Postscript for the item is appended + * to the result. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +static int +RtdImageToPostscript(interp, canvas, itemPtr, prepass) + Tcl_Interp *interp; /* Leave Postscript or error message + * here. */ + Tk_Canvas canvas; /* Information about overall canvas. */ + Tk_Item *itemPtr; /* Item for which Postscript is + * wanted. */ + int prepass; /* 1 means this is a prepass to + * collect font information; 0 means + * final Postscript is being created.*/ +{ + ImageItem *imgPtr = (ImageItem *)itemPtr; + Tk_Window canvasWin = Tk_CanvasTkwin(canvas); + + char buffer[256]; + double x, y; + int width, height; + Tk_Image image; + Tk_State state = itemPtr->state; + int screenX1, screenY1, screenX2, screenY2; + TkCanvas *canvasPtr = (TkCanvas *) canvas; + + if (state == TK_STATE_NULL) { + state = ((TkCanvas *)canvas)->canvas_state; + } + + image = imgPtr->image; + if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (imgPtr->activeImage != NULL) { + image = imgPtr->activeImage; + } + } else if (state == TK_STATE_DISABLED) { + if (imgPtr->disabledImage != NULL) { + image = imgPtr->disabledImage; + } + } + if (image == NULL) { + /* + * Image item without actual image specified. + */ + return TCL_OK; + } + + Tk_SizeOfImage(image, &width, &height); + + /* Determine region of image that needs to be drawn. For rtdimages only + * the part visible on the display screen is done. */ + screenX1 = canvasPtr->xOrigin + canvasPtr->inset; + screenY1 = canvasPtr->yOrigin + canvasPtr->inset; + screenX2 = canvasPtr->xOrigin + Tk_Width(canvasWin) - canvasPtr->inset; + screenY2 = canvasPtr->yOrigin + Tk_Height(canvasWin) - canvasPtr->inset; + if ( width > screenX2 - screenX1 ) { + width = screenX2 - screenX1; + } else { + screenX1 = 0; + } + + if ( height > screenY2 - screenY1 ) { + height = screenY2 - screenY1; + } else { + screenY1 = 0; + } + + /* + * Compute the coordinates of the lower-left corner of the image, + * taking into account the anchor position for the image. + */ + + x = imgPtr->x; + y = Tk_CanvasPsY(canvas, imgPtr->y); + + switch (imgPtr->anchor) { + case TK_ANCHOR_NW: y -= height; break; + case TK_ANCHOR_N: x -= width/2.0; y -= height; break; + case TK_ANCHOR_NE: x -= width; y -= height; break; + case TK_ANCHOR_E: x -= width; y -= height/2.0; break; + case TK_ANCHOR_SE: x -= width; break; + case TK_ANCHOR_S: x -= width/2.0; break; + case TK_ANCHOR_SW: break; + case TK_ANCHOR_W: y -= height/2.0; break; + case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break; + } + + if (!prepass) { + sprintf(buffer, "%.15g %.15g", x, y); + Tcl_AppendResult(interp, buffer, " translate\n", (char *) NULL); + } + + return Tk_PostscriptImage(image, interp, canvasWin, + ((TkCanvas *) canvas)->psInfo, + screenX1, screenY1, width, height, prepass); +}