📄 tktextdisp.c
字号:
* This procedure is called to free up all of the private display * information kept by this file for a text widget. * * Results: * None. * * Side effects: * Lots of resources get freed. * *---------------------------------------------------------------------- */voidTkTextFreeDInfo(textPtr) TkText *textPtr; /* Overall information for text widget. */{ register TextDInfo *dInfoPtr = textPtr->dInfoPtr; /* * Be careful to free up styleTable *after* freeing up all the * DLines, so that the hash table is still intact to free up the * style-related information from the lines. Once the lines are * all free then styleTable will be empty. */ FreeDLines(textPtr, dInfoPtr->dLinePtr, (DLine *) NULL, 1); Tcl_DeleteHashTable(&dInfoPtr->styleTable); if (dInfoPtr->copyGC != None) { Tk_FreeGC(textPtr->display, dInfoPtr->copyGC); } Tk_FreeGC(textPtr->display, dInfoPtr->scrollGC); if (dInfoPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayText, (ClientData) textPtr); } ckfree((char *) dInfoPtr);}/* *---------------------------------------------------------------------- * * GetStyle -- * * This procedure creates all the information needed to display * text at a particular location. * * Results: * The return value is a pointer to a TextStyle structure that * corresponds to *sValuePtr. * * Side effects: * A new entry may be created in the style table for the widget. * *---------------------------------------------------------------------- */static TextStyle *GetStyle(textPtr, indexPtr) TkText *textPtr; /* Overall information about text widget. */ TkTextIndex *indexPtr; /* The character in the text for which * display information is wanted. */{ TkTextTag **tagPtrs; register TkTextTag *tagPtr; StyleValues styleValues; TextStyle *stylePtr; Tcl_HashEntry *hPtr; int numTags, new, i; XGCValues gcValues; unsigned long mask; /* * The variables below keep track of the highest-priority specification * that has occurred for each of the various fields of the StyleValues. */ int borderPrio, borderWidthPrio, reliefPrio, bgStipplePrio; int fgPrio, fontPrio, fgStipplePrio; int underlinePrio, justifyPrio, offsetPrio; int lMargin1Prio, lMargin2Prio, rMarginPrio; int spacing1Prio, spacing2Prio, spacing3Prio; int overstrikePrio, tabPrio, wrapPrio; /* * Find out what tags are present for the character, then compute * a StyleValues structure corresponding to those tags (scan * through all of the tags, saving information for the highest- * priority tag). */ tagPtrs = TkBTreeGetTags(indexPtr, &numTags); borderPrio = borderWidthPrio = reliefPrio = bgStipplePrio = -1; fgPrio = fontPrio = fgStipplePrio = -1; underlinePrio = justifyPrio = offsetPrio = -1; lMargin1Prio = lMargin2Prio = rMarginPrio = -1; spacing1Prio = spacing2Prio = spacing3Prio = -1; overstrikePrio = tabPrio = wrapPrio = -1; memset((VOID *) &styleValues, 0, sizeof(StyleValues)); styleValues.relief = TK_RELIEF_FLAT; styleValues.fgColor = textPtr->fgColor; styleValues.tkfont = textPtr->tkfont; styleValues.justify = TK_JUSTIFY_LEFT; styleValues.spacing1 = textPtr->spacing1; styleValues.spacing2 = textPtr->spacing2; styleValues.spacing3 = textPtr->spacing3; styleValues.tabArrayPtr = textPtr->tabArrayPtr; styleValues.wrapMode = textPtr->wrapMode; for (i = 0 ; i < numTags; i++) { tagPtr = tagPtrs[i]; /* * On Windows and Mac, we need to skip the selection tag if * we don't have focus. */#ifndef ALWAYS_SHOW_SELECTION if ((tagPtr == textPtr->selTagPtr) && !(textPtr->flags & GOT_FOCUS)) { continue; }#endif if ((tagPtr->border != NULL) && (tagPtr->priority > borderPrio)) { styleValues.border = tagPtr->border; borderPrio = tagPtr->priority; } if ((tagPtr->bdString != NULL) && (tagPtr->priority > borderWidthPrio)) { styleValues.borderWidth = tagPtr->borderWidth; borderWidthPrio = tagPtr->priority; } if ((tagPtr->reliefString != NULL) && (tagPtr->priority > reliefPrio)) { if (styleValues.border == NULL) { styleValues.border = textPtr->border; } styleValues.relief = tagPtr->relief; reliefPrio = tagPtr->priority; } if ((tagPtr->bgStipple != None) && (tagPtr->priority > bgStipplePrio)) { styleValues.bgStipple = tagPtr->bgStipple; bgStipplePrio = tagPtr->priority; } if ((tagPtr->fgColor != None) && (tagPtr->priority > fgPrio)) { styleValues.fgColor = tagPtr->fgColor; fgPrio = tagPtr->priority; } if ((tagPtr->tkfont != None) && (tagPtr->priority > fontPrio)) { styleValues.tkfont = tagPtr->tkfont; fontPrio = tagPtr->priority; } if ((tagPtr->fgStipple != None) && (tagPtr->priority > fgStipplePrio)) { styleValues.fgStipple = tagPtr->fgStipple; fgStipplePrio = tagPtr->priority; } if ((tagPtr->justifyString != NULL) && (tagPtr->priority > justifyPrio)) { styleValues.justify = tagPtr->justify; justifyPrio = tagPtr->priority; } if ((tagPtr->lMargin1String != NULL) && (tagPtr->priority > lMargin1Prio)) { styleValues.lMargin1 = tagPtr->lMargin1; lMargin1Prio = tagPtr->priority; } if ((tagPtr->lMargin2String != NULL) && (tagPtr->priority > lMargin2Prio)) { styleValues.lMargin2 = tagPtr->lMargin2; lMargin2Prio = tagPtr->priority; } if ((tagPtr->offsetString != NULL) && (tagPtr->priority > offsetPrio)) { styleValues.offset = tagPtr->offset; offsetPrio = tagPtr->priority; } if ((tagPtr->overstrikeString != NULL) && (tagPtr->priority > overstrikePrio)) { styleValues.overstrike = tagPtr->overstrike; overstrikePrio = tagPtr->priority; } if ((tagPtr->rMarginString != NULL) && (tagPtr->priority > rMarginPrio)) { styleValues.rMargin = tagPtr->rMargin; rMarginPrio = tagPtr->priority; } if ((tagPtr->spacing1String != NULL) && (tagPtr->priority > spacing1Prio)) { styleValues.spacing1 = tagPtr->spacing1; spacing1Prio = tagPtr->priority; } if ((tagPtr->spacing2String != NULL) && (tagPtr->priority > spacing2Prio)) { styleValues.spacing2 = tagPtr->spacing2; spacing2Prio = tagPtr->priority; } if ((tagPtr->spacing3String != NULL) && (tagPtr->priority > spacing3Prio)) { styleValues.spacing3 = tagPtr->spacing3; spacing3Prio = tagPtr->priority; } if ((tagPtr->tabString != NULL) && (tagPtr->priority > tabPrio)) { styleValues.tabArrayPtr = tagPtr->tabArrayPtr; tabPrio = tagPtr->priority; } if ((tagPtr->underlineString != NULL) && (tagPtr->priority > underlinePrio)) { styleValues.underline = tagPtr->underline; underlinePrio = tagPtr->priority; } if ((tagPtr->wrapMode != NULL) && (tagPtr->priority > wrapPrio)) { styleValues.wrapMode = tagPtr->wrapMode; wrapPrio = tagPtr->priority; } } if (tagPtrs != NULL) { ckfree((char *) tagPtrs); } /* * Use an existing style if there's one around that matches. */ hPtr = Tcl_CreateHashEntry(&textPtr->dInfoPtr->styleTable, (char *) &styleValues, &new); if (!new) { stylePtr = (TextStyle *) Tcl_GetHashValue(hPtr); stylePtr->refCount++; return stylePtr; } /* * No existing style matched. Make a new one. */ stylePtr = (TextStyle *) ckalloc(sizeof(TextStyle)); stylePtr->refCount = 1; if (styleValues.border != NULL) { gcValues.foreground = Tk_3DBorderColor(styleValues.border)->pixel; mask = GCForeground; if (styleValues.bgStipple != None) { gcValues.stipple = styleValues.bgStipple; gcValues.fill_style = FillStippled; mask |= GCStipple|GCFillStyle; } stylePtr->bgGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues); } else { stylePtr->bgGC = None; } mask = GCForeground|GCFont; gcValues.foreground = styleValues.fgColor->pixel; gcValues.font = Tk_FontId(styleValues.tkfont); if (styleValues.fgStipple != None) { gcValues.stipple = styleValues.fgStipple; gcValues.fill_style = FillStippled; mask |= GCStipple|GCFillStyle; } stylePtr->fgGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues); stylePtr->sValuePtr = (StyleValues *) Tcl_GetHashKey(&textPtr->dInfoPtr->styleTable, hPtr); stylePtr->hPtr = hPtr; Tcl_SetHashValue(hPtr, stylePtr); return stylePtr;}/* *---------------------------------------------------------------------- * * FreeStyle -- * * This procedure is called when a TextStyle structure is no longer * needed. It decrements the reference count and frees up the * space for the style structure if the reference count is 0. * * Results: * None. * * Side effects: * The storage and other resources associated with the style * are freed up if no-one's still using it. * *---------------------------------------------------------------------- */static voidFreeStyle(textPtr, stylePtr) TkText *textPtr; /* Information about overall widget. */ register TextStyle *stylePtr; /* Information about style to free. */{ stylePtr->refCount--; if (stylePtr->refCount == 0) { if (stylePtr->bgGC != None) { Tk_FreeGC(textPtr->display, stylePtr->bgGC); } Tk_FreeGC(textPtr->display, stylePtr->fgGC); Tcl_DeleteHashEntry(stylePtr->hPtr); ckfree((char *) stylePtr); }}/* *---------------------------------------------------------------------- * * LayoutDLine -- * * This procedure generates a single DLine structure for a display * line whose leftmost character is given by indexPtr. * * Results: * The return value is a pointer to a DLine structure desribing the * display line. All fields are filled in and correct except for * y and nextPtr. * * Side effects: * Storage is allocated for the new DLine. * *---------------------------------------------------------------------- */static DLine *LayoutDLine(textPtr, indexPtr) TkText *textPtr; /* Overall information about text widget. */ TkTextIndex *indexPtr; /* Beginning of display line. May not * necessarily point to a character segment. */{ register DLine *dlPtr; /* New display line. */ TkTextSegment *segPtr; /* Current segment in text. */ TkTextDispChunk *lastChunkPtr; /* Last chunk allocated so far * for line. */ TkTextDispChunk *chunkPtr; /* Current chunk. */ TkTextIndex curIndex; TkTextDispChunk *breakChunkPtr; /* Chunk containing best word break * point, if any. */ TkTextIndex breakIndex; /* Index of first character in * breakChunkPtr. */ int breakCharOffset; /* Character within breakChunkPtr just * to right of best break point. */ int noCharsYet; /* Non-zero means that no characters * have been placed on the line yet. */ int justify; /* How to justify line: taken from * style for first character in line. */ int jIndent; /* Additional indentation (beyond * margins) due to justification. */ int rMargin; /* Right margin width for line. */ Tk_Uid wrapMode; /* Wrap mode to use for this line. */ int x = 0, maxX = 0; /* Initializations needed only to * stop compiler warnings. */ int wholeLine; /* Non-zero means this display line * runs to the end of the text line. */ int tabIndex; /* Index of the current tab stop. */ int gotTab; /* Non-zero means the current chunk * contains a tab. */ TkTextDispChunk *tabChunkPtr; /* Pointer to the chunk containing * the previous tab stop. */ int maxChars; /* Maximum number of characters to * include in this chunk. */ TkTextTabArray *tabArrayPtr; /* Tab stops for line; taken from * style for first character on line. */ int tabSize; /* Number of pixels consumed by current * tab stop. */ TkTextDispChunk *lastCharChunkPtr; /* Pointer to last chunk in display * lines with numChars > 0. Used to * drop 0-sized chunks from the end * of the line. */ int offset, ascent, descent, code; StyleValues *sValuePtr; /* * Create and initialize a new DLine structure. */ dlPtr = (DLine *) ckalloc(sizeof(DLine)); dlPtr->index = *indexPtr; dlPtr->count = 0; dlPtr->y = 0; dlPtr->oldY = -1; dlPtr->height = 0; dlPtr->baseline = 0; dlPtr->chunkPtr = NULL; dlPtr->nextPtr = NULL; dlPtr->flags = NEW_LAYOUT; /* * Each iteration of the loop below creates one TkTextDispChunk for * the new display line. The line will always have at least one * chunk (for the newline character at the end, if there's nothing * else available). */ curIndex = *indexPtr; lastChunkPtr = NULL; chunkPtr = NULL; noCharsYet = 1; breakChunkPtr = NULL; breakCharOffset = 0; justify = TK_JUSTIFY_LEFT; tabIndex = -1; tabChunkPtr = NULL; tabArrayPtr = NULL; rMargin = 0; wrapMode = tkTextCharUid; tabSize = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -