📄 tktextdisp.c
字号:
/* * tkTextDisp.c -- * * This module provides facilities to display text widgets. It is * the only place where information is kept about the screen layout * of text widgets. * * Copyright (c) 1992-1994 The Regents of the University of California. * Copyright (c) 1994-1997 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: @(#) tkTextDisp.c 1.124 97/07/11 18:01:03 */#include "tkPort.h"#include "tkInt.h"#include "tkText.h"/* * The following structure describes how to display a range of characters. * The information is generated by scanning all of the tags associated * with the characters and combining that with default information for * the overall widget. These structures form the hash keys for * dInfoPtr->styleTable. */typedef struct StyleValues { Tk_3DBorder border; /* Used for drawing background under text. * NULL means use widget background. */ int borderWidth; /* Width of 3-D border for background. */ int relief; /* 3-D relief for background. */ Pixmap bgStipple; /* Stipple bitmap for background. None * means draw solid. */ XColor *fgColor; /* Foreground color for text. */ Tk_Font tkfont; /* Font for displaying text. */ Pixmap fgStipple; /* Stipple bitmap for text and other * foreground stuff. None means draw * solid.*/ int justify; /* Justification style for text. */ int lMargin1; /* Left margin, in pixels, for first display * line of each text line. */ int lMargin2; /* Left margin, in pixels, for second and * later display lines of each text line. */ int offset; /* Offset in pixels of baseline, relative to * baseline of line. */ int overstrike; /* Non-zero means draw overstrike through * text. */ int rMargin; /* Right margin, in pixels. */ int spacing1; /* Spacing above first dline in text line. */ int spacing2; /* Spacing between lines of dline. */ int spacing3; /* Spacing below last dline in text line. */ TkTextTabArray *tabArrayPtr;/* Locations and types of tab stops (may * be NULL). */ int underline; /* Non-zero means draw underline underneath * text. */ Tk_Uid wrapMode; /* How to handle wrap-around for this tag. * One of tkTextCharUid, tkTextNoneUid, * or tkTextWordUid. */} StyleValues;/* * The following structure extends the StyleValues structure above with * graphics contexts used to actually draw the characters. The entries * in dInfoPtr->styleTable point to structures of this type. */typedef struct TextStyle { int refCount; /* Number of times this structure is * referenced in Chunks. */ GC bgGC; /* Graphics context for background. None * means use widget background. */ GC fgGC; /* Graphics context for foreground. */ StyleValues *sValuePtr; /* Raw information from which GCs were * derived. */ Tcl_HashEntry *hPtr; /* Pointer to entry in styleTable. Used * to delete entry. */} TextStyle;/* * The following macro determines whether two styles have the same * background so that, for example, no beveled border should be drawn * between them. */#define SAME_BACKGROUND(s1, s2) \ (((s1)->sValuePtr->border == (s2)->sValuePtr->border) \ && ((s1)->sValuePtr->borderWidth == (s2)->sValuePtr->borderWidth) \ && ((s1)->sValuePtr->relief == (s2)->sValuePtr->relief) \ && ((s1)->sValuePtr->bgStipple == (s2)->sValuePtr->bgStipple))/* * The following structure describes one line of the display, which may * be either part or all of one line of the text. */typedef struct DLine { TkTextIndex index; /* Identifies first character in text * that is displayed on this line. */ int count; /* Number of characters accounted for by this * display line, including a trailing space * or newline that isn't actually displayed. */ int y; /* Y-position at which line is supposed to * be drawn (topmost pixel of rectangular * area occupied by line). */ int oldY; /* Y-position at which line currently * appears on display. -1 means line isn't * currently visible on display and must be * redrawn. This is used to move lines by * scrolling rather than re-drawing. */ int height; /* Height of line, in pixels. */ int baseline; /* Offset of text baseline from y, in * pixels. */ int spaceAbove; /* How much extra space was added to the * top of the line because of spacing * options. This is included in height * and baseline. */ int spaceBelow; /* How much extra space was added to the * bottom of the line because of spacing * options. This is included in height. */ int length; /* Total length of line, in pixels. */ TkTextDispChunk *chunkPtr; /* Pointer to first chunk in list of all * of those that are displayed on this * line of the screen. */ struct DLine *nextPtr; /* Next in list of all display lines for * this window. The list is sorted in * order from top to bottom. Note: the * next DLine doesn't always correspond * to the next line of text: (a) can have * multiple DLines for one text line, and * (b) can have gaps where DLine's have been * deleted because they're out of date. */ int flags; /* Various flag bits: see below for values. */} DLine;/* * Flag bits for DLine structures: * * HAS_3D_BORDER - Non-zero means that at least one of the * chunks in this line has a 3D border, so * it potentially interacts with 3D borders * in neighboring lines (see * DisplayLineBackground). * NEW_LAYOUT - Non-zero means that the line has been * re-layed out since the last time the * display was updated. * TOP_LINE - Non-zero means that this was the top line * in the window the last time that the window * was laid out. This is important because * a line may be displayed differently if its * at the top or bottom than if it's in the * middle (e.g. beveled edges aren't displayed * for middle lines if the adjacent line has * a similar background). * BOTTOM_LINE - Non-zero means that this was the bottom line * in the window the last time that the window * was laid out. */#define HAS_3D_BORDER 1#define NEW_LAYOUT 2#define TOP_LINE 4#define BOTTOM_LINE 8/* * Overall display information for a text widget: */typedef struct TextDInfo { Tcl_HashTable styleTable; /* Hash table that maps from StyleValues * to TextStyles for this widget. */ DLine *dLinePtr; /* First in list of all display lines for * this widget, in order from top to bottom. */ GC copyGC; /* Graphics context for copying from off- * screen pixmaps onto screen. */ GC scrollGC; /* Graphics context for copying from one place * in the window to another (scrolling): * differs from copyGC in that we need to get * GraphicsExpose events. */ int x; /* First x-coordinate that may be used for * actually displaying line information. * Leaves space for border, etc. */ int y; /* First y-coordinate that may be used for * actually displaying line information. * Leaves space for border, etc. */ int maxX; /* First x-coordinate to right of available * space for displaying lines. */ int maxY; /* First y-coordinate below available * space for displaying lines. */ int topOfEof; /* Top-most pixel (lowest y-value) that has * been drawn in the appropriate fashion for * the portion of the window after the last * line of the text. This field is used to * figure out when to redraw part or all of * the eof field. */ /* * Information used for scrolling: */ int newCharOffset; /* Desired x scroll position, measured as the * number of average-size characters off-screen * to the left for a line with no left * margin. */ int curPixelOffset; /* Actual x scroll position, measured as the * number of pixels off-screen to the left. */ int maxLength; /* Length in pixels of longest line that's * visible in window (length may exceed window * size). If there's no wrapping, this will * be zero. */ double xScrollFirst, xScrollLast; /* Most recent values reported to horizontal * scrollbar; used to eliminate unnecessary * reports. */ double yScrollFirst, yScrollLast; /* Most recent values reported to vertical * scrollbar; used to eliminate unnecessary * reports. */ /* * The following information is used to implement scanning: */ int scanMarkChar; /* Character that was at the left edge of * the window when the scan started. */ int scanMarkX; /* X-position of mouse at time scan started. */ int scanTotalScroll; /* Total scrolling (in screen lines) that has * occurred since scanMarkY was set. */ int scanMarkY; /* Y-position of mouse at time scan started. */ /* * Miscellaneous information: */ int dLinesInvalidated; /* This value is set to 1 whenever something * happens that invalidates information in * DLine structures; if a redisplay * is in progress, it will see this and * abort the redisplay. This is needed * because, for example, an embedded window * could change its size when it is first * displayed, invalidating the DLine that * is currently being displayed. If redisplay * continues, it will use freed memory and * could dump core. */ int flags; /* Various flag values: see below for * definitions. */} TextDInfo;/* * In TkTextDispChunk structures for character segments, the clientData * field points to one of the following structures: */typedef struct CharInfo { int numChars; /* Number of characters to display. */ char chars[4]; /* Characters to display. Actual size * will be numChars, not 4. THIS MUST BE * THE LAST FIELD IN THE STRUCTURE. */} CharInfo;/* * Flag values for TextDInfo structures: * * DINFO_OUT_OF_DATE: Non-zero means that the DLine structures * for this window are partially or completely * out of date and need to be recomputed. * REDRAW_PENDING: Means that a when-idle handler has been * scheduled to update the display. * REDRAW_BORDERS: Means window border or pad area has * potentially been damaged and must be redrawn. * REPICK_NEEDED: 1 means that the widget has been modified * in a way that could change the current * character (a different character might be * under the mouse cursor now). Need to * recompute the current character before * the next redisplay. */#define DINFO_OUT_OF_DATE 1#define REDRAW_PENDING 2#define REDRAW_BORDERS 4#define REPICK_NEEDED 8/* * The following counters keep statistics about redisplay that can be * checked to see how clever this code is at reducing redisplays. */static int numRedisplays; /* Number of calls to DisplayText. */static int linesRedrawn; /* Number of calls to DisplayDLine. */static int numCopies; /* Number of calls to XCopyArea to copy part * of the screen. *//* * Forward declarations for procedures defined later in this file: */static void AdjustForTab _ANSI_ARGS_((TkText *textPtr, TkTextTabArray *tabArrayPtr, int index, TkTextDispChunk *chunkPtr));static void CharBboxProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr, int index, int y, int lineHeight, int baseline, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr));static void CharDisplayProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY));static int CharMeasureProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr, int x));static void CharUndisplayProc _ANSI_ARGS_((TkText *textPtr, TkTextDispChunk *chunkPtr));static void DisplayDLine _ANSI_ARGS_((TkText *textPtr, DLine *dlPtr, DLine *prevPtr, Pixmap pixmap));static void DisplayLineBackground _ANSI_ARGS_((TkText *textPtr, DLine *dlPtr, DLine *prevPtr, Pixmap pixmap));static void DisplayText _ANSI_ARGS_((ClientData clientData));static DLine * FindDLine _ANSI_ARGS_((DLine *dlPtr, TkTextIndex *indexPtr));static void FreeDLines _ANSI_ARGS_((TkText *textPtr, DLine *firstPtr, DLine *lastPtr, int unlink));static void FreeStyle _ANSI_ARGS_((TkText *textPtr, TextStyle *stylePtr));static TextStyle * GetStyle _ANSI_ARGS_((TkText *textPtr, TkTextIndex *indexPtr));static void GetXView _ANSI_ARGS_((Tcl_Interp *interp, TkText *textPtr, int report));static void GetYView _ANSI_ARGS_((Tcl_Interp *interp, TkText *textPtr, int report));static DLine * LayoutDLine _ANSI_ARGS_((TkText *textPtr, TkTextIndex *indexPtr));static int MeasureChars _ANSI_ARGS_((Tk_Font tkfont, CONST char *source, int maxChars, int startX, int maxX, int tabOrigin, int *nextXPtr));static void MeasureUp _ANSI_ARGS_((TkText *textPtr, TkTextIndex *srcPtr, int distance, TkTextIndex *dstPtr));static int NextTabStop _ANSI_ARGS_((Tk_Font tkfont, int x, int tabOrigin));static void UpdateDisplayInfo _ANSI_ARGS_((TkText *textPtr));static void ScrollByLines _ANSI_ARGS_((TkText *textPtr, int offset));static int SizeOfTab _ANSI_ARGS_((TkText *textPtr, TkTextTabArray *tabArrayPtr, int index, int x, int maxX));static void TextInvalidateRegion _ANSI_ARGS_((TkText *textPtr, TkRegion region));/* *---------------------------------------------------------------------- * * TkTextCreateDInfo -- * * This procedure is called when a new text widget is created. * Its job is to set up display-related information for the widget. * * Results: * None. * * Side effects: * A TextDInfo data structure is allocated and initialized and attached * to textPtr. * *---------------------------------------------------------------------- */voidTkTextCreateDInfo(textPtr) TkText *textPtr; /* Overall information for text widget. */{ register TextDInfo *dInfoPtr; XGCValues gcValues; dInfoPtr = (TextDInfo *) ckalloc(sizeof(TextDInfo)); Tcl_InitHashTable(&dInfoPtr->styleTable, sizeof(StyleValues)/sizeof(int)); dInfoPtr->dLinePtr = NULL; dInfoPtr->copyGC = None; gcValues.graphics_exposures = True; dInfoPtr->scrollGC = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures, &gcValues); dInfoPtr->topOfEof = 0; dInfoPtr->newCharOffset = 0; dInfoPtr->curPixelOffset = 0; dInfoPtr->maxLength = 0; dInfoPtr->xScrollFirst = -1; dInfoPtr->xScrollLast = -1; dInfoPtr->yScrollFirst = -1; dInfoPtr->yScrollLast = -1; dInfoPtr->scanMarkChar = 0; dInfoPtr->scanMarkX = 0; dInfoPtr->scanTotalScroll = 0; dInfoPtr->scanMarkY = 0; dInfoPtr->dLinesInvalidated = 0; dInfoPtr->flags = DINFO_OUT_OF_DATE; textPtr->dInfoPtr = dInfoPtr;}/* *---------------------------------------------------------------------- * * TkTextFreeDInfo -- *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -