/* ARGSUSED */ void TkTextInsertDisplayProc( TkText *textPtr, /* The current text widget. */ TkTextDispChunk *chunkPtr, /* Chunk that is to be drawn. */ int x, /* X-position in dst at which to draw this * chunk (may differ from the x-position in * the chunk because of scrolling). */ int y, /* Y-position at which to draw this chunk in * dst (x-position is in the chunk itself). */ int height, /* Total height of line. */ int baseline, /* Offset of baseline from y. */ Display *display, /* Display to use for drawing. */ Drawable dst, /* Pixmap or window in which to draw chunk. */ int screenY) /* Y-coordinate in text window that * corresponds to y. */ { /* * We have no need for the clientData. */ /* TkText *textPtr = (TkText *) chunkPtr->clientData; */ TkTextIndex index; int halfWidth = textPtr->insertWidth/2; int rightSideWidth; int ix = 0, iy = 0, iw = 0, ih = 0, charWidth = 0; if(textPtr->insertCursorType) { TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index); TkTextIndexBbox(textPtr, &index, &ix, &iy, &iw, &ih, &charWidth); rightSideWidth = charWidth + halfWidth; } else { rightSideWidth = halfWidth; } if ((x + rightSideWidth) < 0) { /* * The insertion cursor is off-screen. Indicate caret at 0,0 and * return. */ Tk_SetCaretPos(textPtr->tkwin, 0, 0, height); return; } Tk_SetCaretPos(textPtr->tkwin, x - halfWidth, screenY, height); /* * As a special hack to keep the cursor visible on mono displays (or * anywhere else that the selection and insertion cursors have the same * color) write the default background in the cursor area (instead of * nothing) when the cursor isn't on. Otherwise the selection might hide * the cursor. */ if (textPtr->flags & INSERT_ON) { Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder, x - halfWidth, y, charWidth + textPtr->insertWidth, height, textPtr->insertBorderWidth, TK_RELIEF_RAISED); } else if (textPtr->selBorder == textPtr->insertBorder) { Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->border, x - halfWidth, y, charWidth + textPtr->insertWidth, height, 0, TK_RELIEF_FLAT); } }
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); } }