📄 tkcanvbmap.c
字号:
case TK_ANCHOR_S: x -= width/2; y -= height; break; case TK_ANCHOR_SW: y -= height; break; case TK_ANCHOR_W: y -= height/2; break; case TK_ANCHOR_NW: break; case TK_ANCHOR_CENTER: x -= width/2; y -= height/2; break; } /* * Store the information in the item header. */ bmapPtr->header.x1 = x; bmapPtr->header.y1 = y; bmapPtr->header.x2 = x + width; bmapPtr->header.y2 = y + height;}/* *-------------------------------------------------------------- * * DisplayBitmap -- * * This procedure is invoked to draw a bitmap item in a given * drawable. * * Results: * None. * * Side effects: * ItemPtr is drawn in drawable using the transformation * information in canvas. * *-------------------------------------------------------------- */static voidDisplayBitmap(canvas, itemPtr, display, drawable, x, y, width, height) Tk_Canvas canvas; /* Canvas that contains item. */ Tk_Item *itemPtr; /* Item to be displayed. */ Display *display; /* Display on which to draw item. */ Drawable drawable; /* Pixmap or window in which to draw * item. */ int x, y, width, height; /* Describes region of canvas that * must be redisplayed (not used). */{ BitmapItem *bmapPtr = (BitmapItem *) itemPtr; int bmapX, bmapY, bmapWidth, bmapHeight; short drawableX, drawableY; /* * If the area being displayed doesn't cover the whole bitmap, * then only redisplay the part of the bitmap that needs * redisplay. */ if (bmapPtr->bitmap != None) { if (x > bmapPtr->header.x1) { bmapX = x - bmapPtr->header.x1; bmapWidth = bmapPtr->header.x2 - x; } else { bmapX = 0; if ((x+width) < bmapPtr->header.x2) { bmapWidth = x + width - bmapPtr->header.x1; } else { bmapWidth = bmapPtr->header.x2 - bmapPtr->header.x1; } } if (y > bmapPtr->header.y1) { bmapY = y - bmapPtr->header.y1; bmapHeight = bmapPtr->header.y2 - y; } else { bmapY = 0; if ((y+height) < bmapPtr->header.y2) { bmapHeight = y + height - bmapPtr->header.y1; } else { bmapHeight = bmapPtr->header.y2 - bmapPtr->header.y1; } } Tk_CanvasDrawableCoords(canvas, (double) (bmapPtr->header.x1 + bmapX), (double) (bmapPtr->header.y1 + bmapY), &drawableX, &drawableY); /* * Must modify the mask origin within the graphics context * to line up with the bitmap's origin (in order to make * bitmaps with "-background {}" work right). */ XSetClipOrigin(display, bmapPtr->gc, drawableX - bmapX, drawableY - bmapY); XCopyPlane(display, bmapPtr->bitmap, drawable, bmapPtr->gc, bmapX, bmapY, (unsigned int) bmapWidth, (unsigned int) bmapHeight, drawableX, drawableY, 1); }}/* *-------------------------------------------------------------- * * BitmapToPoint -- * * Computes the distance from a given point to a given * rectangle, in canvas units. * * Results: * The return value is 0 if the point whose x and y coordinates * are coordPtr[0] and coordPtr[1] is inside the bitmap. If the * point isn't inside the bitmap then the return value is the * distance from the point to the bitmap. * * Side effects: * None. * *-------------------------------------------------------------- */ /* ARGSUSED */static doubleBitmapToPoint(canvas, itemPtr, coordPtr) Tk_Canvas canvas; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item to check against point. */ double *coordPtr; /* Pointer to x and y coordinates. */{ BitmapItem *bmapPtr = (BitmapItem *) itemPtr; double x1, x2, y1, y2, xDiff, yDiff; x1 = bmapPtr->header.x1; y1 = bmapPtr->header.y1; x2 = bmapPtr->header.x2; y2 = bmapPtr->header.y2; /* * Point is outside rectangle. */ if (coordPtr[0] < x1) { xDiff = x1 - coordPtr[0]; } else if (coordPtr[0] > x2) { xDiff = coordPtr[0] - x2; } else { xDiff = 0; } if (coordPtr[1] < y1) { yDiff = y1 - coordPtr[1]; } else if (coordPtr[1] > y2) { yDiff = coordPtr[1] - y2; } else { yDiff = 0; } return hypot(xDiff, yDiff);}/* *-------------------------------------------------------------- * * BitmapToArea -- * * This procedure is called to determine whether an item * lies entirely inside, entirely outside, or overlapping * a given rectangle. * * Results: * -1 is returned if the item is entirely outside the area * given by rectPtr, 0 if it overlaps, and 1 if it is entirely * inside the given area. * * Side effects: * None. * *-------------------------------------------------------------- */ /* ARGSUSED */static intBitmapToArea(canvas, itemPtr, rectPtr) Tk_Canvas canvas; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item to check against rectangle. */ double *rectPtr; /* Pointer to array of four coordinates * (x1, y1, x2, y2) describing rectangular * area. */{ BitmapItem *bmapPtr = (BitmapItem *) itemPtr; if ((rectPtr[2] <= bmapPtr->header.x1) || (rectPtr[0] >= bmapPtr->header.x2) || (rectPtr[3] <= bmapPtr->header.y1) || (rectPtr[1] >= bmapPtr->header.y2)) { return -1; } if ((rectPtr[0] <= bmapPtr->header.x1) && (rectPtr[1] <= bmapPtr->header.y1) && (rectPtr[2] >= bmapPtr->header.x2) && (rectPtr[3] >= bmapPtr->header.y2)) { return 1; } return 0;}/* *-------------------------------------------------------------- * * ScaleBitmap -- * * This procedure is invoked to rescale a bitmap item in a * canvas. It is one of the standard item procedures for * bitmap items, and is invoked by the generic canvas code. * * Results: * None. * * Side effects: * The item referred to by itemPtr is rescaled so that the * following transformation is applied to all point coordinates: * x' = originX + scaleX*(x-originX) * y' = originY + scaleY*(y-originY) * *-------------------------------------------------------------- */static voidScaleBitmap(canvas, itemPtr, originX, originY, scaleX, scaleY) Tk_Canvas canvas; /* Canvas containing rectangle. */ Tk_Item *itemPtr; /* Rectangle to be scaled. */ double originX, originY; /* Origin about which to scale item. */ double scaleX; /* Amount to scale in X direction. */ double scaleY; /* Amount to scale in Y direction. */{ BitmapItem *bmapPtr = (BitmapItem *) itemPtr; bmapPtr->x = originX + scaleX*(bmapPtr->x - originX); bmapPtr->y = originY + scaleY*(bmapPtr->y - originY); ComputeBitmapBbox(canvas, bmapPtr);}/* *-------------------------------------------------------------- * * TranslateBitmap -- * * This procedure is called to move an item by a given amount. * * Results: * None. * * Side effects: * The position of the item is offset by (xDelta, yDelta), and * the bounding box is updated in the generic part of the item * structure. * *-------------------------------------------------------------- */static voidTranslateBitmap(canvas, itemPtr, deltaX, deltaY) Tk_Canvas canvas; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item that is being moved. */ double deltaX, deltaY; /* Amount by which item is to be * moved. */{ BitmapItem *bmapPtr = (BitmapItem *) itemPtr; bmapPtr->x += deltaX; bmapPtr->y += deltaY; ComputeBitmapBbox(canvas, bmapPtr);}/* *-------------------------------------------------------------- * * BitmapToPostscript -- * * This procedure is called to generate Postscript for * bitmap 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 intBitmapToPostscript(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. */{ BitmapItem *bmapPtr = (BitmapItem *) itemPtr; double x, y; int width, height, rowsAtOnce, rowsThisTime; int curRow; char buffer[200]; if (bmapPtr->bitmap == None) { return TCL_OK; } /* * Compute the coordinates of the lower-left corner of the bitmap, * taking into account the anchor position for the bitmp. */ x = bmapPtr->x; y = Tk_CanvasPsY(canvas, bmapPtr->y); Tk_SizeOfBitmap(Tk_Display(Tk_CanvasTkwin(canvas)), bmapPtr->bitmap, &width, &height); switch (bmapPtr->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; } /* * Color the background, if there is one. */ if (bmapPtr->bgColor != NULL) { sprintf(buffer, "%.15g %.15g moveto %d 0 rlineto 0 %d rlineto %d %s\n", x, y, width, height, -width,"0 rlineto closepath"); Tcl_AppendResult(interp, buffer, (char *) NULL); if (Tk_CanvasPsColor(interp, canvas, bmapPtr->bgColor) != TCL_OK) { return TCL_ERROR; } Tcl_AppendResult(interp, "fill\n", (char *) NULL); } /* * Draw the bitmap, if there is a foreground color. If the bitmap * is very large, then chop it up into multiple bitmaps, each * consisting of one or more rows. This is needed because Postscript * can't handle single strings longer than 64 KBytes long. */ if (bmapPtr->fgColor != NULL) { if (Tk_CanvasPsColor(interp, canvas, bmapPtr->fgColor) != TCL_OK) { return TCL_ERROR; } if (width > 60000) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "can't generate Postscript", " for bitmaps more than 60000 pixels wide", (char *) NULL); return TCL_ERROR; } rowsAtOnce = 60000/width; if (rowsAtOnce < 1) { rowsAtOnce = 1; } sprintf(buffer, "%.15g %.15g translate\n", x, y+height); Tcl_AppendResult(interp, buffer, (char *) NULL); for (curRow = 0; curRow < height; curRow += rowsAtOnce) { rowsThisTime = rowsAtOnce; if (rowsThisTime > (height - curRow)) { rowsThisTime = height - curRow; } sprintf(buffer, "0 -%.15g translate\n%d %d true matrix {\n", (double) rowsThisTime, width, rowsThisTime); Tcl_AppendResult(interp, buffer, (char *) NULL); if (Tk_CanvasPsBitmap(interp, canvas, bmapPtr->bitmap, 0, curRow, width, rowsThisTime) != TCL_OK) { return TCL_ERROR; } Tcl_AppendResult(interp, "\n} imagemask\n", (char *) NULL); } } return TCL_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -