📄 tkrectoval.c
字号:
rectOvalPtr->outlineGC = newGC; if (rectOvalPtr->fillColor == NULL) { newGC = None; } else { gcValues.foreground = rectOvalPtr->fillColor->pixel; if (rectOvalPtr->fillStipple != None) { gcValues.stipple = rectOvalPtr->fillStipple; gcValues.fill_style = FillStippled; mask = GCForeground|GCStipple|GCFillStyle; } else { mask = GCForeground; } newGC = Tk_GetGC(tkwin, mask, &gcValues); } if (rectOvalPtr->fillGC != None) { Tk_FreeGC(Tk_Display(tkwin), rectOvalPtr->fillGC); } rectOvalPtr->fillGC = newGC; ComputeRectOvalBbox(canvas, rectOvalPtr); return TCL_OK;}/* *-------------------------------------------------------------- * * DeleteRectOval -- * * This procedure is called to clean up the data structure * associated with a rectangle or oval item. * * Results: * None. * * Side effects: * Resources associated with itemPtr are released. * *-------------------------------------------------------------- */static voidDeleteRectOval(canvas, itemPtr, display) Tk_Canvas canvas; /* Info about overall widget. */ Tk_Item *itemPtr; /* Item that is being deleted. */ Display *display; /* Display containing window for * canvas. */{ RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; if (rectOvalPtr->outlineColor != NULL) { Tk_FreeColor(rectOvalPtr->outlineColor); } if (rectOvalPtr->fillColor != NULL) { Tk_FreeColor(rectOvalPtr->fillColor); } if (rectOvalPtr->fillStipple != None) { Tk_FreeBitmap(display, rectOvalPtr->fillStipple); } if (rectOvalPtr->outlineGC != None) { Tk_FreeGC(display, rectOvalPtr->outlineGC); } if (rectOvalPtr->fillGC != None) { Tk_FreeGC(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(canvas, rectOvalPtr) Tk_Canvas canvas; /* Canvas that contains item. */ RectOvalItem *rectOvalPtr; /* Item whose bbox is to be * recomputed. */{ int bloat, tmp; double dtmp; /* * 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; } if (rectOvalPtr->outlineColor == NULL) { bloat = 0; } else { bloat = (rectOvalPtr->width+1)/2; } /* * Special note: the rectangle is always drawn at least 1x1 in * size, so round up the upper coordinates to be at least 1 unit * greater than the lower ones. */ tmp = (int) ((rectOvalPtr->bbox[0] >= 0) ? rectOvalPtr->bbox[0] + .5 : rectOvalPtr->bbox[0] - .5); rectOvalPtr->header.x1 = tmp - bloat; tmp = (int) ((rectOvalPtr->bbox[1] >= 0) ? rectOvalPtr->bbox[1] + .5 : rectOvalPtr->bbox[1] - .5); rectOvalPtr->header.y1 = tmp - bloat; dtmp = rectOvalPtr->bbox[2]; if (dtmp < (rectOvalPtr->bbox[0] + 1)) { dtmp = rectOvalPtr->bbox[0] + 1; } tmp = (int) ((dtmp >= 0) ? dtmp + .5 : dtmp - .5); rectOvalPtr->header.x2 = tmp + bloat; dtmp = rectOvalPtr->bbox[3]; if (dtmp < (rectOvalPtr->bbox[1] + 1)) { dtmp = rectOvalPtr->bbox[1] + 1; } tmp = (int) ((dtmp >= 0) ? dtmp + .5 : dtmp - .5); rectOvalPtr->header.y2 = tmp + 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 canvas. * *-------------------------------------------------------------- */static voidDisplayRectOval(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). */{ RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; short 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. */ Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[0], rectOvalPtr->bbox[1], &x1, &y1); Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[2], rectOvalPtr->bbox[3], &x2, &y2); 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) { Tk_CanvasSetStippleOrigin(canvas, rectOvalPtr->fillGC); } 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, (unsigned) (x2-x1), (unsigned) (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, (unsigned) (x2-x1), (unsigned) (y2-y1)); } else { XDrawArc(display, drawable, rectOvalPtr->outlineGC, x1, y1, (unsigned) (x2-x1), (unsigned) (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(canvas, itemPtr, pointPtr) Tk_Canvas canvas; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item to check against point. */ double *pointPtr; /* Pointer to x and y coordinates. */{ 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -