📄 tkcanvtext.c
字号:
/* * tkCanvText.c -- * * This file implements text items for canvas widgets. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkCanvText.c 1.68 97/10/09 17:44:53 */#include <stdio.h>#include "tkInt.h"#include "tkCanvas.h"#include "tkPort.h"#include "default.h"/* * The structure below defines the record for each text item. */typedef struct TextItem { Tk_Item header; /* Generic stuff that's the same for all * types. MUST BE FIRST IN STRUCTURE. */ Tk_CanvasTextInfo *textInfoPtr; /* Pointer to a structure containing * information about the selection and * insertion cursor. The structure is owned * by (and shared with) the generic canvas * code. */ /* * Fields that are set by widget commands other than "configure". */ double x, y; /* Positioning point for text. */ int insertPos; /* Insertion cursor is displayed just to left * of character with this index. */ /* * Configuration settings that are updated by Tk_ConfigureWidget. */ Tk_Anchor anchor; /* Where to anchor text relative to (x,y). */ XColor *color; /* Color for text. */ Tk_Font tkfont; /* Font for drawing text. */ Tk_Justify justify; /* Justification mode for text. */ Pixmap stipple; /* Stipple bitmap for text, or None. */ char *text; /* Text for item (malloc-ed). */ int width; /* Width of lines for word-wrap, pixels. * Zero means no word-wrap. */ /* * Fields whose values are derived from the current values of the * configuration settings above. */ int numChars; /* Number of non-NULL characters in text. */ Tk_TextLayout textLayout; /* Cached text layout information. */ int leftEdge; /* Pixel location of the left edge of the * text item; where the left border of the * text layout is drawn. */ int rightEdge; /* Pixel just to right of right edge of * area of text item. Used for selecting up * to end of line. */ GC gc; /* Graphics context for drawing text. */ GC selTextGC; /* Graphics context for selected text. */ GC cursorOffGC; /* If not None, this gives a graphics context * to use to draw the insertion cursor when * it's off. Used if the selection and * insertion cursor colors are the same. */} TextItem;/* * Information used for parsing configuration specs: */static Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, (ClientData) NULL};static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL, "center", Tk_Offset(TextItem, anchor), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL, "black", Tk_Offset(TextItem, color), 0}, {TK_CONFIG_FONT, "-font", (char *) NULL, (char *) NULL, DEF_CANVTEXT_FONT, Tk_Offset(TextItem, tkfont), 0}, {TK_CONFIG_JUSTIFY, "-justify", (char *) NULL, (char *) NULL, "left", Tk_Offset(TextItem, justify), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL, (char *) NULL, Tk_Offset(TextItem, stipple), TK_CONFIG_NULL_OK}, {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL, (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, "-text", (char *) NULL, (char *) NULL, "", Tk_Offset(TextItem, text), 0}, {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL, "0", Tk_Offset(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, 0, 0}};/* * Prototypes for procedures defined in this file: */static void ComputeTextBbox _ANSI_ARGS_((Tk_Canvas canvas, TextItem *textPtr));static int ConfigureText _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int argc, char **argv, int flags));static int CreateText _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, int argc, char **argv));static void DeleteText _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, Display *display));static void DisplayCanvText _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, Display *display, Drawable dst, int x, int y, int width, int height));static int GetSelText _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, int offset, char *buffer, int maxBytes));static int GetTextIndex _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, char *indexString, int *indexPtr));static void ScaleText _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, double originX, double originY, double scaleX, double scaleY));static void SetTextCursor _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, int index));static int TextCoords _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int argc, char **argv));static void TextDeleteChars _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, int first, int last));static void TextInsert _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, int beforeThis, char *string));static int TextToArea _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, double *rectPtr));static double TextToPoint _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, double *pointPtr));static int TextToPostscript _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));static void TranslateText _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, double deltaX, double deltaY));/* * The structures below defines the rectangle and oval item types * by means of procedures that can be invoked by generic item code. */Tk_ItemType tkTextType = { "text", /* name */ sizeof(TextItem), /* itemSize */ CreateText, /* createProc */ configSpecs, /* configSpecs */ ConfigureText, /* configureProc */ TextCoords, /* coordProc */ DeleteText, /* deleteProc */ DisplayCanvText, /* displayProc */ 0, /* alwaysRedraw */ TextToPoint, /* pointProc */ TextToArea, /* areaProc */ TextToPostscript, /* postscriptProc */ ScaleText, /* scaleProc */ TranslateText, /* translateProc */ GetTextIndex, /* indexProc */ SetTextCursor, /* icursorProc */ GetSelText, /* selectionProc */ TextInsert, /* insertProc */ TextDeleteChars, /* dTextProc */ (Tk_ItemType *) NULL /* nextPtr */};/* *-------------------------------------------------------------- * * CreateText -- * * This procedure is invoked to create a new text item * in a canvas. * * Results: * A standard Tcl return value. If an error occurred in * creating the item then an error message is left in * interp->result; in this case itemPtr is left uninitialized * so it can be safely freed by the caller. * * Side effects: * A new text item is created. * *-------------------------------------------------------------- */static intCreateText(interp, canvas, itemPtr, argc, argv) Tcl_Interp *interp; /* Interpreter for error reporting. */ Tk_Canvas canvas; /* Canvas to hold new item. */ Tk_Item *itemPtr; /* Record to hold new item; header * has been initialized by caller. */ int argc; /* Number of arguments in argv. */ char **argv; /* Arguments describing rectangle. */{ TextItem *textPtr = (TextItem *) itemPtr; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tk_PathName(Tk_CanvasTkwin(canvas)), " create ", itemPtr->typePtr->name, " x y ?options?\"", (char *) NULL); return TCL_ERROR; } /* * Carry out initialization that is needed in order to clean * up after errors during the the remainder of this procedure. */ textPtr->textInfoPtr = Tk_CanvasGetTextInfo(canvas); textPtr->insertPos = 0; textPtr->anchor = TK_ANCHOR_CENTER; textPtr->color = NULL; textPtr->tkfont = NULL; textPtr->justify = TK_JUSTIFY_LEFT; textPtr->stipple = None; textPtr->text = NULL; textPtr->width = 0; textPtr->numChars = 0; textPtr->textLayout = NULL; textPtr->leftEdge = 0; textPtr->rightEdge = 0; textPtr->gc = None; textPtr->selTextGC = None; textPtr->cursorOffGC = None; /* * Process the arguments to fill in the item record. */ if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &textPtr->x) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[1], &textPtr->y) != TCL_OK)) { return TCL_ERROR; } if (ConfigureText(interp, canvas, itemPtr, argc-2, argv+2, 0) != TCL_OK) { DeleteText(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas))); return TCL_ERROR; } return TCL_OK;}/* *-------------------------------------------------------------- * * TextCoords -- * * This procedure is invoked to process the "coords" widget * command on text items. See the user documentation for * details on what it does. * * Results: * Returns TCL_OK or TCL_ERROR, and sets interp->result. * * Side effects: * The coordinates for the given item may be changed. * *-------------------------------------------------------------- */static intTextCoords(interp, canvas, itemPtr, argc, argv) Tcl_Interp *interp; /* Used for error reporting. */ Tk_Canvas canvas; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item whose coordinates are to be * read or modified. */ int argc; /* Number of coordinates supplied in * argv. */ char **argv; /* Array of coordinates: x1, y1, * x2, y2, ... */{ TextItem *textPtr = (TextItem *) itemPtr; char x[TCL_DOUBLE_SPACE], y[TCL_DOUBLE_SPACE]; if (argc == 0) { Tcl_PrintDouble(interp, textPtr->x, x); Tcl_PrintDouble(interp, textPtr->y, y); Tcl_AppendResult(interp, x, " ", y, (char *) NULL); } else if (argc == 2) { if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &textPtr->x) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[1], &textPtr->y) != TCL_OK)) { return TCL_ERROR; } ComputeTextBbox(canvas, textPtr); } else { sprintf(interp->result, "wrong # coordinates: expected 0 or 2, got %d", argc); return TCL_ERROR; } return TCL_OK;}/* *-------------------------------------------------------------- * * ConfigureText -- * * This procedure is invoked to configure various aspects * of a text item, such as its border and background colors. * * Results: * A standard Tcl result code. If an error occurs, then * an error message is left in interp->result. * * Side effects: * Configuration information, such as colors and stipple * patterns, may be set for itemPtr. * *-------------------------------------------------------------- */static intConfigureText(interp, canvas, itemPtr, argc, argv, flags) Tcl_Interp *interp; /* Interpreter for error reporting. */ Tk_Canvas canvas; /* Canvas containing itemPtr. */ Tk_Item *itemPtr; /* Rectangle item to reconfigure. */ int argc; /* Number of elements in argv. */ char **argv; /* Arguments describing things to configure. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */{ TextItem *textPtr = (TextItem *) itemPtr; XGCValues gcValues; GC newGC, newSelGC; unsigned long mask; Tk_Window tkwin; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; XColor *selBgColorPtr; tkwin = Tk_CanvasTkwin(canvas); if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, argv, (char *) textPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * A few of the options require additional processing, such as * graphics contexts. */ newGC = newSelGC = None; if ((textPtr->color != NULL) && (textPtr->tkfont != NULL)) { gcValues.foreground = textPtr->color->pixel; gcValues.font = Tk_FontId(textPtr->tkfont); mask = GCForeground|GCFont; if (textPtr->stipple != None) { gcValues.stipple = textPtr->stipple; gcValues.fill_style = FillStippled; mask |= GCForeground|GCStipple|GCFillStyle; } newGC = Tk_GetGC(tkwin, mask, &gcValues); gcValues.foreground = textInfoPtr->selFgColorPtr->pixel; newSelGC = Tk_GetGC(tkwin, mask, &gcValues); } if (textPtr->gc != None) { Tk_FreeGC(Tk_Display(tkwin), textPtr->gc); } textPtr->gc = newGC; if (textPtr->selTextGC != None) { Tk_FreeGC(Tk_Display(tkwin), textPtr->selTextGC); } textPtr->selTextGC = newSelGC; selBgColorPtr = Tk_3DBorderColor(textInfoPtr->selBorder); if (Tk_3DBorderColor(textInfoPtr->insertBorder)->pixel == selBgColorPtr->pixel) { if (selBgColorPtr->pixel == BlackPixelOfScreen(Tk_Screen(tkwin))) { gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin)); } else { gcValues.foreground = BlackPixelOfScreen(Tk_Screen(tkwin)); } newGC = Tk_GetGC(tkwin, GCForeground, &gcValues); } else { newGC = None; } if (textPtr->cursorOffGC != None) { Tk_FreeGC(Tk_Display(tkwin), textPtr->cursorOffGC); } textPtr->cursorOffGC = newGC; /* * If the text was changed, move the selection and insertion indices * to keep them inside the item. */ textPtr->numChars = strlen(textPtr->text); if (textInfoPtr->selItemPtr == itemPtr) { if (textInfoPtr->selectFirst >= textPtr->numChars) { textInfoPtr->selItemPtr = NULL; } else { if (textInfoPtr->selectLast >= textPtr->numChars) { textInfoPtr->selectLast = textPtr->numChars-1; } if ((textInfoPtr->anchorItemPtr == itemPtr) && (textInfoPtr->selectAnchor >= textPtr->numChars)) { textInfoPtr->selectAnchor = textPtr->numChars-1; } } } if (textPtr->insertPos >= textPtr->numChars) { textPtr->insertPos = textPtr->numChars; } ComputeTextBbox(canvas, textPtr); return TCL_OK;}/* *-------------------------------------------------------------- * * DeleteText -- * * This procedure is called to clean up the data structure * associated with a text item. * * Results: * None. * * Side effects: * Resources associated with itemPtr are released. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -