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

📄 styledtext.java

📁 源码为Eclipse开源开发平台桌面开发工具SWT的源代码,
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	 */	class ContentWidthCache implements LineCache {		StyledText parent;				// parent widget, used to create a GC for line measuring		int[] lineWidth;				// width in pixel of each line in the document, -1 for unknown width		StyledTextContent content;		// content to use for line width calculation		int lineCount;					// number of lines in lineWidth array		int maxWidth;					// maximum line width of all measured lines		int maxWidthLineIndex;			// index of the widest line					/** 	 * Creates a new <code>ContentWidthCache</code> and allocates space 	 * for the given number of lines.	 * <p>	 *	 * @param parent the StyledText widget used to create a GC for 	 * 	line measuring	 * @param lineCount initial number of lines to allocate space for	 */	public ContentWidthCache(StyledText parent, StyledTextContent content) {		this.parent = parent;		this.content = content;		this.lineCount = content.getLineCount();		lineWidth = new int[lineCount];		reset(0, lineCount, false);	}	/**	 * Calculates the width of each line in the given range if it has	 * not been calculated yet.	 * If any line in the given range is wider than the currently widest	 * line, the maximum line width is updated,	 * <p>	 * 	 * @param startLine first line to calculate the line width of	 * @param lineCount number of lines to calculate the line width for	 */	public void calculate(int startLine, int lineCount) {		int caretWidth = 0;		int endLine = startLine + lineCount;					if (startLine < 0 || endLine > lineWidth.length) {			return;		}		caretWidth = getCaretWidth();		for (int i = startLine; i < endLine; i++) {			if (lineWidth[i] == -1) {				String line = content.getLine(i);				int lineOffset = content.getOffsetAtLine(i);				lineWidth[i] = contentWidth(line, lineOffset) + caretWidth;			}			if (lineWidth[i] > maxWidth) {				maxWidth = lineWidth[i];				maxWidthLineIndex = i;			}		}	}	/** 	 * Calculates the width of the visible lines in the specified 	 * range.	 * <p>	 *	 * @param startLine	the first changed line	 * @param newLineCount the number of inserted lines	 */  	void calculateVisible(int startLine, int newLineCount) {		int topIndex = parent.getTopIndex();		int bottomLine = Math.min(getPartialBottomIndex(), startLine + newLineCount);				startLine = Math.max(startLine, topIndex);		calculate(startLine, bottomLine - startLine + 1);	}	/**	 * Measures the width of the given line.	 * <p>	 * 	 * @param line the line to measure	 * @param lineOffset start offset of the line to measure, relative 	 * 	to the start of the document	 * @param gc the GC to use for measuring the line	 * @param currentFont the font currently set in gc. Cached for better 	 * 	performance. Null when running in a bidi locale.	 * @return the width of the given line	 */	int contentWidth(String line, int lineOffset) {		TextLayout layout = renderer.getTextLayout(line, lineOffset);		Rectangle rect = layout.getLineBounds(0);		renderer.disposeTextLayout(layout);		return rect.x + rect.width + leftMargin + rightMargin;	}	/**	 * Grows the <code>lineWidth</code> array to accomodate new line width	 * information.	 * <p>	 *	 * @param numLines the number of elements to increase the array by	 */	void expandLines(int numLines) {		int size = lineWidth.length;		if (size - lineCount >= numLines) {			return;		}		int[] newLines = new int[Math.max(size * 2, size + numLines)];		System.arraycopy(lineWidth, 0, newLines, 0, size);		lineWidth = newLines;		reset(size, lineWidth.length - size, false);	}	/**	 * Returns the width of the longest measured line.	 * <p>	 *	 * @return the width of the longest measured line.	 */	public int getWidth() {		return maxWidth;	}	/**	 * Updates the line width array to reflect inserted or deleted lines.	 * <p>	 *	 * @param start	the starting line of the change that took place	 * @param delta	the number of lines in the change, > 0 indicates lines inserted,	 * 	< 0 indicates lines deleted	 */	void linesChanged(int startLine, int delta) {		boolean inserting = delta > 0;				if (delta == 0) {			return;		}		if (inserting) {			// shift the lines down to make room for new lines			expandLines(delta);			for (int i = lineCount - 1; i >= startLine; i--) {				lineWidth[i + delta] = lineWidth[i];			}			// reset the new lines			for (int i = startLine + 1; i <= startLine + delta && i < lineWidth.length; i++) {				lineWidth[i] = -1;			}			// have new lines been inserted above the longest line?			if (maxWidthLineIndex >= startLine) {				maxWidthLineIndex += delta;			}		} 		else {			// shift up the lines			for (int i = startLine - delta; i < lineCount; i++) {				lineWidth[i+delta] = lineWidth[i];			}			// has the longest line been removed?			if (maxWidthLineIndex > startLine && maxWidthLineIndex <= startLine - delta) {				maxWidth = 0;				maxWidthLineIndex = -1;			}			else			if (maxWidthLineIndex >= startLine - delta) {				maxWidthLineIndex += delta;			}		}		lineCount += delta;	}	/**	 * Resets the line width of the lines in the specified range.	 * <p>	 *	 * @param startLine	the first line to reset	 * @param lineCount the number of lines to reset	 * @param calculateMaxWidth true=if the widest line is being 	 * 	reset the maximum width of all remaining cached lines is 	 * 	calculated. false=the maximum width is set to 0 if the 	 * 	widest line is being reset.	 */	public void redrawReset(int startLine, int lineCount, boolean calculateMaxWidth) {		reset(startLine, lineCount, calculateMaxWidth);	}	/**	 * Resets the line width of the lines in the specified range.	 * <p>	 *	 * @param startLine	the first line to reset	 * @param lineCount the number of lines to reset	 * @param calculateMaxWidth true=if the widest line is being 	 * 	reset the maximum width of all remaining cached lines is 	 * 	calculated. false=the maximum width is set to 0 if the 	 * 	widest line is being reset.	 */	public void reset(int startLine, int lineCount, boolean calculateMaxWidth) {		int endLine = startLine + lineCount;				if (startLine < 0 || endLine > lineWidth.length) {			return;		}		for (int i = startLine; i < endLine; i++) {			lineWidth[i] = -1;		}				// if the longest line is one of the reset lines, the maximum line 		// width is no longer valid		if (maxWidthLineIndex >= startLine && maxWidthLineIndex < endLine) {			maxWidth = 0;			maxWidthLineIndex = -1;			if (calculateMaxWidth) {				for (int i = 0; i < lineCount; i++) {					if (lineWidth[i] > maxWidth) {						maxWidth = lineWidth[i];						maxWidthLineIndex = i;					}				}						}		}	}	/** 	 * Updates the line width array to reflect a text change.	 * Lines affected by the text change will be reset.	 * <p>	 *	 * @param startOffset	the start offset of the text change	 * @param newLineCount the number of inserted lines	 * @param replaceLineCount the number of deleted lines	 * @param newCharCount the number of new characters	 * @param replaceCharCount the number of deleted characters	 */  	public void textChanged(int startOffset, int newLineCount, int replaceLineCount, int newCharCount, int replaceCharCount) {		int startLine = parent.getLineAtOffset(startOffset);		boolean removedMaxLine = (maxWidthLineIndex > startLine && maxWidthLineIndex <= startLine + replaceLineCount);		// entire text deleted?		if (startLine == 0 && replaceLineCount == lineCount) {			lineCount = newLineCount;			lineWidth = new int[lineCount];			reset(0, lineCount, false);			maxWidth = 0;		}		else {			linesChanged(startLine, -replaceLineCount);			linesChanged(startLine, newLineCount);			lineWidth[startLine] = -1;		}		// only calculate the visible lines. otherwise measurements of changed lines 		// outside the visible area may subsequently change again without the 		// lines ever being visible.		calculateVisible(startLine, newLineCount);		// maxWidthLineIndex will be -1 (i.e., unknown line width) if the widget has 		// not been visible yet and the changed lines have therefore not been		// calculated above.		if (removedMaxLine || 			(maxWidthLineIndex != -1 && lineWidth[maxWidthLineIndex] < maxWidth)) {			// longest line has been removed or changed and is now shorter.			// need to recalculate maximum content width for all lines			maxWidth = 0;			for (int i = 0; i < lineCount; i++) {				if (lineWidth[i] > maxWidth) {					maxWidth = lineWidth[i];					maxWidthLineIndex = i;				}			}					}	}	}	/**	 * Updates the line wrapping of the content.	 * The line wrapping must always be in a consistent state. 	 * Therefore, when <code>reset</code> or <code>redrawReset</code>	 * is called, the line wrapping is recalculated immediately 	 * instead of in <code>calculate</code>.	 */	class WordWrapCache implements LineCache {		StyledText parent;		WrappedContent visualContent;					/** 	 * Creates a new <code>WordWrapCache</code> and calculates an initial	 * line wrapping.	 * <p>	 *	 * @param parent the StyledText widget to wrap content in.	 * @param content the content provider that does the actual line wrapping.	 */	public WordWrapCache(StyledText parent, WrappedContent content) {		this.parent = parent;		visualContent = content;		visualContent.wrapLines();	}	/**	 * Do nothing. Lines are wrapped immediately after reset.	 * <p>	 * 	 * @param startLine first line to calculate	 * @param lineCount number of lines to calculate	 */	public void calculate(int startLine, int lineCount) {	}	/**	 * Returns the client area width. Lines are wrapped so there	 * is no horizontal scroll bar.	 * <p>	 *	 * @return the line width	 */	public int getWidth() {		return parent.getClientArea().width;	}	/**	 * Wraps the lines in the specified range.	 * This method is called in <code>StyledText.redraw()</code>.	 * A redraw is therefore not necessary.	 * <p>	 *	 * @param startLine the first line to reset	 * @param lineCount the number of lines to reset	 * @param calculateMaxWidth true=implementors should retain a 	 * 	valid width even if it is affected by the reset operation.	 * 	false=the width may be set to 0	 */	public void redrawReset(int startLine, int lineCount, boolean calculateMaxWidth) {	    if (lineCount == visualContent.getLineCount()) {			// do a full rewrap if all lines are reset			visualContent.wrapLines();	    }	    else {		    visualContent.reset(startLine, lineCount);	    }	}	/**	 * Rewraps the lines in the specified range and redraws	 * the widget if the line wrapping has changed.	 * <p>	 *	 * @param startLine the first line to reset	 * @param lineCount the number of lines to reset	 * @param calculateMaxWidth true=implementors should retain a 	 * 	valid width even if it is affected by the reset operation.	 * 	false=the width may be set to 0	 */	public void reset(int startLine, int lineCount, boolean calculateMaxWidth) {		int itemCount = getPartialBottomIndex() - topIndex + 1;	    int[] oldLineOffsets = new int[itemCount];	    	    for (int i = 0; i < itemCount; i++) {	    	oldLineOffsets[i] = visualContent.getOffsetAtLine(i + topIndex);	    }	    redrawReset(startLine, lineCount, calculateMaxWidth);		// check for cases which will require a full redraw	    if (getPartialBottomIndex() - topIndex + 1 != itemCount) {	    	// number of visible lines has changed	    	parent.internalRedraw();	    }	    else {		    for (int i = 0; i < itemCount; i++) {		    	if (visualContent.getOffsetAtLine(i + topIndex) != oldLineOffsets[i]) {		    		// wrapping of one of the visible lines has changed		    		parent.internalRedraw();		    		break;		    	}	    	}	    		    }	}	/** 	 * Passes the text change notification to the line wrap content.	 * <p>	 *	 * @param startOffset	the start offset of the text change	 * @param newLineCount the number of inserted lines	 * @param replaceLineCount the number of deleted lines	 * @param newCharCount the number of new characters	 * @param replaceCharCount the number of deleted characters	 */  	public void textChanged(int startOffset, int newLineCount, int replaceLineCount, int newCharCount, int replaceCharCount) {		int startLine = visualContent.getLineAtOffset(startOffset);		visualContent.textChanged(startOffset, newLineCount, replaceLineCount, newCharCount, replaceCharCount);		// if we are wrapping then it is possible for a deletion on the last		// line of text to shorten the total text length by a line.  If this		// occurs then the startIndex must be adjusted such that a redraw will		// be performed if a visible region is affected.  fixes bug 42947.		if (wordWrap) {			int lineCount = content.getLineCount();			if (startLine >= lineCount) startLine = lineCount - 1;  		}		if (startLine <= getPartialBottomIndex()) {			// only redraw if the text change affects text inside or above 			// the visible lines. if it is below the visible lines it will			// not affect the word wrapping. fixes bug 14047.			parent.internalRedraw();		}	}	}/** * Constructs a new instance of this class given its parent * and a style value describing its behavior and appearance. * <p> * The style value is either one of the style constants defined in * class <code>SWT</code> which is applicable to instances of this

⌨️ 快捷键说明

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