📄 tkrectoval.c
字号:
} if (rectOvalPtr->fillColor != NULL) { Tk_FreeColor(rectOvalPtr->fillColor); } if (rectOvalPtr->fillStipple != None) { Tk_FreeBitmap(canvasPtr->display, rectOvalPtr->fillStipple); } if (rectOvalPtr->outlineGC != None) { Tk_FreeGC(canvasPtr->display, rectOvalPtr->outlineGC); } if (rectOvalPtr->fillGC != None) { Tk_FreeGC(canvasPtr->display, rectOvalPtr->fillGC); }}/* *-------------------------------------------------------------- * * ComputeRectOvalBbox -- * * This procedure is invoked to compute the bounding box of * all the pixels that may be drawn as part of a rectangle * or oval. * * Results: * None. * * Side effects: * The fields x1, y1, x2, and y2 are updated in the header * for itemPtr. * *-------------------------------------------------------------- */ /* ARGSUSED */static voidComputeRectOvalBbox(canvasPtr, rectOvalPtr) Tk_Canvas *canvasPtr; /* Canvas that contains item. */ register RectOvalItem *rectOvalPtr; /* Item whose bbox is to be * recomputed. */{ int bloat; /* * Make sure that the first coordinates are the lowest ones. */ if (rectOvalPtr->bbox[1] > rectOvalPtr->bbox[3]) { double tmp; tmp = rectOvalPtr->bbox[3]; rectOvalPtr->bbox[3] = rectOvalPtr->bbox[1]; rectOvalPtr->bbox[1] = tmp; } if (rectOvalPtr->bbox[0] > rectOvalPtr->bbox[2]) { double tmp; tmp = rectOvalPtr->bbox[2]; rectOvalPtr->bbox[2] = rectOvalPtr->bbox[0]; rectOvalPtr->bbox[0] = tmp; } bloat = (rectOvalPtr->width+1)/2 + 1; rectOvalPtr->header.x1 = rectOvalPtr->bbox[0] - bloat; rectOvalPtr->header.y1 = rectOvalPtr->bbox[1] - bloat; rectOvalPtr->header.x2 = rectOvalPtr->bbox[2] + bloat; rectOvalPtr->header.y2 = rectOvalPtr->bbox[3] + bloat;}/* *-------------------------------------------------------------- * * DisplayRectOval -- * * This procedure is invoked to draw a rectangle or oval * item in a given drawable. * * Results: * None. * * Side effects: * ItemPtr is drawn in drawable using the transformation * information in canvasPtr. * *-------------------------------------------------------------- */static voidDisplayRectOval(canvasPtr, itemPtr, drawable) register Tk_Canvas *canvasPtr; /* Canvas that contains item. */ Tk_Item *itemPtr; /* Item to be displayed. */ Drawable drawable; /* Pixmap or window in which to draw * item. */{ register RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; Display *display = Tk_Display(canvasPtr->tkwin); int x1, y1, x2, y2; /* * Compute the screen coordinates of the bounding box for the item. * Make sure that the bbox is at least one pixel large, since some * X servers will die if it isn't. */ x1 = SCREEN_X(canvasPtr, rectOvalPtr->bbox[0]); y1 = SCREEN_Y(canvasPtr, rectOvalPtr->bbox[1]); x2 = SCREEN_X(canvasPtr, rectOvalPtr->bbox[2]); y2 = SCREEN_Y(canvasPtr, rectOvalPtr->bbox[3]); if (x2 <= x1) { x2 = x1+1; } if (y2 <= y1) { y2 = y1+1; } /* * Display filled part first (if wanted), then outline. If we're * stippling, then modify the stipple offset in the GC. Be sure to * reset the offset when done, since the GC is supposed to be * read-only. */ if (rectOvalPtr->fillGC != None) { if (rectOvalPtr->fillStipple != None) { XSetTSOrigin(display, rectOvalPtr->fillGC, -canvasPtr->drawableXOrigin, -canvasPtr->drawableYOrigin); } if (rectOvalPtr->header.typePtr == &TkRectangleType) { XFillRectangle(display, drawable, rectOvalPtr->fillGC, x1, y1, (unsigned int) (x2-x1), (unsigned int) (y2-y1)); } else { XFillArc(display, drawable, rectOvalPtr->fillGC, x1, y1, (x2-x1), (y2-y1), 0, 360*64); } if (rectOvalPtr->fillStipple != None) { XSetTSOrigin(display, rectOvalPtr->fillGC, 0, 0); } } if (rectOvalPtr->outlineGC != None) { if (rectOvalPtr->header.typePtr == &TkRectangleType) { XDrawRectangle(display, drawable, rectOvalPtr->outlineGC, x1, y1, (x2-x1), (y2-y1)); } else { XDrawArc(display, drawable, rectOvalPtr->outlineGC, x1, y1, (x2-x1), (y2-y1), 0, 360*64); } }}/* *-------------------------------------------------------------- * * RectToPoint -- * * 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 rectangle. If the * point isn't inside the rectangle then the return value is the * distance from the point to the rectangle. If itemPtr is filled, * then anywhere in the interior is considered "inside"; if * itemPtr isn't filled, then "inside" means only the area * occupied by the outline. * * Side effects: * None. * *-------------------------------------------------------------- */ /* ARGSUSED */static doubleRectToPoint(canvasPtr, itemPtr, pointPtr) Tk_Canvas *canvasPtr; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item to check against point. */ double *pointPtr; /* Pointer to x and y coordinates. */{ register RectOvalItem *rectPtr = (RectOvalItem *) itemPtr; double xDiff, yDiff, x1, y1, x2, y2, inc, tmp; /* * Generate a new larger rectangle that includes the border * width, if there is one. */ x1 = rectPtr->bbox[0]; y1 = rectPtr->bbox[1]; x2 = rectPtr->bbox[2]; y2 = rectPtr->bbox[3]; if (rectPtr->outlineGC != None) { inc = rectPtr->width/2.0; x1 -= inc; y1 -= inc; x2 += inc; y2 += inc; } /* * If the point is inside the rectangle, handle specially: * distance is 0 if rectangle is filled, otherwise compute * distance to nearest edge of rectangle and subtract width * of edge. */ if ((pointPtr[0] >= x1) && (pointPtr[0] < x2) && (pointPtr[1] >= y1) && (pointPtr[1] < y2)) { if ((rectPtr->fillGC != None) || (rectPtr->outlineGC == None)) { return 0.0; } xDiff = pointPtr[0] - x1; tmp = x2 - pointPtr[0]; if (tmp < xDiff) { xDiff = tmp; } yDiff = pointPtr[1] - y1; tmp = y2 - pointPtr[1]; if (tmp < yDiff) { yDiff = tmp; } if (yDiff < xDiff) { xDiff = yDiff; } xDiff -= rectPtr->width; if (xDiff < 0.0) { return 0.0; } return xDiff; } /* * Point is outside rectangle. */ if (pointPtr[0] < x1) { xDiff = x1 - pointPtr[0]; } else if (pointPtr[0] > x2) { xDiff = pointPtr[0] - x2; } else { xDiff = 0; } if (pointPtr[1] < y1) { yDiff = y1 - pointPtr[1]; } else if (pointPtr[1] > y2) { yDiff = pointPtr[1] - y2; } else { yDiff = 0; } return hypot(xDiff, yDiff);}/* *-------------------------------------------------------------- * * OvalToPoint -- * * Computes the distance from a given point to a given * oval, 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 oval. If the * point isn't inside the oval then the return value is the * distance from the point to the oval. If itemPtr is filled, * then anywhere in the interior is considered "inside"; if * itemPtr isn't filled, then "inside" means only the area * occupied by the outline. * * Side effects: * None. * *-------------------------------------------------------------- */ /* ARGSUSED */static doubleOvalToPoint(canvasPtr, itemPtr, pointPtr) Tk_Canvas *canvasPtr; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item to check against point. */ double *pointPtr; /* Pointer to x and y coordinates. */{ register RectOvalItem *ovalPtr = (RectOvalItem *) itemPtr; double width; int filled; width = ovalPtr->width; filled = ovalPtr->fillGC != None; if (ovalPtr->outlineGC == None) { width = 0.0; filled = 1; } return TkOvalToPoint(ovalPtr->bbox, width, filled, pointPtr);}/* *-------------------------------------------------------------- * * RectToArea -- * * 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 intRectToArea(canvasPtr, itemPtr, areaPtr) Tk_Canvas *canvasPtr; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item to check against rectangle. */ double *areaPtr; /* Pointer to array of four coordinates * (x1, y1, x2, y2) describing rectangular * area. */{ register RectOvalItem *rectPtr = (RectOvalItem *) itemPtr; double halfWidth; halfWidth = rectPtr->width/2.0; if (rectPtr->outlineGC == None) { halfWidth = 0.0; } if ((areaPtr[2] <= (rectPtr->bbox[0] - halfWidth)) || (areaPtr[0] >= (rectPtr->bbox[2] + halfWidth)) || (areaPtr[3] <= (rectPtr->bbox[1] - halfWidth)) || (areaPtr[1] >= (rectPtr->bbox[3] + halfWidth))) { return -1; } if ((rectPtr->fillGC == None) && (rectPtr->outlineGC != None) && (areaPtr[0] >= (rectPtr->bbox[0] + halfWidth)) && (areaPtr[1] >= (rectPtr->bbox[1] + halfWidth)) && (areaPtr[2] <= (rectPtr->bbox[2] - halfWidth)) && (areaPtr[3] <= (rectPtr->bbox[3] - halfWidth))) { return -1; } if ((areaPtr[0] <= (rectPtr->bbox[0] - halfWidth)) && (areaPtr[1] <= (rectPtr->bbox[1] - halfWidth)) && (areaPtr[2] >= (rectPtr->bbox[2] + halfWidth)) && (areaPtr[3] >= (rectPtr->bbox[3] + halfWidth))) { return 1; } return 0;}/* *-------------------------------------------------------------- * * OvalToArea -- * * This procedure is called to determine whether an item * lies entirely inside, entirely outside, or overlapping * a given rectangular area. * * 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 intOvalToArea(canvasPtr, itemPtr, areaPtr) Tk_Canvas *canvasPtr; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item to check against oval. */ double *areaPtr; /* Pointer to array of four coordinates * (x1, y1, x2, y2) describing rectangular * area. */{ register RectOvalItem *ovalPtr = (RectOvalItem *) itemPtr; double oval[4], halfWidth; int result; /* * Expand the oval to include the width of the outline, if any. */ halfWidth = ovalPtr->width/2.0; if (ovalPtr->outlineGC == None) { halfWidth = 0.0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -