📄 textdisp.c
字号:
static const char CVSID[] = "$Id: textDisp.c,v 1.53.2.1 2003/08/01 01:26:42 n8gray Exp $";/******************************************************************************** ** textDisp.c - Display text from a text buffer ** ** Copyright (C) 1999 Mark Edel ** ** This is free software; you can redistribute it and/or modify it under the ** terms of the GNU General Public License as published by the Free Software ** Foundation; either version 2 of the License, or (at your option) any later ** version. ** ** This software is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ** for more details. ** ** You should have received a copy of the GNU General Public License along with ** software; if not, write to the Free Software Foundation, Inc., 59 Temple ** Place, Suite 330, Boston, MA 02111-1307 USA ** ** Nirvana Text Editor ** June 15, 1995 ** ** Written by Mark Edel ** ********************************************************************************/#ifdef HAVE_CONFIG_H#include "../config.h"#endif#include "textDisp.h"#include "textBuf.h"#include "text.h"#include "textP.h"#include "nedit.h"#include "calltips.h"#include "highlight.h"#include "rangeset.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>#ifdef VMS#include "../util/VMSparam.h"#else#ifndef __MVS__#include <sys/param.h>#endif#endif /*VMS*/#include <Xm/Xm.h>#include <Xm/ScrolledW.h>#include <Xm/ScrollBar.h>#include <Xm/Label.h>#include <X11/Shell.h>#ifdef HAVE_DEBUG_H#include "../debug.h"#endif#define TOP_MARGIN 1#define BOTTOM_MARGIN 1#define LEFT_MARGIN 3#define RIGHT_MARGIN 3/* Masks for text drawing methods. These are or'd together to form an integer which describes what drawing calls to use to draw a string */#define FILL_SHIFT 8#define SECONDARY_SHIFT 9#define PRIMARY_SHIFT 10#define HIGHLIGHT_SHIFT 11#define STYLE_LOOKUP_SHIFT 0#define BACKLIGHT_SHIFT 12#define FILL_MASK (1 << FILL_SHIFT)#define SECONDARY_MASK (1 << SECONDARY_SHIFT)#define PRIMARY_MASK (1 << PRIMARY_SHIFT)#define HIGHLIGHT_MASK (1 << HIGHLIGHT_SHIFT)#define STYLE_LOOKUP_MASK (0xff << STYLE_LOOKUP_SHIFT)#define BACKLIGHT_MASK (0xff << BACKLIGHT_SHIFT)#define RANGESET_SHIFT (20)#define RANGESET_MASK (0x3F << RANGESET_SHIFT)/* If you use both 32-Bit Style mask layout: Bits +----------------+----------------+----------------+----------------+ hex |1F1E1D1C1B1A1918|1716151413121110| F E D C B A 9 8| 7 6 5 4 3 2 1 0| dec |3130292827262524|2322212019181716|151413121110 9 8| 7 6 5 4 3 2 1 0| +----------------+----------------+----------------+----------------+ Type | r r| r r r r b b b b| b b b b H 1 2 F| s s s s s s s s| +----------------+----------------+----------------+----------------+ where: s - style lookup value (8 bits) F - fill (1 bit) 2 - secondary selection (1 bit) 1 - primary selection (1 bit) H - highlight (1 bit) b - backlighting index (8 bits) r - rangeset index (6 bits) This leaves 6 "unused" bits *//* Maximum displayable line length (how many characters will fit across the widest window). This amount of memory is temporarily allocated from the stack in the redisplayLine routine for drawing strings */#define MAX_DISP_LINE_LEN 1000/* Macro for getting the TextPart from a textD */#define TEXT_OF_TEXTD(t) (((TextWidget)((t)->w))->text)enum positionTypes {CURSOR_POS, CHARACTER_POS};static void updateLineStarts(textDisp *textD, int pos, int charsInserted, int charsDeleted, int linesInserted, int linesDeleted, int *scrolled);static void offsetLineStarts(textDisp *textD, int newTopLineNum);static void calcLineStarts(textDisp *textD, int startLine, int endLine);static void calcLastChar(textDisp *textD);static int posToVisibleLineNum(textDisp *textD, int pos, int *lineNum);static void redisplayLine(textDisp *textD, int visLineNum, int leftClip, int rightClip, int leftCharIndex, int rightCharIndex);static void drawString(textDisp *textD, int style, int x, int y, int toX, char *string, int nChars);static void clearRect(textDisp *textD, GC gc, int x, int y, int width, int height);static void drawCursor(textDisp *textD, int x, int y);static int styleOfPos(textDisp *textD, int lineStartPos, int lineLen, int lineIndex, int dispIndex, int thisChar);static int stringWidth(textDisp *textD, char *string, int length, int style);static int inSelection(selection *sel, int pos, int lineStartPos, int dispIndex);static int xyToPos(textDisp *textD, int x, int y, int posType);static void xyToUnconstrainedPos(textDisp *textD, int x, int y, int *row, int *column, int posType);static void bufPreDeleteCB(int pos, int nDeleted, void *cbArg);static void bufModifiedCB(int pos, int nInserted, int nDeleted, int nRestyled, char *deletedText, void *cbArg);static void setScroll(textDisp *textD, int topLineNum, int horizOffset, int updateVScrollBar, int updateHScrollBar);static void hScrollCB(Widget w, XtPointer clientData, XtPointer callData);static void vScrollCB(Widget w, XtPointer clientData, XtPointer callData);static void visibilityEH(Widget w, XtPointer data, XEvent *event, Boolean *continueDispatch);static void redrawLineNumbers(textDisp *textD, int clearAll);static void updateVScrollBarRange(textDisp *textD);static int updateHScrollBarRange(textDisp *textD);static int max(int i1, int i2);static int min(int i1, int i2);static int countLines(char *string);static int measureVisLine(textDisp *textD, int visLineNum);static int emptyLinesVisible(textDisp *textD);static void blankCursorProtrusions(textDisp *textD);static void allocateFixedFontGCs(textDisp *textD, XFontStruct *fontStruct, Pixel bgPixel, Pixel fgPixel, Pixel selectFGPixel, Pixel selectBGPixel, Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel);static GC allocateGC(Widget w, unsigned long valueMask, unsigned long foreground, unsigned long background, Font font, unsigned long dynamicMask, unsigned long dontCareMask);static void releaseGC(Widget w, GC gc);static void resetClipRectangles(textDisp *textD);static int visLineLength(textDisp *textD, int visLineNum);static void measureDeletedLines(textDisp *textD, int pos, int nDeleted);static void findWrapRange(textDisp *textD, char *deletedText, int pos, int nInserted, int nDeleted, int *modRangeStart, int *modRangeEnd, int *linesInserted, int *linesDeleted);static void wrappedLineCounter(textDisp *textD, textBuffer *buf, int startPos, int maxPos, int maxLines, int startPosIsLineStart, int styleBufOffset, int *retPos, int *retLines, int *retLineStart, int *retLineEnd);static void findLineEnd(textDisp *textD, int startPos, int startPosIsLineStart, int *lineEnd, int *nextLineStart);static int wrapUsesCharacter(textDisp *textD, int lineEndPos);static void hideOrShowHScrollBar(textDisp *textD);static int rangeTouchesRectSel(selection *sel, int rangeStart, int rangeEnd);static void extendRangeForStyleMods(textDisp *textD, int *start, int *end);static int getAbsTopLineNum(textDisp *textD);static void offsetAbsLineNum(textDisp *textD, int oldFirstChar);static int maintainingAbsTopLineNum(textDisp *textD);static void resetAbsLineNum(textDisp *textD);static int measurePropChar(textDisp *textD, char c, int colNum, int pos);static Pixel allocBGColor(Widget w, char *colorName, int *ok);Pixel getRangesetColor(textDisp *textD, int ind, Pixel bground);textDisp *TextDCreate(Widget widget, Widget hScrollBar, Widget vScrollBar, Position left, Position top, Position width, Position height, Position lineNumLeft, Position lineNumWidth, textBuffer *buffer, XFontStruct *fontStruct, Pixel bgPixel, Pixel fgPixel, Pixel selectFGPixel, Pixel selectBGPixel, Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel cursorFGPixel, Pixel lineNumFGPixel, int continuousWrap, int wrapMargin, XmString bgClassString, Pixel calltipFGPixel, Pixel calltipBGPixel){ textDisp *textD; XGCValues gcValues; int i; textD = (textDisp *)XtMalloc(sizeof(textDisp)); textD->w = widget; textD->top = top; textD->left = left; textD->width = width; textD->height = height; textD->cursorOn = True; textD->cursorPos = 0; textD->cursorX = -100; textD->cursorY = -100; textD->cursorToHint = NO_HINT; textD->cursorStyle = NORMAL_CURSOR; textD->cursorPreferredCol = -1; textD->buffer = buffer; textD->firstChar = 0; textD->lastChar = 0; textD->nBufferLines = 0; textD->topLineNum = 1; textD->absTopLineNum = 1; textD->needAbsTopLineNum = False; textD->horizOffset = 0; textD->visibility = VisibilityUnobscured; textD->hScrollBar = hScrollBar; textD->vScrollBar = vScrollBar; textD->fontStruct = fontStruct; textD->ascent = fontStruct->ascent; textD->descent = fontStruct->descent; textD->fixedFontWidth = fontStruct->min_bounds.width == fontStruct->max_bounds.width ? fontStruct->min_bounds.width : -1; textD->styleBuffer = NULL; textD->styleTable = NULL; textD->nStyles = 0; textD->bgPixel = bgPixel; textD->fgPixel = fgPixel; textD->selectFGPixel = selectFGPixel; textD->highlightFGPixel = highlightFGPixel; textD->selectBGPixel = selectBGPixel; textD->highlightBGPixel = highlightBGPixel; textD->lineNumFGPixel = lineNumFGPixel; textD->cursorFGPixel = cursorFGPixel; textD->wrapMargin = wrapMargin; textD->continuousWrap = continuousWrap; allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel, selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel); textD->styleGC = allocateGC(textD->w, 0, 0, 0, fontStruct->fid, GCClipMask|GCForeground|GCBackground, GCArcMode); textD->lineNumLeft = lineNumLeft; textD->lineNumWidth = lineNumWidth; textD->nVisibleLines = (height - 1) / (textD->ascent + textD->descent) + 1; gcValues.foreground = cursorFGPixel; textD->cursorFGGC = XtGetGC(widget, GCForeground, &gcValues); textD->lineStarts = (int *)XtMalloc(sizeof(int) * textD->nVisibleLines); textD->lineStarts[0] = 0; textD->calltipW = NULL; textD->calltipShell = NULL; textD->calltip.ID = 0; textD->calltipFGPixel = calltipFGPixel; textD->calltipBGPixel = calltipBGPixel; for (i=1; i<textD->nVisibleLines; i++) textD->lineStarts[i] = -1; textD->bgClassPixel = NULL; textD->bgClass = NULL; TextDSetupBGClasses(widget, bgClassString, &textD->bgClassPixel, &textD->bgClass, bgPixel); textD->suppressResync = 0; textD->nLinesDeleted = 0; textD->modifyingTabDist = 0; textD->pointerHidden = False; textD->graphicsExposeQueue = NULL; /* Attach an event handler to the widget so we can know the visibility (used for choosing the fastest drawing method) */ XtAddEventHandler(widget, VisibilityChangeMask, False, visibilityEH, textD); /* Attach the callback to the text buffer for receiving modification information */ if (buffer != NULL) { BufAddModifyCB(buffer, bufModifiedCB, textD); BufAddPreDeleteCB(buffer, bufPreDeleteCB, textD); } /* Initialize the scroll bars and attach movement callbacks */ if (vScrollBar != NULL) { XtVaSetValues(vScrollBar, XmNminimum, 1, XmNmaximum, 2, XmNsliderSize, 1, XmNrepeatDelay, 10, XmNvalue, 1, NULL); XtAddCallback(vScrollBar, XmNdragCallback, vScrollCB, (XtPointer)textD); XtAddCallback(vScrollBar, XmNvalueChangedCallback, vScrollCB, (XtPointer)textD); } if (hScrollBar != NULL) { XtVaSetValues(hScrollBar, XmNminimum, 0, XmNmaximum, 1, XmNsliderSize, 1, XmNrepeatDelay, 10, XmNvalue, 0, XmNincrement, fontStruct->max_bounds.width, NULL); XtAddCallback(hScrollBar, XmNdragCallback, hScrollCB, (XtPointer)textD); XtAddCallback(hScrollBar, XmNvalueChangedCallback, hScrollCB, (XtPointer)textD); } /* Update the display to reflect the contents of the buffer */ if (buffer != NULL) bufModifiedCB(0, buffer->length, 0, 0, NULL, textD); /* Decide if the horizontal scroll bar needs to be visible */ hideOrShowHScrollBar(textD); return textD;}/*** Free a text display and release its associated memory. Note, the text** BUFFER that the text display displays is a separate entity and is not** freed, nor are the style buffer or style table.*/void TextDFree(textDisp *textD){ BufRemoveModifyCB(textD->buffer, bufModifiedCB, textD); BufRemovePreDeleteCB(textD->buffer, bufPreDeleteCB, textD); 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->styleGC); releaseGC(textD->w, textD->lineNumGC); XtFree((char *)textD->lineStarts); while (TextDPopGraphicExposeQueueEntry(textD)) { } XtFree((char *)textD->bgClassPixel); XtFree((char *)textD->bgClass); XtFree((char *)textD);}/*** Attach a text buffer to display, replacing the current buffer (if any)*/void TextDSetBuffer(textDisp *textD, textBuffer *buffer){ /* If the text display is already displaying a buffer, clear it off of the display and remove our callback from it */ if (textD->buffer != NULL) { bufModifiedCB(0, 0, textD->buffer->length, 0, NULL, textD); BufRemoveModifyCB(textD->buffer, bufModifiedCB, textD); BufRemovePreDeleteCB(textD->buffer, bufPreDeleteCB, textD); } /* Add the buffer to the display, and attach a callback to the buffer for receiving modification information when the buffer contents change */ textD->buffer = buffer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -