📄 textdisp.c
字号:
BufAddModifyCB(buffer, bufModifiedCB, textD); BufAddPreDeleteCB(buffer, bufPreDeleteCB, textD); /* Update the display */ bufModifiedCB(0, buffer->length, 0, 0, NULL, textD);}/*** return the displayed text buffer*/textBuffer *TextDGetBuffer(textDisp *textD){ return textD->buffer;}/*** Attach (or remove) highlight information in text display and redisplay.** Highlighting information consists of a style buffer which parallels the** normal text buffer, but codes font and color information for the display;** a style table which translates style buffer codes (indexed by buffer** character - 65 (ASCII code for 'A')) into fonts and colors; and a callback ** mechanism for as-needed highlighting, triggered by a style buffer entry of** "unfinishedStyle". Style buffer can trigger additional redisplay during** a normal buffer modification if the buffer contains a primary selection** (see extendRangeForStyleMods for more information on this protocol).**** Style buffers, tables and their associated memory are managed by the caller.*/void TextDAttachHighlightData(textDisp *textD, textBuffer *styleBuffer, styleTableEntry *styleTable, int nStyles, char unfinishedStyle, unfinishedStyleCBProc unfinishedHighlightCB, void *cbArg){ textD->styleBuffer = styleBuffer; textD->styleTable = styleTable; textD->nStyles = nStyles; textD->unfinishedStyle = unfinishedStyle; textD->unfinishedHighlightCB = unfinishedHighlightCB; textD->highlightCBArg = cbArg; /* Call TextDSetFont to combine font information from style table and primary font, adjust font-related parameters, and then redisplay */ TextDSetFont(textD, textD->fontStruct);}/* Change the (non syntax-highlit) colors */ void TextDSetColors(textDisp *textD, Pixel textFgP, Pixel textBgP, Pixel selectFgP, Pixel selectBgP, Pixel hiliteFgP, Pixel hiliteBgP, Pixel lineNoFgP, Pixel cursorFgP){ XGCValues values; Display *d = XtDisplay(textD->w); /* Update the stored pixels */ textD->fgPixel = textFgP; textD->bgPixel = textBgP; textD->selectFGPixel = selectFgP; textD->selectBGPixel = selectBgP; textD->highlightFGPixel = hiliteFgP; textD->highlightBGPixel = hiliteBgP; textD->lineNumFGPixel = lineNoFgP; textD->cursorFGPixel = cursorFgP; releaseGC(textD->w, textD->gc); releaseGC(textD->w, textD->selectGC); releaseGC(textD->w, textD->selectBGGC); releaseGC(textD->w, textD->highlightGC); releaseGC(textD->w, textD->highlightBGGC); releaseGC(textD->w, textD->lineNumGC); allocateFixedFontGCs(textD, textD->fontStruct, textBgP, textFgP, selectFgP, selectBgP, hiliteFgP, hiliteBgP, lineNoFgP); /* Change the cursor GC (the cursor GC is not shared). */ values.foreground = cursorFgP; XChangeGC( d, textD->cursorFGGC, GCForeground, &values ); /* Redisplay */ TextDRedisplayRect(textD, textD->left, textD->top, textD->width, textD->height); redrawLineNumbers(textD, True);}/*** Change the (non highlight) font*/void TextDSetFont(textDisp *textD, XFontStruct *fontStruct){ Display *display = XtDisplay(textD->w); int i, maxAscent = fontStruct->ascent, maxDescent = fontStruct->descent; int width, height, fontWidth; Pixel bgPixel, fgPixel, selectFGPixel, selectBGPixel; Pixel highlightFGPixel, highlightBGPixel, lineNumFGPixel; XGCValues values; XFontStruct *styleFont; /* If font size changes, cursor will be redrawn in a new position */ blankCursorProtrusions(textD); /* If there is a (syntax highlighting) style table in use, find the new maximum font height for this text display */ for (i=0; i<textD->nStyles; i++) { styleFont = textD->styleTable[i].font; if (styleFont != NULL && styleFont->ascent > maxAscent) maxAscent = styleFont->ascent; if (styleFont != NULL && styleFont->descent > maxDescent) maxDescent = styleFont->descent; } textD->ascent = maxAscent; textD->descent = maxDescent; /* If all of the current fonts are fixed and match in width, compute */ fontWidth = fontStruct->max_bounds.width; if (fontWidth != fontStruct->min_bounds.width) fontWidth = -1; else { for (i=0; i<textD->nStyles; i++) { styleFont = textD->styleTable[i].font; if (styleFont != NULL && (styleFont->max_bounds.width != fontWidth || styleFont->max_bounds.width != styleFont->min_bounds.width)) fontWidth = -1; } } textD->fixedFontWidth = fontWidth; /* Don't let the height dip below one line, or bad things can happen */ if (textD->height < maxAscent + maxDescent) textD->height = maxAscent + maxDescent; /* Change the font. In most cases, this means re-allocating the affected GCs (they are shared with other widgets, and if the primary font changes, must be re-allocated to change it). Unfortunately, this requres recovering all of the colors from the existing GCs */ textD->fontStruct = fontStruct; XGetGCValues(display, textD->gc, GCForeground|GCBackground, &values); fgPixel = values.foreground; bgPixel = values.background; XGetGCValues(display, textD->selectGC, GCForeground|GCBackground, &values); selectFGPixel = values.foreground; selectBGPixel = values.background; XGetGCValues(display, textD->highlightGC,GCForeground|GCBackground,&values); highlightFGPixel = values.foreground; highlightBGPixel = values.background; XGetGCValues(display, textD->lineNumGC, GCForeground, &values); lineNumFGPixel = values.foreground; releaseGC(textD->w, textD->gc); releaseGC(textD->w, textD->selectGC); releaseGC(textD->w, textD->highlightGC); releaseGC(textD->w, textD->selectBGGC); releaseGC(textD->w, textD->highlightBGGC); releaseGC(textD->w, textD->lineNumGC); allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel, selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel); XSetFont(display, textD->styleGC, fontStruct->fid); /* Do a full resize to force recalculation of font related parameters */ width = textD->width; height = textD->height; textD->width = textD->height = 0; TextDResize(textD, width, height); /* Redisplay */ TextDRedisplayRect(textD, textD->left, textD->top, textD->width, textD->height); /* Clean up line number area in case spacing has changed */ redrawLineNumbers(textD, True);}int TextDMinFontWidth(textDisp *textD, Boolean considerStyles){ int fontWidth = textD->fontStruct->max_bounds.width; int i; if (considerStyles) { for (i = 0; i < textD->nStyles; ++i) { int thisWidth = (textD->styleTable[i].font)->min_bounds.width; if (thisWidth < fontWidth) { fontWidth = thisWidth; } } } return(fontWidth);}int TextDMaxFontWidth(textDisp *textD, Boolean considerStyles){ int fontWidth = textD->fontStruct->max_bounds.width; int i; if (considerStyles) { for (i = 0; i < textD->nStyles; ++i) { int thisWidth = (textD->styleTable[i].font)->max_bounds.width; if (thisWidth > fontWidth) { fontWidth = thisWidth; } } } return(fontWidth);}/*** Change the size of the displayed text area*/void TextDResize(textDisp *textD, int width, int height){ int oldVisibleLines = textD->nVisibleLines; int canRedraw = XtWindow(textD->w) != 0; int newVisibleLines = height / (textD->ascent + textD->descent); int redrawAll = False; int oldWidth = textD->width; int exactHeight = height - height % (textD->ascent + textD->descent); textD->width = width; textD->height = height; /* In continuous wrap mode, a change in width affects the total number of lines in the buffer, and can leave the top line number incorrect, and the top character no longer pointing at a valid line start */ if (textD->continuousWrap && textD->wrapMargin==0 && width!=oldWidth) { int oldFirstChar = textD->firstChar; textD->nBufferLines = TextDCountLines(textD, 0, textD->buffer->length, True); textD->firstChar = TextDStartOfLine(textD, textD->firstChar); textD->topLineNum = TextDCountLines(textD, 0, textD->firstChar, True)+1; redrawAll = True; offsetAbsLineNum(textD, oldFirstChar); } /* reallocate and update the line starts array, which may have changed size and/or contents. (contents can change in continuous wrap mode when the width changes, even without a change in height) */ if (oldVisibleLines < newVisibleLines) { XtFree((char *)textD->lineStarts); textD->lineStarts = (int *)XtMalloc(sizeof(int) * newVisibleLines); } textD->nVisibleLines = newVisibleLines; calcLineStarts(textD, 0, newVisibleLines); calcLastChar(textD); /* if the window became shorter, there may be partially drawn text left at the bottom edge, which must be cleaned up */ if (canRedraw && oldVisibleLines>newVisibleLines && exactHeight!=height) XClearArea(XtDisplay(textD->w), XtWindow(textD->w), textD->left, textD->top + exactHeight, textD->width, height - exactHeight, False); /* if the window became taller, there may be an opportunity to display more text by scrolling down */ if (canRedraw && oldVisibleLines < newVisibleLines && textD->topLineNum + textD->nVisibleLines > textD->nBufferLines) setScroll(textD, max(1, textD->nBufferLines - textD->nVisibleLines + 2 + TEXT_OF_TEXTD(textD).cursorVPadding), textD->horizOffset, False, False); /* Update the scroll bar page increment size (as well as other scroll bar parameters. If updating the horizontal range caused scrolling, redraw */ updateVScrollBarRange(textD); if (updateHScrollBarRange(textD)) redrawAll = True; /* If a full redraw is needed */ if (redrawAll && canRedraw) TextDRedisplayRect(textD, textD->left, textD->top, textD->width, textD->height); /* Decide if the horizontal scroll bar needs to be visible */ hideOrShowHScrollBar(textD); /* Refresh the line number display to draw more line numbers, or erase extras */ redrawLineNumbers(textD, True); /* Redraw the calltip */ TextDRedrawCalltip(textD, 0);}/*** Refresh a rectangle of the text display. left and top are in coordinates of** the text drawing window*/void TextDRedisplayRect(textDisp *textD, int left, int top, int width, int height){ int fontHeight, firstLine, lastLine, line; /* find the line number range of the display */ fontHeight = textD->ascent + textD->descent; firstLine = (top - textD->top - fontHeight + 1) / fontHeight; lastLine = (top + height - textD->top) / fontHeight; /* If the graphics contexts are shared using XtAllocateGC, their clipping rectangles may have changed since the last use */ resetClipRectangles(textD); /* draw the lines of text */ for (line=firstLine; line<=lastLine; line++) redisplayLine(textD, line, left, left+width, 0, INT_MAX); /* draw the line numbers if exposed area includes them */ if (textD->lineNumWidth != 0 && left <= textD->lineNumLeft + textD->lineNumWidth) redrawLineNumbers(textD, False);}/*** Refresh all of the text between buffer positions "start" and "end"** not including the character at the position "end".** If end points beyond the end of the buffer, refresh the whole display** after pos, including blank lines which are not technically part of** any range of characters.*/void TextDRedisplayRange(textDisp *textD, int start, int end){ int i, startLine, lastLine, startIndex, endIndex; /* If the range is outside of the displayed text, just return */ if (end < textD->firstChar || (start > textD->lastChar && !emptyLinesVisible(textD))) return; /* Clean up the starting and ending values */ if (start < 0) start = 0; if (start > textD->buffer->length) start = textD->buffer->length; if (end < 0) end = 0; if (end > textD->buffer->length) end = textD->buffer->length; /* Get the starting and ending lines */ if (start < textD->firstChar) start = textD->firstChar; if (!posToVisibleLineNum(textD, start, &startLine)) startLine = textD->nVisibleLines - 1; if (end >= textD->lastChar) { lastLine = textD->nVisibleLines - 1; } else { if (!posToVisibleLineNum(textD, end, &lastLine)) { /* shouldn't happen */ lastLine = textD->nVisibleLines - 1; } } /* Get the starting and ending positions within the lines */ startIndex = textD->lineStarts[startLine] == -1 ? 0 : start - textD->lineStarts[startLine];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -