home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / tcl / tk3.3b1 / tkCanvBmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-16  |  20.9 KB  |  728 lines

  1. /* 
  2.  * tkCanvBmap.c --
  3.  *
  4.  *    This file implements bitmap items for canvas widgets.
  5.  *
  6.  * Copyright (c) 1992-1993 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Permission is hereby granted, without written agreement and without
  10.  * license or royalty fees, to use, copy, modify, and distribute this
  11.  * software and its documentation for any purpose, provided that the
  12.  * above copyright notice and the following two paragraphs appear in
  13.  * all copies of this software.
  14.  * 
  15.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  16.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  17.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  18.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  19.  *
  20.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  21.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  22.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  23.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  24.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  25.  */
  26.  
  27. #ifndef lint
  28. static char rcsid[] = "$Header: /user6/ouster/wish/RCS/tkCanvBmap.c,v 1.10 93/06/16 17:16:10 ouster Exp $ SPRITE (Berkeley)";
  29. #endif
  30.  
  31. #include <stdio.h>
  32. #include <math.h>
  33. #include "tkInt.h"
  34. #include "tkCanvas.h"
  35.  
  36. /*
  37.  * The structure below defines the record for each rectangle/oval item.
  38.  */
  39.  
  40. typedef struct BitmapItem  {
  41.     Tk_Item header;        /* Generic stuff that's the same for all
  42.                  * types.  MUST BE FIRST IN STRUCTURE. */
  43.     double x, y;        /* Coordinates of positioning point for
  44.                  * bitmap. */
  45.     Tk_Anchor anchor;        /* Where to anchor bitmap relative to
  46.                  * (x,y). */
  47.     Pixmap bitmap;        /* Bitmap to display in window. */
  48.     XColor *fgColor;        /* Foreground color to use for bitmap. */
  49.     XColor *bgColor;        /* Background color to use for bitmap. */
  50.     GC gc;            /* Graphics context to use for drawing
  51.                  * bitmap on screen. */
  52. } BitmapItem;
  53.  
  54. /*
  55.  * Information used for parsing configuration specs:
  56.  */
  57.  
  58. static Tk_ConfigSpec configSpecs[] = {
  59.     {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
  60.     "center", Tk_Offset(BitmapItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
  61.     {TK_CONFIG_COLOR, "-background", (char *) NULL, (char *) NULL,
  62.     (char *) NULL, Tk_Offset(BitmapItem, bgColor), TK_CONFIG_NULL_OK},
  63.     {TK_CONFIG_BITMAP, "-bitmap", (char *) NULL, (char *) NULL,
  64.     (char *) NULL, Tk_Offset(BitmapItem, bitmap), TK_CONFIG_NULL_OK},
  65.     {TK_CONFIG_COLOR, "-foreground", (char *) NULL, (char *) NULL,
  66.     "black", Tk_Offset(BitmapItem, fgColor), 0},
  67.     {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
  68.     (char *) NULL, 0, TK_CONFIG_NULL_OK, &tkCanvasTagsOption},
  69.     {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
  70.     (char *) NULL, 0, 0}
  71. };
  72.  
  73. /*
  74.  * Prototypes for procedures defined in this file:
  75.  */
  76.  
  77. static int        BitmapCoords _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  78.                 Tk_Item *itemPtr, int argc, char **argv));
  79. static int        BitmapToArea _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  80.                 Tk_Item *itemPtr, double *rectPtr));
  81. static double        BitmapToPoint _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  82.                 Tk_Item *itemPtr, double *coordPtr));
  83. static int        BitmapToPostscript _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  84.                 Tk_Item *itemPtr, Tk_PostscriptInfo *psInfoPtr));
  85. static void        ComputeBitmapBbox _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  86.                 BitmapItem *bmapPtr));
  87. static int        ConfigureBitmap _ANSI_ARGS_((
  88.                 Tk_Canvas *canvasPtr, Tk_Item *itemPtr, int argc,
  89.                 char **argv, int flags));
  90. static int        CreateBitmap _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  91.                 struct Tk_Item *itemPtr, int argc, char **argv));
  92. static void        DeleteBitmap _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  93.                 Tk_Item *itemPtr));
  94. static void        DisplayBitmap _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  95.                 Tk_Item *itemPtr, Drawable dst));
  96. static void        ScaleBitmap _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  97.                 Tk_Item *itemPtr, double originX, double originY,
  98.                 double scaleX, double scaleY));
  99. static void        TranslateBitmap _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  100.                 Tk_Item *itemPtr, double deltaX, double deltaY));
  101.  
  102. /*
  103.  * The structures below defines the rectangle and oval item types
  104.  * by means of procedures that can be invoked by generic item code.
  105.  */
  106.  
  107. Tk_ItemType TkBitmapType = {
  108.     "bitmap",                /* name */
  109.     sizeof(BitmapItem),            /* itemSize */
  110.     CreateBitmap,            /* createProc */
  111.     configSpecs,            /* configSpecs */
  112.     ConfigureBitmap,            /* configureProc */
  113.     BitmapCoords,            /* coordProc */
  114.     DeleteBitmap,            /* deleteProc */
  115.     DisplayBitmap,            /* displayProc */
  116.     0,                    /* alwaysRedraw */
  117.     BitmapToPoint,            /* pointProc */
  118.     BitmapToArea,            /* areaProc */
  119.     BitmapToPostscript,            /* postscriptProc */
  120.     ScaleBitmap,            /* scaleProc */
  121.     TranslateBitmap,            /* translateProc */
  122.     (Tk_ItemIndexProc *) NULL,        /* indexProc */
  123.     (Tk_ItemCursorProc *) NULL,        /* icursorProc */
  124.     (Tk_ItemSelectionProc *) NULL,    /* selectionProc */
  125.     (Tk_ItemInsertProc *) NULL,        /* insertProc */
  126.     (Tk_ItemDCharsProc *) NULL,        /* dTextProc */
  127.     (Tk_ItemType *) NULL        /* nextPtr */
  128. };
  129.  
  130. /*
  131.  *--------------------------------------------------------------
  132.  *
  133.  * CreateBitmap --
  134.  *
  135.  *    This procedure is invoked to create a new bitmap
  136.  *    item in a canvas.
  137.  *
  138.  * Results:
  139.  *    A standard Tcl return value.  If an error occurred in
  140.  *    creating the item, then an error message is left in
  141.  *    canvasPtr->interp->result;  in this case itemPtr is
  142.  *    left uninitialized, so it can be safely freed by the
  143.  *    caller.
  144.  *
  145.  * Side effects:
  146.  *    A new bitmap item is created.
  147.  *
  148.  *--------------------------------------------------------------
  149.  */
  150.  
  151. static int
  152. CreateBitmap(canvasPtr, itemPtr, argc, argv)
  153.     register Tk_Canvas *canvasPtr;    /* Canvas to hold new item. */
  154.     Tk_Item *itemPtr;            /* Record to hold new item;  header
  155.                      * has been initialized by caller. */
  156.     int argc;                /* Number of arguments in argv. */
  157.     char **argv;            /* Arguments describing rectangle. */
  158. {
  159.     register BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
  160.  
  161.     if (argc < 2) {
  162.     Tcl_AppendResult(canvasPtr->interp, "wrong # args:  should be \"",
  163.         Tk_PathName(canvasPtr->tkwin), "\" create ",
  164.         itemPtr->typePtr->name, " x y ?options?",
  165.         (char *) NULL);
  166.     return TCL_ERROR;
  167.     }
  168.  
  169.     /*
  170.      * Initialize item's record.
  171.      */
  172.  
  173.     bmapPtr->anchor = TK_ANCHOR_CENTER;
  174.     bmapPtr->bitmap = None;
  175.     bmapPtr->fgColor = NULL;
  176.     bmapPtr->bgColor = NULL;
  177.     bmapPtr->gc = None;
  178.  
  179.     /*
  180.      * Process the arguments to fill in the item record.
  181.      */
  182.  
  183.     if ((TkGetCanvasCoord(canvasPtr, argv[0], &bmapPtr->x) != TCL_OK)
  184.         || (TkGetCanvasCoord(canvasPtr, argv[1],
  185.         &bmapPtr->y) != TCL_OK)) {
  186.     return TCL_ERROR;
  187.     }
  188.  
  189.     if (ConfigureBitmap(canvasPtr, itemPtr, argc-2, argv+2, 0) != TCL_OK) {
  190.     DeleteBitmap(canvasPtr, itemPtr);
  191.     return TCL_ERROR;
  192.     }
  193.     return TCL_OK;
  194. }
  195.  
  196. /*
  197.  *--------------------------------------------------------------
  198.  *
  199.  * BitmapCoords --
  200.  *
  201.  *    This procedure is invoked to process the "coords" widget
  202.  *    command on bitmap items.  See the user documentation for
  203.  *    details on what it does.
  204.  *
  205.  * Results:
  206.  *    Returns TCL_OK or TCL_ERROR, and sets canvasPtr->interp->result.
  207.  *
  208.  * Side effects:
  209.  *    The coordinates for the given item may be changed.
  210.  *
  211.  *--------------------------------------------------------------
  212.  */
  213.  
  214. static int
  215. BitmapCoords(canvasPtr, itemPtr, argc, argv)
  216.     register Tk_Canvas *canvasPtr;    /* Canvas containing item. */
  217.     Tk_Item *itemPtr;            /* Item whose coordinates are to be
  218.                      * read or modified. */
  219.     int argc;                /* Number of coordinates supplied in
  220.                      * argv. */
  221.     char **argv;            /* Array of coordinates: x1, y1,
  222.                      * x2, y2, ... */
  223. {
  224.     register BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
  225.     char x[TCL_DOUBLE_SPACE], y[TCL_DOUBLE_SPACE];
  226.  
  227.     if (argc == 0) {
  228.     Tcl_PrintDouble(canvasPtr->interp, bmapPtr->x, x);
  229.     Tcl_PrintDouble(canvasPtr->interp, bmapPtr->y, y);
  230.     Tcl_AppendResult(canvasPtr->interp, x, " ", y, (char *) NULL);
  231.     } else if (argc == 2) {
  232.     if ((TkGetCanvasCoord(canvasPtr, argv[0], &bmapPtr->x) != TCL_OK)
  233.         || (TkGetCanvasCoord(canvasPtr, argv[1],
  234.             &bmapPtr->y) != TCL_OK)) {
  235.         return TCL_ERROR;
  236.     }
  237.     ComputeBitmapBbox(canvasPtr, bmapPtr);
  238.     } else {
  239.     sprintf(canvasPtr->interp->result,
  240.         "wrong # coordinates:  expected 0 or 2, got %d",
  241.         argc);
  242.     return TCL_ERROR;
  243.     }
  244.     return TCL_OK;
  245. }
  246.  
  247. /*
  248.  *--------------------------------------------------------------
  249.  *
  250.  * ConfigureBitmap --
  251.  *
  252.  *    This procedure is invoked to configure various aspects
  253.  *    of a bitmap item, such as its anchor position.
  254.  *
  255.  * Results:
  256.  *    A standard Tcl result code.  If an error occurs, then
  257.  *    an error message is left in canvasPtr->interp->result.
  258.  *
  259.  * Side effects:
  260.  *    Configuration information may be set for itemPtr.
  261.  *
  262.  *--------------------------------------------------------------
  263.  */
  264.  
  265. static int
  266. ConfigureBitmap(canvasPtr, itemPtr, argc, argv, flags)
  267.     Tk_Canvas *canvasPtr;    /* Canvas containing itemPtr. */
  268.     Tk_Item *itemPtr;        /* Bitmap item to reconfigure. */
  269.     int argc;            /* Number of elements in argv.  */
  270.     char **argv;        /* Arguments describing things to configure. */
  271.     int flags;            /* Flags to pass to Tk_ConfigureWidget. */
  272. {
  273.     register BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
  274.     XGCValues gcValues;
  275.     GC newGC;
  276.  
  277.     if (Tk_ConfigureWidget(canvasPtr->interp, canvasPtr->tkwin,
  278.         configSpecs, argc, argv, (char *) bmapPtr, flags) != TCL_OK) {
  279.     return TCL_ERROR;
  280.     }
  281.  
  282.     /*
  283.      * A few of the options require additional processing, such as those
  284.      * that determine the graphics context.
  285.      */
  286.  
  287.     gcValues.foreground = bmapPtr->fgColor->pixel;
  288.     if (bmapPtr->bgColor != NULL) {
  289.     gcValues.background = bmapPtr->bgColor->pixel;
  290.     } else {
  291.     gcValues.background = Tk_3DBorderColor(canvasPtr->bgBorder)->pixel;
  292.     }
  293.     newGC = Tk_GetGC(canvasPtr->tkwin, GCForeground|GCBackground, &gcValues);
  294.     if (bmapPtr->gc != None) {
  295.     Tk_FreeGC(canvasPtr->display, bmapPtr->gc);
  296.     }
  297.     bmapPtr->gc = newGC;
  298.  
  299.     ComputeBitmapBbox(canvasPtr, bmapPtr);
  300.  
  301.     return TCL_OK;
  302. }
  303.  
  304. /*
  305.  *--------------------------------------------------------------
  306.  *
  307.  * DeleteBitmap --
  308.  *
  309.  *    This procedure is called to clean up the data structure
  310.  *    associated with a bitmap item.
  311.  *
  312.  * Results:
  313.  *    None.
  314.  *
  315.  * Side effects:
  316.  *    Resources associated with itemPtr are released.
  317.  *
  318.  *--------------------------------------------------------------
  319.  */
  320.  
  321. static void
  322. DeleteBitmap(canvasPtr, itemPtr)
  323.     Tk_Canvas *canvasPtr;        /* Info about overall canvas widget. */
  324.     Tk_Item *itemPtr;            /* Item that is being deleted. */
  325. {
  326.     register BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
  327.  
  328.     if (bmapPtr->bitmap != None) {
  329.     Tk_FreeBitmap(canvasPtr->display, bmapPtr->bitmap);
  330.     }
  331.     if (bmapPtr->fgColor != NULL) {
  332.     Tk_FreeColor(bmapPtr->fgColor);
  333.     }
  334.     if (bmapPtr->bgColor != NULL) {
  335.     Tk_FreeColor(bmapPtr->bgColor);
  336.     }
  337.     if (bmapPtr->gc != NULL) {
  338.     Tk_FreeGC(canvasPtr->display, bmapPtr->gc);
  339.     }
  340. }
  341.  
  342. /*
  343.  *--------------------------------------------------------------
  344.  *
  345.  * ComputeBitmapBbox --
  346.  *
  347.  *    This procedure is invoked to compute the bounding box of
  348.  *    all the pixels that may be drawn as part of a bitmap item.
  349.  *    This procedure is where the child bitmap's placement is
  350.  *    computed.
  351.  *
  352.  * Results:
  353.  *    None.
  354.  *
  355.  * Side effects:
  356.  *    The fields x1, y1, x2, and y2 are updated in the header
  357.  *    for itemPtr.
  358.  *
  359.  *--------------------------------------------------------------
  360.  */
  361.  
  362.     /* ARGSUSED */
  363. static void
  364. ComputeBitmapBbox(canvasPtr, bmapPtr)
  365.     Tk_Canvas *canvasPtr;        /* Canvas that contains item. */
  366.     register BitmapItem *bmapPtr;    /* Item whose bbox is to be
  367.                      * recomputed. */
  368. {
  369.     unsigned int width, height;
  370.     int x, y;
  371.  
  372.     x = bmapPtr->x + 0.5;
  373.     y = bmapPtr->y + 0.5;
  374.  
  375.     if (bmapPtr->bitmap == None) {
  376.     bmapPtr->header.x1 = bmapPtr->header.x2 = x;
  377.     bmapPtr->header.y1 = bmapPtr->header.y2 = y;
  378.     return;
  379.     }
  380.  
  381.     /*
  382.      * Compute location and size of bitmap, using anchor information.
  383.      */
  384.  
  385.     Tk_SizeOfBitmap(canvasPtr->display, bmapPtr->bitmap, &width, &height);
  386.     switch (bmapPtr->anchor) {
  387.     case TK_ANCHOR_N:
  388.         x -= width/2;
  389.         break;
  390.     case TK_ANCHOR_NE:
  391.         x -= width;
  392.         break;
  393.     case TK_ANCHOR_E:
  394.         x -= width;
  395.         y -= height/2;
  396.         break;
  397.     case TK_ANCHOR_SE:
  398.         x -= width;
  399.         y -= height;
  400.         break;
  401.     case TK_ANCHOR_S:
  402.         x -= width/2;
  403.         y -= height;
  404.         break;
  405.     case TK_ANCHOR_SW:
  406.         y -= height;
  407.         break;
  408.     case TK_ANCHOR_W:
  409.         y -= height/2;
  410.         break;
  411.     case TK_ANCHOR_NW:
  412.         break;
  413.     case TK_ANCHOR_CENTER:
  414.         x -= width/2;
  415.         y -= height/2;
  416.         break;
  417.     }
  418.  
  419.     /*
  420.      * Store the information in the item header.
  421.      */
  422.  
  423.     bmapPtr->header.x1 = x;
  424.     bmapPtr->header.y1 = y;
  425.     bmapPtr->header.x2 = x + width;
  426.     bmapPtr->header.y2 = y + height;
  427. }
  428.  
  429. /*
  430.  *--------------------------------------------------------------
  431.  *
  432.  * DisplayBitmap --
  433.  *
  434.  *    This procedure is invoked to draw a bitmap item in a given
  435.  *    drawable.
  436.  *
  437.  * Results:
  438.  *    None.
  439.  *
  440.  * Side effects:
  441.  *    ItemPtr is drawn in drawable using the transformation
  442.  *    information in canvasPtr.
  443.  *
  444.  *--------------------------------------------------------------
  445.  */
  446.  
  447. static void
  448. DisplayBitmap(canvasPtr, itemPtr, drawable)
  449.     register Tk_Canvas *canvasPtr;    /* Canvas that contains item. */
  450.     Tk_Item *itemPtr;            /* Item to be displayed. */
  451.     Drawable drawable;            /* Pixmap or window in which to draw
  452.                      * item. */
  453. {
  454.     register BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
  455.  
  456.     if (bmapPtr->bitmap != None) {
  457.     XCopyPlane(Tk_Display(canvasPtr->tkwin), bmapPtr->bitmap, drawable,
  458.         bmapPtr->gc, 0, 0,
  459.         (unsigned int) bmapPtr->header.x2 - bmapPtr->header.x1,
  460.         (unsigned int) bmapPtr->header.y2 - bmapPtr->header.y1,
  461.         bmapPtr->header.x1 - canvasPtr->drawableXOrigin,
  462.         bmapPtr->header.y1 - canvasPtr->drawableYOrigin, 1);
  463.     }
  464. }
  465.  
  466. /*
  467.  *--------------------------------------------------------------
  468.  *
  469.  * BitmapToPoint --
  470.  *
  471.  *    Computes the distance from a given point to a given
  472.  *    rectangle, in canvas units.
  473.  *
  474.  * Results:
  475.  *    The return value is 0 if the point whose x and y coordinates
  476.  *    are coordPtr[0] and coordPtr[1] is inside the bitmap.  If the
  477.  *    point isn't inside the bitmap then the return value is the
  478.  *    distance from the point to the bitmap.
  479.  *
  480.  * Side effects:
  481.  *    None.
  482.  *
  483.  *--------------------------------------------------------------
  484.  */
  485.  
  486.     /* ARGSUSED */
  487. static double
  488. BitmapToPoint(canvasPtr, itemPtr, coordPtr)
  489.     Tk_Canvas *canvasPtr;    /* Canvas containing item. */
  490.     Tk_Item *itemPtr;        /* Item to check against point. */
  491.     double *coordPtr;        /* Pointer to x and y coordinates. */
  492. {
  493.     register BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
  494.     double x1, x2, y1, y2, xDiff, yDiff;
  495.  
  496.     x1 = bmapPtr->header.x1;
  497.     y1 = bmapPtr->header.y1;
  498.     x2 = bmapPtr->header.x2;
  499.     y2 = bmapPtr->header.y2;
  500.  
  501.     /*
  502.      * Point is outside rectangle.
  503.      */
  504.  
  505.     if (coordPtr[0] < x1) {
  506.     xDiff = x1 - coordPtr[0];
  507.     } else if (coordPtr[0] > x2)  {
  508.     xDiff = coordPtr[0] - x2;
  509.     } else {
  510.     xDiff = 0;
  511.     }
  512.  
  513.     if (coordPtr[1] < y1) {
  514.     yDiff = y1 - coordPtr[1];
  515.     } else if (coordPtr[1] > y2)  {
  516.     yDiff = coordPtr[1] - y2;
  517.     } else {
  518.     yDiff = 0;
  519.     }
  520.  
  521.     return hypot(xDiff, yDiff);
  522. }
  523.  
  524. /*
  525.  *--------------------------------------------------------------
  526.  *
  527.  * BitmapToArea --
  528.  *
  529.  *    This procedure is called to determine whether an item
  530.  *    lies entirely inside, entirely outside, or overlapping
  531.  *    a given rectangle.
  532.  *
  533.  * Results:
  534.  *    -1 is returned if the item is entirely outside the area
  535.  *    given by rectPtr, 0 if it overlaps, and 1 if it is entirely
  536.  *    inside the given area.
  537.  *
  538.  * Side effects:
  539.  *    None.
  540.  *
  541.  *--------------------------------------------------------------
  542.  */
  543.  
  544.     /* ARGSUSED */
  545. static int
  546. BitmapToArea(canvasPtr, itemPtr, rectPtr)
  547.     Tk_Canvas *canvasPtr;    /* Canvas containing item. */
  548.     Tk_Item *itemPtr;        /* Item to check against rectangle. */
  549.     double *rectPtr;        /* Pointer to array of four coordinates
  550.                  * (x1, y1, x2, y2) describing rectangular
  551.                  * area.  */
  552. {
  553.     register BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
  554.  
  555.     if ((rectPtr[2] <= bmapPtr->header.x1)
  556.         || (rectPtr[0] >= bmapPtr->header.x2)
  557.         || (rectPtr[3] <= bmapPtr->header.y1)
  558.         || (rectPtr[1] >= bmapPtr->header.y2)) {
  559.     return -1;
  560.     }
  561.     if ((rectPtr[0] <= bmapPtr->header.x1)
  562.         && (rectPtr[1] <= bmapPtr->header.y1)
  563.         && (rectPtr[2] >= bmapPtr->header.x2)
  564.         && (rectPtr[3] >= bmapPtr->header.y2)) {
  565.     return 1;
  566.     }
  567.     return 0;
  568. }
  569.  
  570. /*
  571.  *--------------------------------------------------------------
  572.  *
  573.  * ScaleBitmap --
  574.  *
  575.  *    This procedure is invoked to rescale a rectangle or oval
  576.  *    item.
  577.  *
  578.  * Results:
  579.  *    None.
  580.  *
  581.  * Side effects:
  582.  *    The rectangle or oval referred to by itemPtr is rescaled
  583.  *    so that the following transformation is applied to all
  584.  *    point coordinates:
  585.  *        x' = originX + scaleX*(x-originX)
  586.  *        y' = originY + scaleY*(y-originY)
  587.  *
  588.  *--------------------------------------------------------------
  589.  */
  590.  
  591. static void
  592. ScaleBitmap(canvasPtr, itemPtr, originX, originY, scaleX, scaleY)
  593.     Tk_Canvas *canvasPtr;        /* Canvas containing rectangle. */
  594.     Tk_Item *itemPtr;            /* Rectangle to be scaled. */
  595.     double originX, originY;        /* Origin about which to scale rect. */
  596.     double scaleX;            /* Amount to scale in X direction. */
  597.     double scaleY;            /* Amount to scale in Y direction. */
  598. {
  599.     register BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
  600.  
  601.     bmapPtr->x = originX + scaleX*(bmapPtr->x - originX);
  602.     bmapPtr->y = originY + scaleY*(bmapPtr->y - originY);
  603.     ComputeBitmapBbox(canvasPtr, bmapPtr);
  604. }
  605.  
  606. /*
  607.  *--------------------------------------------------------------
  608.  *
  609.  * TranslateBitmap --
  610.  *
  611.  *    This procedure is called to move a rectangle or oval by a
  612.  *    given amount.
  613.  *
  614.  * Results:
  615.  *    None.
  616.  *
  617.  * Side effects:
  618.  *    The position of the rectangle or oval is offset by
  619.  *    (xDelta, yDelta), and the bounding box is updated in the
  620.  *    generic part of the item structure.
  621.  *
  622.  *--------------------------------------------------------------
  623.  */
  624.  
  625. static void
  626. TranslateBitmap(canvasPtr, itemPtr, deltaX, deltaY)
  627.     Tk_Canvas *canvasPtr;        /* Canvas containing item. */
  628.     Tk_Item *itemPtr;            /* Item that is being moved. */
  629.     double deltaX, deltaY;        /* Amount by which item is to be
  630.                      * moved. */
  631. {
  632.     register BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
  633.  
  634.     bmapPtr->x += deltaX;
  635.     bmapPtr->y += deltaY;
  636.     ComputeBitmapBbox(canvasPtr, bmapPtr);
  637. }
  638.  
  639. /*
  640.  *--------------------------------------------------------------
  641.  *
  642.  * BitmapToPostscript --
  643.  *
  644.  *    This procedure is called to generate Postscript for
  645.  *    bitmap items.
  646.  *
  647.  * Results:
  648.  *    The return value is a standard Tcl result.  If an error
  649.  *    occurs in generating Postscript then an error message is
  650.  *    left in canvasPtr->interp->result, replacing whatever used
  651.  *    to be there.  If no error occurs, then Postscript for the
  652.  *    item is appended to the result.
  653.  *
  654.  * Side effects:
  655.  *    None.
  656.  *
  657.  *--------------------------------------------------------------
  658.  */
  659.  
  660. static int
  661. BitmapToPostscript(canvasPtr, itemPtr, psInfoPtr)
  662.     Tk_Canvas *canvasPtr;        /* Information about overall canvas. */
  663.     Tk_Item *itemPtr;            /* Item for which Postscript is
  664.                      * wanted. */
  665.     Tk_PostscriptInfo *psInfoPtr;    /* Information about the Postscript;
  666.                      * must be passed back to Postscript
  667.                      * utility procedures. */
  668. {
  669.     register BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
  670.     double x, y;
  671.     unsigned int width, height;
  672.     char buffer[200];
  673.  
  674.     /*
  675.      * Compute the coordinates of the lower-left corner of the bitmap,
  676.      * taking into account the anchor position for the bitmp.
  677.      */
  678.  
  679.     x = bmapPtr->x;
  680.     y = TkCanvPsY(psInfoPtr, bmapPtr->y);
  681.     Tk_SizeOfBitmap(canvasPtr->display, bmapPtr->bitmap, &width, &height);
  682.     switch (bmapPtr->anchor) {
  683.     case TK_ANCHOR_NW:            y -= height;        break;
  684.     case TK_ANCHOR_N:    x -= width/2.0; y -= height;        break;
  685.     case TK_ANCHOR_NE:    x -= width;    y -= height;        break;
  686.     case TK_ANCHOR_E:    x -= width;    y -= height/2.0;    break;
  687.     case TK_ANCHOR_SE:    x -= width;                break;
  688.     case TK_ANCHOR_S:    x -= width/2.0;                break;
  689.     case TK_ANCHOR_SW:                        break;
  690.     case TK_ANCHOR_W:            y -= height/2.0;    break;
  691.     case TK_ANCHOR_CENTER:    x -= width/2.0; y -= height/2.0;    break;
  692.     }
  693.  
  694.     /*
  695.      * Color the background, if there is one.
  696.      */
  697.  
  698.     if (bmapPtr->bgColor != NULL) {
  699.     sprintf(buffer,
  700.         "%.15g %.15g moveto %d 0 rlineto 0 %d rlineto %d %s\n",
  701.         x, y, width, height, -width,"0 rlineto closepath");
  702.     Tcl_AppendResult(canvasPtr->interp, buffer, (char *) NULL);
  703.     if (TkCanvPsColor(canvasPtr, psInfoPtr, bmapPtr->bgColor) != TCL_OK) {
  704.         return TCL_ERROR;
  705.     }
  706.     Tcl_AppendResult(canvasPtr->interp, "fill\n", (char *) NULL);
  707.     }
  708.  
  709.     /*
  710.      * Draw the bitmap, if there is a foreground color.
  711.      */
  712.  
  713.  
  714.     if (bmapPtr->fgColor != NULL) {
  715.     if (TkCanvPsColor(canvasPtr, psInfoPtr, bmapPtr->fgColor) != TCL_OK) {
  716.         return TCL_ERROR;
  717.     }
  718.     sprintf(buffer, "%.15g %.15g translate\n %d %d true matrix {\n",
  719.         x, y, width, height);
  720.     Tcl_AppendResult(canvasPtr->interp, buffer, (char *) NULL);
  721.     if (TkCanvPsBitmap(canvasPtr, psInfoPtr, bmapPtr->bitmap) != TCL_OK) {
  722.         return TCL_ERROR;
  723.     }
  724.     Tcl_AppendResult(canvasPtr->interp, "\n} imagemask\n", (char *) NULL);
  725.     }
  726.     return TCL_OK;
  727. }
  728.