Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Hendrikx2017-08-16 05:59:39 -0400
committerDani Megert2017-08-22 10:21:16 -0400
commita435a3c38c399c4c17905b5a714529e9268497a8 (patch)
tree9fe8d72ca09286fdb865ebff03963cb30147283f
parentf002b3af5b2e8c8d256615df1f5ab37dd11312f6 (diff)
downloadeclipse.platform.text-a435a3c38c399c4c17905b5a714529e9268497a8.tar.gz
eclipse.platform.text-a435a3c38c399c4c17905b5a714529e9268497a8.tar.xz
eclipse.platform.text-a435a3c38c399c4c17905b5a714529e9268497a8.zip
Bug 434194: [painting] "Show whitespace character" option makes the editor slow if there are many spacesI20170822-2000
Space characters (and their visible place holders) are drawn with a single call, not separately, if they are all of the same width. Change-Id: Ibfbcfe216cb8f7117180d5b530ebdf39ff81c164 Signed-off-by: John Hendrikx <hjohn@xs4all.nl>
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/WhitespaceCharacterPainter.java40
1 files changed, 29 insertions, 11 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/WhitespaceCharacterPainter.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/WhitespaceCharacterPainter.java
index 153f26f3b..475b82a2a 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/WhitespaceCharacterPainter.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/WhitespaceCharacterPainter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2012 Wind River Systems, Inc., IBM Corporation and others.
+ * Copyright (c) 2006, 2017 Wind River Systems, Inc., IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
* Anton Leherbauer (Wind River Systems) - [painting] Long lines take too long to display when "Show Whitespace Characters" is enabled - https://bugs.eclipse.org/bugs/show_bug.cgi?id=196116
* Anton Leherbauer (Wind River Systems) - [painting] Whitespace characters not drawn when scrolling to right slowly - https://bugs.eclipse.org/bugs/show_bug.cgi?id=206633
* Tom Eicher (Avaloq Evolution AG) - block selection mode
+ * John Hendrikx - [painting] Performance improvement of space character rendering - https://bugs.eclipse.org/bugs/show_bug.cgi?id=434194
*******************************************************************************/
package org.eclipse.jface.text;
@@ -40,6 +41,9 @@ public class WhitespaceCharacterPainter implements IPainter, PaintListener {
private static final char CARRIAGE_RETURN_SIGN= '\u00a4';
private static final char LINE_FEED_SIGN= '\u00b6';
+ private static final String SPACE_SIGN_STRING= String.valueOf(SPACE_SIGN);
+ private static final String IDEOGRAPHIC_SPACE_SIGN_STRING= String.valueOf(IDEOGRAPHIC_SPACE_SIGN);
+
/** Indicates whether this painter is active. */
private boolean fIsActive= false;
/** The source viewer this painter is attached to. */
@@ -215,6 +219,10 @@ public class WhitespaceCharacterPainter implements IPainter, PaintListener {
*/
private void drawLineRange(GC gc, int startLine, int endLine, int x, int w) {
final int viewPortWidth= fTextWidget.getClientArea().width;
+ int spaceCharWidth= gc.stringExtent(" ").x; //$NON-NLS-1$
+ boolean spaceCharsAreSameWidth= spaceCharWidth == gc.stringExtent(SPACE_SIGN_STRING).x &&
+ spaceCharWidth == gc.stringExtent(IDEOGRAPHIC_SPACE_SIGN_STRING).x;
+
for (int line= startLine; line <= endLine; line++) {
int lineOffset= fTextWidget.getOffsetAtLine(line);
// line end offset including line delimiter
@@ -268,7 +276,7 @@ public class WhitespaceCharacterPainter implements IPainter, PaintListener {
}
// draw character range
if (endOffset > startOffset) {
- drawCharRange(gc, startOffset, endOffset, lineOffset, lineEndOffset);
+ drawCharRange(gc, startOffset, endOffset, lineOffset, lineEndOffset, spaceCharsAreSameWidth);
}
}
}
@@ -285,8 +293,10 @@ public class WhitespaceCharacterPainter implements IPainter, PaintListener {
* @param endOffset exclusive end index of the drawing range
* @param lineOffset inclusive start index of the line
* @param lineEndOffset exclusive end index of the line
+ * @param spaceCharsAreSameWidth whether or not all space chars are same width, if <code>true</code>
+ * rendering can be optimized
*/
- private void drawCharRange(GC gc, int startOffset, int endOffset, int lineOffset, int lineEndOffset) {
+ private void drawCharRange(GC gc, int startOffset, int endOffset, int lineOffset, int lineEndOffset, boolean spaceCharsAreSameWidth) {
StyledTextContent content= fTextWidget.getContent();
String lineText= content.getTextRange(lineOffset, lineEndOffset - lineOffset);
int startOffsetInLine= startOffset - lineOffset;
@@ -313,11 +323,11 @@ public class WhitespaceCharacterPainter implements IPainter, PaintListener {
StyleRange styleRange= null;
Color fg= null;
StringBuilder visibleChar= new StringBuilder(10);
+ int delta= 0;
for (int textOffset= startOffsetInLine; textOffset <= endOffsetInLine; ++textOffset) {
- int delta= 0;
boolean eol= false;
+ delta++;
if (textOffset < endOffsetInLine) {
- delta= 1;
char c= lineText.charAt(textOffset);
switch (c) {
case ' ':
@@ -338,8 +348,12 @@ public class WhitespaceCharacterPainter implements IPainter, PaintListener {
visibleChar.append(SPACE_SIGN);
}
}
- // 'continue' would improve performance but may produce drawing errors
- // for long runs of space if width of space and dot differ
+ // 'continue' improves performance but may produce drawing errors
+ // for long runs of space if width of space and dot differ, therefore
+ // it can be used only for monospace fonts
+ if (spaceCharsAreSameWidth) {
+ continue;
+ }
break;
case '\u3000': // ideographic whitespace
if (isEmptyLine) {
@@ -359,8 +373,12 @@ public class WhitespaceCharacterPainter implements IPainter, PaintListener {
visibleChar.append(IDEOGRAPHIC_SPACE_SIGN);
}
}
- // 'continue' would improve performance but may produce drawing errors
- // for long runs of space if width of space and dot differ
+ // 'continue' improves performance but may produce drawing errors
+ // for long runs of space if width of space and dot differ, therefore
+ // it can be used only for monospace fonts
+ if (spaceCharsAreSameWidth) {
+ continue;
+ }
break;
case '\t':
if (isEmptyLine) {
@@ -397,12 +415,11 @@ public class WhitespaceCharacterPainter implements IPainter, PaintListener {
eol= true;
break;
default:
- delta= 0;
break;
}
}
if (visibleChar.length() > 0) {
- int widgetOffset= startOffset + textOffset - startOffsetInLine - visibleChar.length() + delta;
+ int widgetOffset= startOffset + textOffset - startOffsetInLine - delta + 1;
if (!eol || !isFoldedLine(content.getLineAtOffset(widgetOffset))) {
/*
* Block selection is drawn using alpha and no selection-inverting
@@ -422,6 +439,7 @@ public class WhitespaceCharacterPainter implements IPainter, PaintListener {
}
visibleChar.delete(0, visibleChar.length());
}
+ delta= 0;
}
}

Back to the top