📄 tkcanvtext.c
字号:
*-------------------------------------------------------------- */static voidDeleteText(canvas, itemPtr, display) Tk_Canvas canvas; /* Info about overall canvas widget. */ Tk_Item *itemPtr; /* Item that is being deleted. */ Display *display; /* Display containing window for * canvas. */{ TextItem *textPtr = (TextItem *) itemPtr; if (textPtr->color != NULL) { Tk_FreeColor(textPtr->color); } Tk_FreeFont(textPtr->tkfont); if (textPtr->stipple != None) { Tk_FreeBitmap(display, textPtr->stipple); } if (textPtr->text != NULL) { ckfree(textPtr->text); } Tk_FreeTextLayout(textPtr->textLayout); if (textPtr->gc != None) { Tk_FreeGC(display, textPtr->gc); } if (textPtr->selTextGC != None) { Tk_FreeGC(display, textPtr->selTextGC); } if (textPtr->cursorOffGC != None) { Tk_FreeGC(display, textPtr->cursorOffGC); }}/* *-------------------------------------------------------------- * * ComputeTextBbox -- * * This procedure is invoked to compute the bounding box of * all the pixels that may be drawn as part of a text item. * In addition, it recomputes all of the geometry information * used to display a text item or check for mouse hits. * * Results: * None. * * Side effects: * The fields x1, y1, x2, and y2 are updated in the header * for itemPtr, and the linePtr structure is regenerated * for itemPtr. * *-------------------------------------------------------------- */static voidComputeTextBbox(canvas, textPtr) Tk_Canvas canvas; /* Canvas that contains item. */ TextItem *textPtr; /* Item whose bbos is to be * recomputed. */{ Tk_CanvasTextInfo *textInfoPtr; int leftX, topY, width, height, fudge; Tk_FreeTextLayout(textPtr->textLayout); textPtr->textLayout = Tk_ComputeTextLayout(textPtr->tkfont, textPtr->text, textPtr->numChars, textPtr->width, textPtr->justify, 0, &width, &height); /* * Use overall geometry information to compute the top-left corner * of the bounding box for the text item. */ leftX = (int) (textPtr->x + 0.5); topY = (int) (textPtr->y + 0.5); switch (textPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_N: case TK_ANCHOR_NE: break; case TK_ANCHOR_W: case TK_ANCHOR_CENTER: case TK_ANCHOR_E: topY -= height / 2; break; case TK_ANCHOR_SW: case TK_ANCHOR_S: case TK_ANCHOR_SE: topY -= height; break; } switch (textPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: break; case TK_ANCHOR_N: case TK_ANCHOR_CENTER: case TK_ANCHOR_S: leftX -= width / 2; break; case TK_ANCHOR_NE: case TK_ANCHOR_E: case TK_ANCHOR_SE: leftX -= width; break; } textPtr->leftEdge = leftX; textPtr->rightEdge = leftX + width; /* * Last of all, update the bounding box for the item. The item's * bounding box includes the bounding box of all its lines, plus * an extra fudge factor for the cursor border (which could * potentially be quite large). */ textInfoPtr = textPtr->textInfoPtr; fudge = (textInfoPtr->insertWidth + 1) / 2; if (textInfoPtr->selBorderWidth > fudge) { fudge = textInfoPtr->selBorderWidth; } textPtr->header.x1 = leftX - fudge; textPtr->header.y1 = topY; textPtr->header.x2 = leftX + width + fudge; textPtr->header.y2 = topY + height;}/* *-------------------------------------------------------------- * * DisplayCanvText -- * * This procedure is invoked to draw a text item in a given * drawable. * * Results: * None. * * Side effects: * ItemPtr is drawn in drawable using the transformation * information in canvas. * *-------------------------------------------------------------- */static voidDisplayCanvText(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). */{ TextItem *textPtr; Tk_CanvasTextInfo *textInfoPtr; int selFirst, selLast; short drawableX, drawableY; textPtr = (TextItem *) itemPtr; textInfoPtr = textPtr->textInfoPtr; if (textPtr->gc == None) { 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 (textPtr->stipple != None) { Tk_CanvasSetStippleOrigin(canvas, textPtr->gc); } selFirst = -1; selLast = 0; /* lint. */ if (textInfoPtr->selItemPtr == itemPtr) { selFirst = textInfoPtr->selectFirst; selLast = textInfoPtr->selectLast; if (selLast >= textPtr->numChars) { selLast = textPtr->numChars - 1; } if ((selFirst >= 0) && (selFirst <= selLast)) { /* * Draw a special background under the selection. */ int xFirst, yFirst, hFirst; int xLast, yLast, wLast; Tk_CharBbox(textPtr->textLayout, selFirst, &xFirst, &yFirst, NULL, &hFirst); Tk_CharBbox(textPtr->textLayout, selLast, &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) { if (y == yLast) { width = (xLast + wLast) - x; } else { width = textPtr->rightEdge - textPtr->leftEdge - x; } Tk_CanvasDrawableCoords(canvas, (double) (textPtr->leftEdge + x - textInfoPtr->selBorderWidth), (double) (textPtr->header.y1 + y), &drawableX, &drawableY); Tk_Fill3DRectangle(Tk_CanvasTkwin(canvas), drawable, textInfoPtr->selBorder, drawableX, drawableY, width + 2 * textInfoPtr->selBorderWidth, height, 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)) { Tk_CanvasDrawableCoords(canvas, (double) (textPtr->leftEdge + x - (textInfoPtr->insertWidth / 2)), (double) (textPtr->header.y1 + y), &drawableX, &drawableY); if (textInfoPtr->cursorOn) { Tk_Fill3DRectangle(Tk_CanvasTkwin(canvas), drawable, textInfoPtr->insertBorder, drawableX, drawableY, textInfoPtr->insertWidth, height, textInfoPtr->insertBorderWidth, TK_RELIEF_RAISED); } else if (textPtr->cursorOffGC != None) { /* * 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. */ XFillRectangle(display, drawable, textPtr->cursorOffGC, drawableX, drawableY, (unsigned) textInfoPtr->insertWidth, (unsigned) height); } } } /* * Display the text in two pieces: draw the entire text item, then * draw the selected text on top of it. The selected text then * will only need to be drawn if it has different attributes (such * as foreground color) than regular text. */ Tk_CanvasDrawableCoords(canvas, (double) textPtr->leftEdge, (double) textPtr->header.y1, &drawableX, &drawableY); Tk_DrawTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, 0, -1); if ((selFirst >= 0) && (textPtr->selTextGC != textPtr->gc)) { Tk_DrawTextLayout(display, drawable, textPtr->selTextGC, textPtr->textLayout, drawableX, drawableY, selFirst, selLast + 1); } if (textPtr->stipple != None) { XSetTSOrigin(display, textPtr->gc, 0, 0); }}/* *-------------------------------------------------------------- * * TextInsert -- * * Insert characters into a text item at a given position. * * Results: * None. * * Side effects: * The text in the given item is modified. The cursor and * selection positions are also modified to reflect the * insertion. * *-------------------------------------------------------------- */static voidTextInsert(canvas, itemPtr, beforeThis, string) Tk_Canvas canvas; /* Canvas containing text item. */ Tk_Item *itemPtr; /* Text item to be modified. */ int beforeThis; /* Index of character before which text is * to be inserted. */ char *string; /* New characters to be inserted. */{ TextItem *textPtr = (TextItem *) itemPtr; int length; char *new; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; length = strlen(string); if (length == 0) { return; } if (beforeThis < 0) { beforeThis = 0; } if (beforeThis > textPtr->numChars) { beforeThis = textPtr->numChars; } new = (char *) ckalloc((unsigned) (textPtr->numChars + length + 1)); strncpy(new, textPtr->text, (size_t) beforeThis); strcpy(new+beforeThis, string); strcpy(new+beforeThis+length, textPtr->text+beforeThis); ckfree(textPtr->text); textPtr->text = new; textPtr->numChars += length; /* * Inserting characters invalidates indices such as those for the * selection and cursor. Update the indices appropriately. */ if (textInfoPtr->selItemPtr == itemPtr) { if (textInfoPtr->selectFirst >= beforeThis) { textInfoPtr->selectFirst += length; } if (textInfoPtr->selectLast >= beforeThis) { textInfoPtr->selectLast += length; } if ((textInfoPtr->anchorItemPtr == itemPtr) && (textInfoPtr->selectAnchor >= beforeThis)) { textInfoPtr->selectAnchor += length; } } if (textPtr->insertPos >= beforeThis) { textPtr->insertPos += length; } ComputeTextBbox(canvas, textPtr);}/* *-------------------------------------------------------------- * * TextDeleteChars -- * * Delete one or more characters from a text item. * * Results: * None. * * Side effects: * Characters between "first" and "last", inclusive, get * deleted from itemPtr, and things like the selection * position get updated. * *-------------------------------------------------------------- */static voidTextDeleteChars(canvas, itemPtr, first, last) Tk_Canvas canvas; /* Canvas containing itemPtr. */ Tk_Item *itemPtr; /* Item in which to delete characters. */ int first; /* Index of first character to delete. */ int last; /* Index of last character to delete. */{ TextItem *textPtr = (TextItem *) itemPtr; int count; char *new; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; if (first < 0) { first = 0; } if (last >= textPtr->numChars) { last = textPtr->numChars-1; } if (first > last) { return; } count = last + 1 - first; new = (char *) ckalloc((unsigned) (textPtr->numChars + 1 - count)); strncpy(new, textPtr->text, (size_t) first); strcpy(new+first, textPtr->text+last+1); ckfree(textPtr->text); textPtr->text = new; textPtr->numChars -= count; /* * Update indexes for the selection and cursor to reflect the * renumbering of the remaining characters. */ if (textInfoPtr->selItemPtr == itemPtr) { if (textInfoPtr->selectFirst > first) { textInfoPtr->selectFirst -= count; if (textInfoPtr->selectFirst < first) { textInfoPtr->selectFirst = first; } } if (textInfoPtr->selectLast >= first) { textInfoPtr->selectLast -= count; if (textInfoPtr->selectLast < (first-1)) { textInfoPtr->selectLast = (first-1); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -