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

📄 textdisp.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
    	charLen = BufExpandCharacter(lineStr[charIndex], outIndex, expandedChar,    		textD->buffer->tabDist, textD->buffer->nullSubsChar);   	charStyle = styleOfPos(textD, lineStartPos, lineLen, charIndex,   	    	outIndex, lineStr[charIndex]);    	xStep += stringWidth(textD, expandedChar, charLen, charStyle);    	outIndex += charLen;    }    *x = xStep;    XtFree(lineStr);    return True;}/*** If the text widget is maintaining a line number count appropriate to "pos"** return the line and column numbers of pos, otherwise return False.  If** continuous wrap mode is on, returns the absolute line number (as opposed to** the wrapped line number which is used for scrolling).  THIS ROUTINE ONLY** WORKS FOR DISPLAYED LINES AND, IN CONTINUOUS WRAP MODE, ONLY WHEN THE** ABSOLUTE LINE NUMBER IS BEING MAINTAINED.  Otherwise, it returns False.*/int TextDPosToLineAndCol(textDisp *textD, int pos, int *lineNum, int *column){    textBuffer *buf = textD->buffer;        /* In continuous wrap mode, the absolute (non-wrapped) line count is       maintained separately, as needed.  Only return it if we're actually       keeping track of it and pos is in the displayed text */    if (textD->continuousWrap) {	if (!maintainingAbsTopLineNum(textD) || pos < textD->firstChar ||		pos > textD->lastChar)	    return False;	*lineNum = textD->absTopLineNum + BufCountLines(buf,		textD->firstChar, pos);	*column = BufCountDispChars(buf, BufStartOfLine(buf, pos), pos);	return True;    }    /* Only return the data if pos is within the displayed text */    if (!posToVisibleLineNum(textD, pos, lineNum))	return False;    *column = BufCountDispChars(buf, textD->lineStarts[*lineNum], pos);    *lineNum += textD->topLineNum;    return True;}/*** Return True if position (x, y) is inside of the primary selection*/int TextDInSelection(textDisp *textD, int x, int y){    int row, column, pos = xyToPos(textD, x, y, CHARACTER_POS);    textBuffer *buf = textD->buffer;        xyToUnconstrainedPos(textD, x, y, &row, &column, CHARACTER_POS);    if (rangeTouchesRectSel(&buf->primary, textD->firstChar, textD->lastChar))    	column = TextDOffsetWrappedColumn(textD, row, column);    return inSelection(&buf->primary, pos, BufStartOfLine(buf, pos), column);}/*** Correct a column number based on an unconstrained position (as returned by** TextDXYToUnconstrainedPosition) to be relative to the last actual newline** in the buffer before the row and column position given, rather than the** last line start created by line wrapping.  This is an adapter** for rectangular selections and code written before continuous wrap mode,** which thinks that the unconstrained column is the number of characters** from the last newline.  Obviously this is time consuming, because it** invloves character re-counting.*/int TextDOffsetWrappedColumn(textDisp *textD, int row, int column){    int lineStart, dispLineStart;        if (!textD->continuousWrap || row < 0 || row > textD->nVisibleLines)    	return column;    dispLineStart = textD->lineStarts[row];    if (dispLineStart == -1)    	return column;    lineStart = BufStartOfLine(textD->buffer, dispLineStart);    return column + BufCountDispChars(textD->buffer, lineStart, dispLineStart);}/*** Correct a row number from an unconstrained position (as returned by** TextDXYToUnconstrainedPosition) to a straight number of newlines from the** top line of the display.  Because rectangular selections are based on** newlines, rather than display wrapping, and anywhere a rectangular selection** needs a row, it needs it in terms of un-wrapped lines.*/int TextDOffsetWrappedRow(textDisp *textD, int row){    if (!textD->continuousWrap || row < 0 || row > textD->nVisibleLines)    	return row;    return BufCountLines(textD->buffer, textD->firstChar,     	    textD->lineStarts[row]);}/*** Scroll the display to bring insertion cursor into view.**** Note: it would be nice to be able to do this without counting lines twice** (setScroll counts them too) and/or to count from the most efficient** starting point, but the efficiency of this routine is not as important to** the overall performance of the text display.*/void TextDMakeInsertPosVisible(textDisp *textD){    int hOffset, topLine, x, y;    int cursorPos = textD->cursorPos;    int linesFromTop = 0, do_padding = 1;     int cursorVPadding = (int)TEXT_OF_TEXTD(textD).cursorVPadding;        hOffset = textD->horizOffset;    topLine = textD->topLineNum;        /* Don't do padding if this is a mouse operation */    do_padding = ((TEXT_OF_TEXTD(textD).dragState == NOT_CLICKED) &&                  (cursorVPadding > 0));        /* Find the new top line number */    if (cursorPos < textD->firstChar) {        topLine -= TextDCountLines(textD, cursorPos, textD->firstChar, False);        /* linesFromTop = 0; */    } else if (cursorPos > textD->lastChar && !emptyLinesVisible(textD)) {        topLine += TextDCountLines(textD, textD->lastChar -                (wrapUsesCharacter(textD, textD->lastChar) ? 0 : 1),                cursorPos, False);        linesFromTop = textD->nVisibleLines-1;    } else if (cursorPos == textD->lastChar && !emptyLinesVisible(textD) &&            !wrapUsesCharacter(textD, textD->lastChar)) {        topLine++;        linesFromTop = textD->nVisibleLines-1;    } else {        /* Avoid extra counting if cursorVPadding is disabled */        if (do_padding)            linesFromTop = TextDCountLines(textD, textD->firstChar,                     cursorPos, True);    }    if (topLine < 1) {        fprintf(stderr, "internal consistency check tl1 failed\n");        topLine = 1;    }        if (do_padding) {        /* Keep the cursor away from the top or bottom of screen. */        if (textD->nVisibleLines <= 2*(int)cursorVPadding) {            topLine += (linesFromTop - textD->nVisibleLines/2);            topLine = max(topLine, 1);        } else if (linesFromTop < (int)cursorVPadding) {            topLine -= (cursorVPadding - linesFromTop);            topLine = max(topLine, 1);        } else if (linesFromTop > textD->nVisibleLines-(int)cursorVPadding-1) {            topLine += (linesFromTop - (textD->nVisibleLines-cursorVPadding-1));        }    }        /* Find the new setting for horizontal offset (this is a bit ungraceful).       If the line is visible, just use TextDPositionToXY to get the position       to scroll to, otherwise, do the vertical scrolling first, then the       horizontal */    if (!TextDPositionToXY(textD, cursorPos, &x, &y)) {        setScroll(textD, topLine, hOffset, True, True);        if (!TextDPositionToXY(textD, cursorPos, &x, &y))            return; /* Give up, it's not worth it (but why does it fail?) */    }    if (x > textD->left + textD->width)        hOffset += x - (textD->left + textD->width);    else if (x < textD->left)        hOffset += x - textD->left;        /* Do the scroll */    setScroll(textD, topLine, hOffset, True, True);}/*** Return the current preferred column along with the current** visible line index (-1 if not visible) and the lineStartPos** of the current insert position.*/int TextDPreferredColumn(textDisp *textD, int *visLineNum, int *lineStartPos){    int column;    /* Find the position of the start of the line.  Use the line starts array    if possible, to avoid unbounded line-counting in continuous wrap mode */    if (posToVisibleLineNum(textD, textD->cursorPos, visLineNum)) {        *lineStartPos = textD->lineStarts[*visLineNum];    }    else {        *lineStartPos = TextDStartOfLine(textD, textD->cursorPos);        *visLineNum = -1;    }    /* Decide what column to move to, if there's a preferred column use that */    column = textD->cursorPreferredCol >= 0 ? textD->cursorPreferredCol :        BufCountDispChars(textD->buffer, *lineStartPos, textD->cursorPos);    return(column);}/*** Return the insert position of the requested column given** the lineStartPos.*/int TextDPosOfPreferredCol(textDisp *textD, int column, int lineStartPos){    int newPos;    newPos = BufCountForwardDispChars(textD->buffer, lineStartPos, column);    if (textD->continuousWrap) {        newPos = min(newPos, TextDEndOfLine(textD, lineStartPos, True));    }    return(newPos);}/*** Cursor movement functions*/int TextDMoveRight(textDisp *textD){    if (textD->cursorPos >= textD->buffer->length)    	return False;    TextDSetInsertPosition(textD, textD->cursorPos + 1);    return True;}int TextDMoveLeft(textDisp *textD){    if (textD->cursorPos <= 0)    	return False;    TextDSetInsertPosition(textD, textD->cursorPos - 1);     return True;}int TextDMoveUp(textDisp *textD, int absolute){    int lineStartPos, column, prevLineStartPos, newPos, visLineNum;        /* Find the position of the start of the line.  Use the line starts array       if possible, to avoid unbounded line-counting in continuous wrap mode */    if (absolute) {        lineStartPos = BufStartOfLine(textD->buffer, textD->cursorPos);        visLineNum = -1;    } else if (posToVisibleLineNum(textD, textD->cursorPos, &visLineNum))    	lineStartPos = textD->lineStarts[visLineNum];    else {    	lineStartPos = TextDStartOfLine(textD, textD->cursorPos);    	visLineNum = -1;    }    if (lineStartPos == 0)    	return False;        /* Decide what column to move to, if there's a preferred column use that */    column = textD->cursorPreferredCol >= 0 ? textD->cursorPreferredCol :    	    BufCountDispChars(textD->buffer, lineStartPos, textD->cursorPos);        /* count forward from the start of the previous line to reach the column */    if (absolute)        prevLineStartPos = BufCountBackwardNLines(textD->buffer, lineStartPos, 1);    else if (visLineNum != -1 && visLineNum != 0)    	prevLineStartPos = textD->lineStarts[visLineNum-1];    else    	prevLineStartPos = TextDCountBackwardNLines(textD, lineStartPos, 1);    newPos = BufCountForwardDispChars(textD->buffer, prevLineStartPos, column);    if (textD->continuousWrap && !absolute)    	newPos = min(newPos, TextDEndOfLine(textD, prevLineStartPos, True));        /* move the cursor */    TextDSetInsertPosition(textD, newPos);        /* if a preferred column wasn't aleady established, establish it */    textD->cursorPreferredCol = column;        return True;}int TextDMoveDown(textDisp *textD, int absolute){    int lineStartPos, column, nextLineStartPos, newPos, visLineNum;        if (textD->cursorPos == textD->buffer->length)    	return False;    if (absolute) {        lineStartPos = BufStartOfLine(textD->buffer, textD->cursorPos);    	visLineNum = -1;    } else if (posToVisibleLineNum(textD, textD->cursorPos, &visLineNum))    	lineStartPos = textD->lineStarts[visLineNum];    else {    	lineStartPos = TextDStartOfLine(textD, textD->cursorPos);    	visLineNum = -1;    }    column = textD->cursorPreferredCol >= 0 ? textD->cursorPreferredCol :    	    BufCountDispChars(textD->buffer, lineStartPos, textD->cursorPos);    if (absolute)        nextLineStartPos = BufCountForwardNLines(textD->buffer, lineStartPos, 1);    else        nextLineStartPos = TextDCountForwardNLines(textD, lineStartPos, 1, True);    newPos = BufCountForwardDispChars(textD->buffer, nextLineStartPos, column);    if (textD->continuousWrap && !absolute)    	newPos = min(newPos, TextDEndOfLine(textD, nextLineStartPos, True));    TextDSetInsertPosition(textD, newPos);    textD->cursorPreferredCol = column;        return True;}/*** Same as BufCountLines, but takes in to account wrapping if 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.*/int TextDCountLines(textDisp *textD, int startPos, int endPos,    	int startPosIsLineStart){    int retLines, retPos, retLineStart, retLineEnd;        /* If we're not wrapping use simple (and more efficient) BufCountLines */    if (!textD->continuousWrap)    	return BufCountLines(textD->buffer, startPos, endPos);        wrappedLineCounter(textD, textD->buffer, startPos, endPos, INT_MAX,	    startPosIsLineStart, 0, &retPos, &retLines, &retLineStart,	    &retLineEnd);    return retLines;}/*** Same as BufCountForwardNLines, 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.*/int TextDCountForwardNLines(textDisp *textD, int startPos, int nLines,    	int startPosIsLineStart){    int retLines, retPos, retLineStart, retLineEnd;        /* if we're not wrapping use more efficient BufCountForwardNLines */    if (!textD->continuousWrap)    	return BufCountForwardNLines(textD->buffer, startPos, nLines);        /* wrappedLineCounter can't handle the 0 lines case */    if (nLines == 0)    	return startPos;    

⌨️ 快捷键说明

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