?? defaultlinestyler.java
字號:
/******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/package org.eclipse.swt.custom;import org.eclipse.swt.graphics.*;import org.eclipse.swt.internal.Compatibility;import java.util.Vector;class DefaultLineStyler implements LineStyleListener, LineBackgroundListener { StyledTextContent content; StyleRange styles[] = new StyleRange[0]; int styleCount = 0; // the number of styles int styleExpandExp = 1; // the expansion exponent, used to increase the styles array exponentially int lineExpandExp = 1; // the expansion exponent, used to increase the lines array exponentially int lineCount = 0; Color lineBackgrounds[]; /** * Creates a new default line styler. * <p> * * @param content the text to which the styles apply */public DefaultLineStyler(StyledTextContent content) { this.content = content; lineCount = content.getLineCount(); lineBackgrounds = new Color[lineCount];} /** * Inserts a style at the given location. * <p> * * @param style the new style * @param index the index at which to insert the style (the new style * will reside at this index) * */void insertStyle(StyleRange style, int index) { insertStyles(new StyleRange[] {style}, index);}/** * Insert the styles at the given location. * <p> * * @param insertStyles the new styles * @param index the index at which to insert the styles (the first new style * will reside at this index) * */void insertStyles(StyleRange[] insertStyles, int index) { int size = styles.length; int insertCount = insertStyles.length; int spaceNeeded = styleCount + insertCount - size; if (spaceNeeded > 0) { StyleRange[] newStyles = new StyleRange[size+spaceNeeded]; System.arraycopy(styles, 0, newStyles, 0, size); styles = newStyles; } // shift the styles down to make room for the new styles System.arraycopy(styles, index, styles, index + insertCount, styleCount - index); // add the new styles System.arraycopy(insertStyles, 0, styles, index, insertCount); styleCount = styleCount + insertCount;}/** * Inserts a style, merging it with adjacent styles if possible. * <p> * * @param style the new style * @param index the index at which to insert the style (the new style * will reside at this index) * @return true if the style was inserted, false if the style was merged with an adjacent * style */boolean insertMergeStyle(StyleRange style, int index) { if (mergeStyleBefore(style, index)) return false; if (mergeStyleAfter(style, index)) return false; insertStyle(style, index); return true;}/** * Merges the style with the style before it if possible. * <p> * * @param style the new style * @param index the index at which to attempt the merge. * @return true if the style was merged, false otherwise */boolean mergeStyleBefore(StyleRange style, int index) { // see if the style is similar to the style before it and merge the // styles if possible if (index > 0) { StyleRange previous = styles[index-1]; if (style.similarTo(previous)) { // the start of style needs to be in the range of the previous style // and the end of style needs to be < the start of the next style int previousEnd = previous.start + previous.length; if ((style.start <= previousEnd) && (style.start >= previous.start)) { int styleEnd = style.start + style.length; if ((index == styleCount) || (styleEnd <= styles[index].start)) { previous.length = style.start + style.length - previous.start; return true; } } } } return false;}/** * Merges the style with the style after it if possible. * <p> * * @param style the new style * @param index the index at which to attempt the merge. * @return true if the style was merged, false otherwise */boolean mergeStyleAfter(StyleRange style, int index) { // see if the style is similar to the style that will be after it and // merge the styles if possible if (index < styleCount) { StyleRange next = styles[index]; if (style.similarTo(next)) { // the end of style needs to be in the range of the next style and // the start of style needs to be > the end of the previous style int styleEnd = style.start + style.length; int nextEnd = next.start + next.length; if ((styleEnd <= nextEnd) && (styleEnd >= next.start)) { if ((index == 0) || (style.start >= styles[index-1].start + styles[index-1].length)) { next.length = next.start + next.length - style.start; next.start = style.start; return true; } } } } return false;}/** * Removes style information that is defined for the range of text in <code>clearStyle</code>. * <p> * * @param clearStyle the style information to use for clearing */ void clearStyle(StyleRange clearStyle) { Point pt = getOverlappingStyles(clearStyle.start, clearStyle.length); int clearStyleEnd = clearStyle.start + clearStyle.length - 1; // no overlapped styles exist if ((pt == null) || (pt.y == 0)) return; // the newStyle overlaps one or more of the existing styles // pt.x is the index of the first overlapped style, pt.y is the number of overlapped // styles int count = 0; int deleteStyle = -1; int deleteCount = 0; for (int i=pt.x; count<pt.y; i++) { StyleRange overlap = styles[i]; int overlapEnd = overlap.start + overlap.length - 1; if (overlap.start < clearStyle.start) { if (overlapEnd <= clearStyleEnd) { // the end of overlap needs to be cleared overlap.length=clearStyle.start - overlap.start; } else { // middle of overlap needs to be cleared, this will // cause overlap to be broken into two StyleRange endStyle = (StyleRange)overlap.clone(); endStyle.start = clearStyleEnd + 1; endStyle.length = overlapEnd - clearStyleEnd; overlap.length = clearStyle.start - overlap.start; insertStyle(endStyle, i+1); break; } } else { if (overlapEnd <= clearStyleEnd) { // entire overlap needs to be cleared if (deleteStyle == -1) { deleteStyle = i; } deleteCount++; } else { // beginning of overlap needs to be cleared overlap.start=clearStyleEnd + 1; overlap.length=overlapEnd - overlap.start + 1; break; } } count++; } deleteStyles(deleteStyle, deleteCount);}/** * Increases the <code>linebackgrounds</code> array to accomodate new line background * information. * <p> * * @param numLines the number to increase the array by */void expandLinesBy(int numLines) { int size = lineBackgrounds.length; if (size - lineCount >= numLines) { return; } Color[] newLines = new Color[size+Math.max(Compatibility.pow2(lineExpandExp), numLines)]; System.arraycopy(lineBackgrounds, 0, newLines, 0, size); lineBackgrounds = newLines; lineExpandExp++;}/** * Deletes the style at <code>index</code>. * <p> * * @param index the index of the style to be deleted */void deleteStyle(int index) { deleteStyles(index, 1);}/** * Delete count styles starting at <code>index</code>. * <p> * * @param index the index of the style to be deleted * @param count the number of styles to be deleted */void deleteStyles(int index, int count) { if ((count == 0) || (index < 0)) return; // shift the styles up System.arraycopy(styles, index + count, styles, index, styleCount - (index + count)); for (int i=0; i<count; i++) { styles[styleCount - i - 1] = null; } styleCount = styleCount - count;}/** * Returns the styles that are defined. * <p> * * @return the copied array of styles */StyleRange [] getStyleRanges() { StyleRange[] newStyles = new StyleRange[styleCount]; System.arraycopy(styles, 0, newStyles, 0, styleCount); return newStyles;}/** * Handles the get line background color callback. * <p> * * @param event.lineOffset line number (input) * @param event.lineText line text (input) * @param event.background line background color (output) */public void lineGetBackground(LineBackgroundEvent event) { int lineIndex = content.getLineAtOffset(event.lineOffset); event.lineBackground = lineBackgrounds[lineIndex];}/** * Handles the get line style information callback. * <p> * * @param event.lineOffset line number (input) * @param event.lineText line text (input) * @param event.styles array of StyleRanges, need to be in order (output) */public void lineGetStyle(LineStyleEvent event) { int lineStart = event.lineOffset; int lineEnd = lineStart + event.lineText.length(); int high = searchForStyle(lineStart, lineEnd); StyleRange style = null; Vector lineStyles = new Vector(); // index will represent a style that // -- starts after the line (end processing) // -- ends before the line (continue processing) // -- starts before the line, ends in the line (add range) // -- starts in the line, ends in the line (add range) // -- starts in the line, ends after the line (add range) // -- starts before the line, ends after the line (add range) for (int index = high; index < styleCount; index++) { style = styles[index]; if (style.start > lineEnd) // style starts after the line, end looping break; int styleEnd = style.start + style.length - 1; if (styleEnd >= lineStart) lineStyles.addElement(style); } event.styles = new StyleRange[lineStyles.size()]; lineStyles.copyInto(event.styles);}/** * Searches for the first style in the <code>start</code> - <code>end</code> range. * <p> * * @return the index of the first style that overlaps the input range */int searchForStyle(int start, int end) { int high = styleCount; int low = -1; int index = high; // find the index of the first style for the given range, use a binary search while (high - low > 1) { index = (high + low) / 2; StyleRange style = styles[index]; int styleEnd = style.start + style.length - 1; if (start <= style.start || end <= styleEnd || (start > style.start && styleEnd >= start && styleEnd < end)) { high = index; } else { low = index; } } return high;}/** * Updates the line background colors to reflect a new color. Called by StyledText. * <p> * * @param startLine index of the first line to color * @param lineCount number of lines to color starting at startLine * @param background the background color for the lines */ void setLineBackground(int startLine, int count, Color background) { for (int i=startLine; i<startLine + count; i++) { lineBackgrounds[i]=background; }}/** * Update the styles to reflect the new style. <code>newStyle</code> will * replace any old style for the range. When this method is called, the * DefaultLineStyler may merge the new style with an existing style (if possible). * Called by StyledText when a style is added. Called by StyledText. * <p> * * @param newStyle the new style information. */ void setStyleRange(StyleRange newStyle) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -