static void DiamondIndicatorElementDraw( void *clientData, void *elementRecord, Tk_Window tkwin, Drawable d, Ttk_Box b, unsigned int state) { IndicatorElement *indicator = elementRecord; Tk_3DBorder border = 0, interior = 0; int borderWidth = 2; int relief = TK_RELIEF_RAISED; int diameter, radius; XPoint points[4]; Ttk_Padding padding; interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj); border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj); Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth); Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief); Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding); b = Ttk_PadBox(b, padding); diameter = b.width < b.height ? b.width : b.height; radius = diameter / 2; points[0].x = b.x; points[0].y = b.y + radius; points[1].x = b.x + radius; points[1].y = b.y + 2*radius; points[2].x = b.x + 2*radius; points[2].y = b.y + radius; points[3].x = b.x + radius; points[3].y = b.y; Tk_Fill3DPolygon(tkwin,d,interior,points,4,borderWidth,TK_RELIEF_FLAT); Tk_Draw3DPolygon(tkwin,d,border,points,4,borderWidth,relief); }
static void DrawMenuEntryAccelerator( TkMenu *menuPtr, /* The menu we are drawing */ TkMenuEntry *mePtr, /* The entry we are drawing */ Drawable d, /* The drawable we are drawing into */ GC gc, /* The precalculated gc to draw with */ Tk_Font tkfont, /* The precalculated font */ const Tk_FontMetrics *fmPtr,/* The precalculated metrics */ Tk_3DBorder activeBorder, /* The border for an active item */ int x, /* Left coordinate of entry rect */ int y, /* Top coordinate of entry rect */ int width, /* Width of entry */ int height, /* Height of entry */ int drawArrow) /* Whether or not to draw arrow. */ { XPoint points[3]; int borderWidth, activeBorderWidth; /* * Draw accelerator or cascade arrow. */ if (menuPtr->menuType == MENUBAR) { return; } Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, &borderWidth); Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr, &activeBorderWidth); if ((mePtr->type == CASCADE_ENTRY) && drawArrow) { points[0].x = x + width - borderWidth - activeBorderWidth - CASCADE_ARROW_WIDTH; points[0].y = y + (height - CASCADE_ARROW_HEIGHT)/2; points[1].x = points[0].x; points[1].y = points[0].y + CASCADE_ARROW_HEIGHT; points[2].x = points[0].x + CASCADE_ARROW_WIDTH; points[2].y = points[0].y + CASCADE_ARROW_HEIGHT/2; Tk_Fill3DPolygon(menuPtr->tkwin, d, activeBorder, points, 3, DECORATION_BORDER_WIDTH, (menuPtr->postedCascade == mePtr) ? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED); } else if (mePtr->accelPtr != NULL) { const char *accel = Tcl_GetString(mePtr->accelPtr); int left = x + mePtr->labelWidth + activeBorderWidth + mePtr->indicatorSpace; if (menuPtr->menuType == MENUBAR) { left += 5; } Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, mePtr->accelLength, left, (y + (height + fmPtr->ascent - fmPtr->descent) / 2)); } }
static void ArrowElementDraw( void *clientData, void *elementRecord, Tk_Window tkwin, Drawable d, Ttk_Box b, unsigned int state) { int direction = *(int *)clientData; ArrowElement *arrow = elementRecord; Tk_3DBorder border; int borderWidth; int relief = TK_RELIEF_RAISED; int size; XPoint points[3]; Tk_GetPixelsFromObj(NULL, tkwin, arrow->borderWidthObj, &borderWidth); border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj); Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief); size = b.width < b.height ? b.width : b.height; /* * @@@ There are off-by-one pixel errors in the way these are drawn; * @@@ need to take a look at Tk_Fill3DPolygon and X11 to find the * @@@ exact rules. */ switch (direction) { case ARROW_UP: points[2].x = b.x; points[2].y = b.y + size; points[1].x = b.x + size/2; points[1].y = b.y; points[0].x = b.x + size; points[0].y = b.y + size; break; case ARROW_DOWN: points[0].x = b.x; points[0].y = b.y; points[1].x = b.x + size/2; points[1].y = b.y + size; points[2].x = b.x + size; points[2].y = b.y; break; case ARROW_LEFT: points[0].x = b.x; points[0].y = b.y + size / 2; points[1].x = b.x + size; points[1].y = b.y + size; points[2].x = b.x + size; points[2].y = b.y; break; case ARROW_RIGHT: points[0].x = b.x + size; points[0].y = b.y + size / 2; points[1].x = b.x; points[1].y = b.y; points[2].x = b.x; points[2].y = b.y + size; break; } Tk_Fill3DPolygon(tkwin, d, border, points, 3, borderWidth, relief); }
static void DisplayCanvText( 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, int y, int width, int height) /* Describes region of canvas that must be * redisplayed (not used). */ { TextItem *textPtr; Tk_CanvasTextInfo *textInfoPtr; int selFirstChar, selLastChar; short drawableX, drawableY; Pixmap stipple; Tk_State state = itemPtr->state; textPtr = (TextItem *) itemPtr; textInfoPtr = textPtr->textInfoPtr; if (state == TK_STATE_NULL) { state = Canvas(canvas)->canvas_state; } stipple = textPtr->stipple; if (Canvas(canvas)->currentItemPtr == itemPtr) { if (textPtr->activeStipple != None) { stipple = textPtr->activeStipple; } } else if (state == TK_STATE_DISABLED) { if (textPtr->disabledStipple != None) { stipple = textPtr->disabledStipple; } } if (textPtr->gc == NULL) { return; } /* * 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 (stipple != None) { Tk_CanvasSetOffset(canvas, textPtr->gc, &textPtr->tsoffset); } selFirstChar = -1; selLastChar = 0; /* lint. */ Tk_CanvasDrawableCoords(canvas, textPtr->drawOrigin[0], textPtr->drawOrigin[1], &drawableX, &drawableY); if (textInfoPtr->selItemPtr == itemPtr) { selFirstChar = textInfoPtr->selectFirst; selLastChar = textInfoPtr->selectLast; if (selLastChar > textPtr->numChars) { selLastChar = textPtr->numChars - 1; } if ((selFirstChar >= 0) && (selFirstChar <= selLastChar)) { int xFirst, yFirst, hFirst; int xLast, yLast, wLast; /* * Draw a special background under the selection. */ Tk_CharBbox(textPtr->textLayout, selFirstChar, &xFirst, &yFirst, NULL, &hFirst); Tk_CharBbox(textPtr->textLayout, selLastChar, &xLast, &yLast, &wLast, NULL); /* * If the selection spans the end of this line, then display * selection background all the way to the end of the line. * However, for the last line we only want to display up to the * last character, not the end of the line. */ x = xFirst; height = hFirst; for (y = yFirst ; y <= yLast; y += height) { int dx1, dy1, dx2, dy2; double s = textPtr->sine, c = textPtr->cosine; XPoint points[4]; if (y == yLast) { width = xLast + wLast - x; } else { width = textPtr->actualWidth - x; } dx1 = x - textInfoPtr->selBorderWidth; dy1 = y; dx2 = width + 2 * textInfoPtr->selBorderWidth; dy2 = height; points[0].x = (short)(drawableX + dx1*c + dy1*s); points[0].y = (short)(drawableY + dy1*c - dx1*s); points[1].x = (short)(drawableX + (dx1+dx2)*c + dy1*s); points[1].y = (short)(drawableY + dy1*c - (dx1+dx2)*s); points[2].x = (short)(drawableX + (dx1+dx2)*c + (dy1+dy2)*s); points[2].y = (short)(drawableY + (dy1+dy2)*c - (dx1+dx2)*s); points[3].x = (short)(drawableX + dx1*c + (dy1+dy2)*s); points[3].y = (short)(drawableY + (dy1+dy2)*c - dx1*s); Tk_Fill3DPolygon(Tk_CanvasTkwin(canvas), drawable, textInfoPtr->selBorder, points, 4, textInfoPtr->selBorderWidth, TK_RELIEF_RAISED); x = 0; } } } /* * If the insertion point should be displayed, then draw a special * background for the cursor before drawing the text. Note: if we're the * cursor item but the cursor is turned off, then redraw background over * the area of the cursor. This guarantees that the selection won't make * the cursor invisible on mono displays, where both are drawn in the same * color. */ if ((textInfoPtr->focusItemPtr == itemPtr) && (textInfoPtr->gotFocus)) { if (Tk_CharBbox(textPtr->textLayout, textPtr->insertPos, &x, &y, NULL, &height)) { int dx1, dy1, dx2, dy2; double s = textPtr->sine, c = textPtr->cosine; XPoint points[4]; dx1 = x - (textInfoPtr->insertWidth / 2); dy1 = y; dx2 = textInfoPtr->insertWidth; dy2 = height; points[0].x = (short)(drawableX + dx1*c + dy1*s); points[0].y = (short)(drawableY + dy1*c - dx1*s); points[1].x = (short)(drawableX + (dx1+dx2)*c + dy1*s); points[1].y = (short)(drawableY + dy1*c - (dx1+dx2)*s); points[2].x = (short)(drawableX + (dx1+dx2)*c + (dy1+dy2)*s); points[2].y = (short)(drawableY + (dy1+dy2)*c - (dx1+dx2)*s); points[3].x = (short)(drawableX + dx1*c + (dy1+dy2)*s); points[3].y = (short)(drawableY + (dy1+dy2)*c - dx1*s); Tk_SetCaretPos(Tk_CanvasTkwin(canvas), points[0].x, points[0].y, height); if (textInfoPtr->cursorOn) { Tk_Fill3DPolygon(Tk_CanvasTkwin(canvas), drawable, textInfoPtr->insertBorder, points, 4, textInfoPtr->insertBorderWidth, TK_RELIEF_RAISED); } else if (textPtr->cursorOffGC != NULL) { /* * Redraw the background over the area of the cursor, even * though the cursor is turned off. This guarantees that the * selection won't make the cursor invisible on mono displays, * where both may be drawn in the same color. */ XFillPolygon(display, drawable, textPtr->cursorOffGC, points, 4, Convex, CoordModeOrigin); } } } /* * If there is no selected text or the selected text foreground is the * same as the regular text foreground, then draw one text string. If * there is selected text and the foregrounds differ, draw the regular * text up to the selection, draw the selection, then draw the rest of the * regular text. Drawing the regular text and then the selected text over * it would causes problems with anti-aliased text because the two * anti-aliasing colors would blend together. */ if ((selFirstChar >= 0) && (textPtr->selTextGC != textPtr->gc)) { TkDrawAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, 0, selFirstChar); TkDrawAngledTextLayout(display, drawable, textPtr->selTextGC, textPtr->textLayout, drawableX, drawableY, textPtr->angle, selFirstChar, selLastChar + 1); TkDrawAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, selLastChar + 1, -1); } else { TkDrawAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, 0, -1); } TkUnderlineAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, textPtr->underline); if (stipple != None) { XSetTSOrigin(display, textPtr->gc, 0, 0); } }