⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textdisp.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* use the common line counting routine to count forward */    wrappedLineCounter(textD, textD->buffer, startPos, textD->buffer->length,    	    nLines, startPosIsLineStart, 0, &retPos, &retLines, &retLineStart,    	    &retLineEnd);    return retPos;}/*** Same as BufEndOfLine, but takes in to account line breaks when wrapping** is turned on.  If the caller knows that startPos is at a line start, it** can pass "startPosIsLineStart" as True to make the call more efficient** by avoiding the additional step of scanning back to the last newline.**** Note that the definition of the end of a line is less clear when continuous** wrap is on.  With continuous wrap off, it's just a pointer to the newline** that ends the line.  When it's on, it's the character beyond the last** DISPLAYABLE character on the line, where a whitespace character which has** been "converted" to a newline for wrapping is not considered displayable.** Also note that, a line can be wrapped at a non-whitespace character if the** line had no whitespace.  In this case, this routine returns a pointer to** the start of the next line.  This is also consistent with the model used by** visLineLength.*/int TextDEndOfLine(textDisp *textD, int pos, int startPosIsLineStart){    int retLines, retPos, retLineStart, retLineEnd;        /* If we're not wrapping use more efficien BufEndOfLine */    if (!textD->continuousWrap)    	return BufEndOfLine(textD->buffer, pos);        if (pos == textD->buffer->length)    	return pos;    wrappedLineCounter(textD, textD->buffer, pos, textD->buffer->length, 1,    	    startPosIsLineStart, 0, &retPos, &retLines, &retLineStart,	    &retLineEnd);    return retLineEnd;}/*** Same as BufStartOfLine, but returns the character after last wrap point** rather than the last newline.*/int TextDStartOfLine(textDisp *textD, int pos){    int retLines, retPos, retLineStart, retLineEnd;        /* If we're not wrapping, use the more efficient BufStartOfLine */    if (!textD->continuousWrap)    	return BufStartOfLine(textD->buffer, pos);    wrappedLineCounter(textD, textD->buffer, BufStartOfLine(textD->buffer, pos),    	    pos, INT_MAX, True, 0, &retPos, &retLines, &retLineStart, 	    &retLineEnd);    return retLineStart;}/*** Same as BufCountBackwardNLines, but takes in to account line breaks when** wrapping is turned on.*/int TextDCountBackwardNLines(textDisp *textD, int startPos, int nLines){    textBuffer *buf = textD->buffer;    int pos, lineStart, retLines, retPos, retLineStart, retLineEnd;        /* If we're not wrapping, use the more efficient BufCountBackwardNLines */    if (!textD->continuousWrap)    	return BufCountBackwardNLines(textD->buffer, startPos, nLines);    pos = startPos;    while (True) {	lineStart = BufStartOfLine(buf, pos);	wrappedLineCounter(textD, textD->buffer, lineStart, pos, INT_MAX,	    	True, 0, &retPos, &retLines, &retLineStart, &retLineEnd);	if (retLines > nLines)    	    return TextDCountForwardNLines(textD, lineStart, retLines-nLines,    	    	    True);    	nLines -= retLines;    	pos = lineStart - 1;    	if (pos < 0)    	    return 0;    	nLines -= 1;    }}/*** Callback attached to the text buffer to receive delete information before** the modifications are actually made.*/static void bufPreDeleteCB(int pos, int nDeleted, void *cbArg){    textDisp *textD = (textDisp *)cbArg;    if (textD->continuousWrap &&         (textD->fixedFontWidth == -1 || textD->modifyingTabDist))	/* Note: we must perform this measurement, even if there is not a	   single character deleted; the number of "deleted" lines is the	   number of visual lines spanned by the real line in which the 	   modification takes place. 	   Also, a modification of the tab distance requires the same	   kind of calculations in advance, even if the font width is "fixed",	   because when the width of the tab characters changes, the layout 	   of the text may be completely different. */	measureDeletedLines(textD, pos, nDeleted);    else	textD->suppressResync = 0; /* Probably not needed, but just in case */}/*** Callback attached to the text buffer to receive modification information*/static void bufModifiedCB(int pos, int nInserted, int nDeleted,	int nRestyled, char *deletedText, void *cbArg){    int linesInserted, linesDeleted, startDispPos, endDispPos;    textDisp *textD = (textDisp *)cbArg;    textBuffer *buf = textD->buffer;    int oldFirstChar = textD->firstChar;    int scrolled, origCursorPos = textD->cursorPos;    int wrapModStart, wrapModEnd;     /* buffer modification cancels vertical cursor motion column */    if (nInserted != 0 || nDeleted != 0)    	textD->cursorPreferredCol = -1;        /* Count the number of lines inserted and deleted, and in the case       of continuous wrap mode, how much has changed */    if (textD->continuousWrap) {    	findWrapRange(textD, deletedText, pos, nInserted, nDeleted,    	    	&wrapModStart, &wrapModEnd, &linesInserted, &linesDeleted);    } else {	linesInserted = nInserted == 0 ? 0 :    		BufCountLines(buf, pos, pos + nInserted);	linesDeleted = nDeleted == 0 ? 0 : countLines(deletedText);    }    /* Update the line starts and topLineNum */    if (nInserted != 0 || nDeleted != 0) {	if (textD->continuousWrap) {	    updateLineStarts(textD, wrapModStart, wrapModEnd-wrapModStart,	    	    nDeleted + pos-wrapModStart + (wrapModEnd-(pos+nInserted)),	    	    linesInserted, linesDeleted, &scrolled);	} else {	    updateLineStarts(textD, pos, nInserted, nDeleted, linesInserted,    		    linesDeleted, &scrolled);	}    } else    	scrolled = False;        /* If we're counting non-wrapped lines as well, maintain the absolute       (non-wrapped) line number of the text displayed */    if (maintainingAbsTopLineNum(textD) && (nInserted != 0 || nDeleted != 0)) {	if (pos + nDeleted < oldFirstChar)	    textD->absTopLineNum += BufCountLines(buf, pos, pos + nInserted) -		    countLines(deletedText);	else if (pos < oldFirstChar)	    resetAbsLineNum(textD);    }    	            /* Update the line count for the whole buffer */    textD->nBufferLines += linesInserted - linesDeleted;            /* Update the scroll bar ranges (and value if the value changed).  Note       that updating the horizontal scroll bar range requires scanning the       entire displayed text, however, it doesn't seem to hurt performance       much.  Note also, that the horizontal scroll bar update routine is       allowed to re-adjust horizOffset if there is blank space to the right       of all lines of text. */    updateVScrollBarRange(textD);    scrolled |= updateHScrollBarRange(textD);        /* Update the cursor position */    if (textD->cursorToHint != NO_HINT) {    	textD->cursorPos = textD->cursorToHint;    	textD->cursorToHint = NO_HINT;    } else if (textD->cursorPos > pos) {    	if (textD->cursorPos < pos + nDeleted)    	    textD->cursorPos = pos;    	else    	    textD->cursorPos += nInserted - nDeleted;    }    /* If the changes caused scrolling, re-paint everything and we're done. */    if (scrolled) {    	blankCursorProtrusions(textD);    	TextDRedisplayRect(textD, 0, textD->top, textD->width + textD->left,		textD->height);        if (textD->styleBuffer) {/* See comments in extendRangeForStyleMods */    	    textD->styleBuffer->primary.selected = False;            textD->styleBuffer->primary.zeroWidth = False;        }    	return;    }        /* If the changes didn't cause scrolling, decide the range of characters       that need to be re-painted.  Also if the cursor position moved, be       sure that the redisplay range covers the old cursor position so the       old cursor gets erased, and erase the bits of the cursor which extend       beyond the left and right edges of the text. */    startDispPos = textD->continuousWrap ? wrapModStart : pos;    if (origCursorPos == startDispPos && textD->cursorPos != startDispPos)    	startDispPos = min(startDispPos, origCursorPos-1);    if (linesInserted == linesDeleted) {        if (nInserted == 0 && nDeleted == 0)            endDispPos = pos + nRestyled;        else {    	    endDispPos = textD->continuousWrap ? wrapModEnd :    	    	    BufEndOfLine(buf, pos + nInserted) + 1;    	    if (origCursorPos >= startDispPos &&    	    	    (origCursorPos <= endDispPos || endDispPos == buf->length))    	    	blankCursorProtrusions(textD);    	}        /* If more than one line is inserted/deleted, a line break may have           been inserted or removed in between, and the line numbers may           have changed. If only one line is altered, line numbers cannot           be affected (the insertion or removal of a line break always            results in at least two lines being redrawn). */	if (linesInserted > 1) redrawLineNumbers(textD, False);    } else { /* linesInserted != linesDeleted */    	endDispPos = textD->lastChar + 1;    	if (origCursorPos >= pos)    	    blankCursorProtrusions(textD);	redrawLineNumbers(textD, False);    }        /* If there is a style buffer, check if the modification caused additional       changes that need to be redisplayed.  (Redisplaying separately would       cause double-redraw on almost every modification involving styled       text).  Extend the redraw range to incorporate style changes */    if (textD->styleBuffer)    	extendRangeForStyleMods(textD, &startDispPos, &endDispPos);        /* Redisplay computed range */    TextDRedisplayRange(textD, startDispPos, endDispPos);}/*** In continuous wrap mode, internal line numbers are calculated after** wrapping.  A separate non-wrapped line count is maintained when line** numbering is turned on.  There is some performance cost to maintaining this** line count, so normally absolute line numbers are not tracked if line** numbering is off.  This routine allows callers to specify that they still** want this line count maintained (for use via TextDPosToLineAndCol).** More specifically, this allows the line number reported in the statistics** line to be calibrated in absolute lines, rather than post-wrapped lines.*/void TextDMaintainAbsLineNum(textDisp *textD, int state){    textD->needAbsTopLineNum = state;    resetAbsLineNum(textD);}/*** Returns the absolute (non-wrapped) line number of the first line displayed.** Returns 0 if the absolute top line number is not being maintained.*/static int getAbsTopLineNum(textDisp *textD){    if (!textD->continuousWrap)	return textD->topLineNum;    if (maintainingAbsTopLineNum(textD))	return textD->absTopLineNum;    return 0;}/*** Re-calculate absolute top line number for a change in scroll position.*/static void offsetAbsLineNum(textDisp *textD, int oldFirstChar){    if (maintainingAbsTopLineNum(textD)) {	if (textD->firstChar < oldFirstChar)	    textD->absTopLineNum -= BufCountLines(textD->buffer,		    textD->firstChar, oldFirstChar);	else	    textD->absTopLineNum += BufCountLines(textD->buffer,		    oldFirstChar, textD->firstChar);    }}/*** Return true if a separate absolute top line number is being maintained** (for displaying line numbers or showing in the statistics line).*/static int maintainingAbsTopLineNum(textDisp *textD){    return textD->continuousWrap &&	    (textD->lineNumWidth != 0 || textD->needAbsTopLineNum);}/*** Count lines from the beginning of the buffer to reestablish the** absolute (non-wrapped) top line number.  If mode is not continuous wrap,** or the number is not being maintained, does nothing.*/static void resetAbsLineNum(textDisp *textD){    textD->absTopLineNum = 1;    offsetAbsLineNum(textD, 0);}/*** Find the line number of position "pos" relative to the first line of** displayed text. Returns False if the line is not displayed.*/static int posToVisibleLineNum(textDisp *textD, int pos, int *lineNum){    int i;        if (pos < textD->firstChar)    	return False;    if (pos > textD->lastChar) {    	if (emptyLinesVisible(textD)) {    	    if (textD->lastChar < textD->buffer->length) {    		if (!posToVisibleLineNum(textD, textD->lastChar, lineNum)) {    		    fprintf(stderr, "Consistency check ptvl failed\n");    		    return False;    		}    		return ++(*lineNum) <= textD->nVisibleLines-1;            } else {            	posToVisibleLineNum(textD, max(textD->lastChar-1, 0), lineNum);            	return True;            }	}	return False;    }    	    for (i=textD->nVisibleLines-1; i>=0; i--) {    	if (textD->lineStarts[i] != -1 && pos >= textD->lineStarts[i]) {    	    *lineNum = i;    	    return True;    	}    }    return False; /* probably never be reached */}/*** Redisplay the text on a single line represented by "visLineNum" (the** number of lines down from the top of the display), limited by** "leftClip" and "rightClip" window coordinates and "leftCharIndex" and** "rightCharIndex" character positions (not including the character at** position "rightCharIndex").**** The cursor i

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -