Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMickael Istria2018-03-01 21:56:19 +0000
committerMickael Istria2019-10-18 13:45:55 +0000
commit1ef69a696e82963c1b935ca9bcea9931ee143448 (patch)
treee47d93615e63554d411d707ffc4544a001d1459d
parentcd4eac3be76c741762242d58efabde64d936090f (diff)
downloadeclipse.platform.swt-1ef69a696e82963c1b935ca9bcea9931ee143448.tar.gz
eclipse.platform.swt-1ef69a696e82963c1b935ca9bcea9931ee143448.tar.xz
eclipse.platform.swt-1ef69a696e82963c1b935ca9bcea9931ee143448.zip
Bug 530878 - Dynamically compute isFixedLineHeight
Do not consider fixedHeightLength as a state but instead deduce it from other "payload" state (current styles, linespacing and so on). Also-By: Angelo Zerr <angelozerr@gmail.com> Change-Id: Ifd7994d7f1f9f568e7d6d9ff089ffcccb4aa5f93
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java36
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java3
-rw-r--r--tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java45
3 files changed, 62 insertions, 22 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
index f1b66ece68..4b6a2f112f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
@@ -131,6 +131,7 @@ public class StyledText extends Canvas {
boolean editable = true;
boolean wordWrap = false; // text is wrapped automatically
boolean visualWrap = false; // process line breaks inside logical lines (inserted by BidiSegmentEvent)
+ boolean hasStyleWithVariableHeight = false;
boolean doubleClickEnabled = true; // see getDoubleClickEnabled
boolean overwrite = false; // insert/overwrite edit mode
int textLimit = -1; // limits the number of characters the user can type in the widget. Unlimited by default.
@@ -163,7 +164,6 @@ public class StyledText extends Canvas {
int caretWidth = 0;
Caret defaultCaret = null;
boolean updateCaretDirection = true;
- boolean fixedLineHeight;
boolean dragDetect = true;
IME ime;
Cursor cursor;
@@ -1220,7 +1220,6 @@ public StyledText(Composite parent, int style) {
super.setForeground(getForeground());
super.setDragDetect(false);
Display display = getDisplay();
- fixedLineHeight = true;
if ((style & SWT.READ_ONLY) != 0) {
setEditable(false);
}
@@ -4929,7 +4928,6 @@ StyledTextEvent getBidiSegments(int lineOffset, String line) {
for (int i= 0; i < segmentsChars.length; i++) {
if (segmentsChars[i] == '\n' || segmentsChars[i] == '\r') {
visualWrap = true;
- setVariableLineHeight();
break;
}
}
@@ -7325,7 +7323,7 @@ boolean isBidiCaret() {
return BidiUtil.isBidiPlatform();
}
boolean isFixedLineHeight() {
- return fixedLineHeight;
+ return !isWordWrap() && lineSpacing == 0 && renderer.lineSpacingProvider == null && !hasStyleWithVariableHeight;
}
/**
* Returns whether the given offset is inside a multi byte line delimiter.
@@ -9375,11 +9373,6 @@ public void setLineBullet(int startLine, int lineCount, Bullet bullet) {
setCaretLocation();
}
}
-void setVariableLineHeight () {
- if (!fixedLineHeight) return;
- fixedLineHeight = false;
- renderer.calculateIdle();
-}
/**
* Returns true if StyledText is in word wrap mode and false otherwise.
*
@@ -9481,7 +9474,6 @@ public void setLineVerticalIndent(int lineIndex, int verticalLineIndent) {
if (verticalLineIndent == renderer.getLineVerticalIndent(lineIndex)) {
return;
}
- setVariableLineHeight();
int oldBottom = getLinePixel(lineIndex + 1);
if (oldBottom <= getClientArea().height) {
verticalScrollOffset = -1;
@@ -9561,7 +9553,6 @@ public void setLineSpacing(int lineSpacing) {
checkWidget();
if (this.lineSpacing == lineSpacing || lineSpacing < 0) return;
this.lineSpacing = lineSpacing;
- setVariableLineHeight();
resetCache(0, content.getLineCount());
setCaretLocation();
super.redraw();
@@ -9580,6 +9571,7 @@ public void setLineSpacing(int lineSpacing) {
*/
public void setLineSpacingProvider(StyledTextLineSpacingProvider lineSpacingProvider) {
checkWidget();
+ boolean wasFixedLineHeight = isFixedLineHeight();
if (renderer.getLineSpacingProvider() == null && lineSpacingProvider == null
|| (renderer.getLineSpacingProvider() != null
&& renderer.getLineSpacingProvider().equals(lineSpacingProvider)))
@@ -9587,17 +9579,16 @@ public void setLineSpacingProvider(StyledTextLineSpacingProvider lineSpacingProv
renderer.setLineSpacingProvider(lineSpacingProvider);
// reset lines cache if needed
if (lineSpacingProvider == null) {
- if (!isFixedLineHeight()) {
+ if (!wasFixedLineHeight) {
resetCache(0, content.getLineCount());
}
} else {
- if (isFixedLineHeight()) {
+ if (wasFixedLineHeight) {
int firstLine = -1;
for (int i = 0; i < content.getLineCount(); i++) {
Integer lineSpacing = lineSpacingProvider.getLineSpacing(i);
if (lineSpacing != null && lineSpacing > 0) {
// there is a custom line spacing, set StyledText as variable line height mode
- setVariableLineHeight();
// reset only the line size
renderer.reset(i, 1);
if (firstLine == -1) {
@@ -10238,6 +10229,7 @@ void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles, bo
int[] formerRanges = getRanges(start, length);
StyleRange[] formerStyles = getStyleRanges(start, length);
int end = start + length;
+ final boolean wasFixedLineHeight = isFixedLineHeight();
if (start > end || start < 0) {
SWT.error(SWT.ERROR_INVALID_RANGE);
}
@@ -10249,7 +10241,6 @@ void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles, bo
if (ranges.length != styles.length << 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
int lastOffset = 0;
- boolean variableHeight = false;
for (int i = 0; i < styles.length; i ++) {
if (styles[i] == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
int rangeStart, rangeLength;
@@ -10263,10 +10254,9 @@ void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles, bo
if (rangeLength < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
if (!(0 <= rangeStart && rangeStart + rangeLength <= charCount)) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
if (lastOffset > rangeStart) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- variableHeight |= styles[i].isVariableHeight();
+ hasStyleWithVariableHeight |= styles[i].isVariableHeight();
lastOffset = rangeStart + rangeLength;
}
- if (variableHeight) setVariableLineHeight();
}
int rangeStart = start, rangeEnd = end;
if (styles != null && styles.length > 0) {
@@ -10278,6 +10268,8 @@ void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles, bo
rangeEnd = styles[styles.length - 1].start + styles[styles.length - 1].length;
}
}
+
+ // This needs to happen before new styles are applied
int expectedBottom = 0;
if (!isFixedLineHeight() && !reset) {
int lineEnd = content.getLineAtOffset(Math.max(end, rangeEnd));
@@ -10296,6 +10288,13 @@ void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles, bo
renderer.setStyleRanges(ranges, styles);
}
+ // re-evaluate variable height with all styles (including new ones)
+ hasStyleWithVariableHeight = false;
+ for (StyleRange style : getStyleRanges(false)) {
+ hasStyleWithVariableHeight = style.isVariableHeight();
+ if (hasStyleWithVariableHeight) break;
+ }
+
SortedSet<Integer> modifiedLines = computeModifiedLines(formerRanges, formerStyles, ranges, styles);
resetCache(modifiedLines);
if (reset) {
@@ -10314,7 +10313,7 @@ void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles, bo
if (partialTopIndex <= lineEnd && lineEnd <= partialBottomIndex) {
bottom = getLinePixel(lineEnd + 1);
}
- if (!isFixedLineHeight() && bottom != expectedBottom) {
+ if (!(wasFixedLineHeight && isFixedLineHeight()) && bottom != expectedBottom) {
bottom = clientAreaHeight;
}
super.redraw(0, top, clientAreaWidth, bottom - top, false);
@@ -10743,7 +10742,6 @@ public void setWordWrap(boolean wrap) {
if (wordWrap == wrap) return;
if (wordWrap && blockSelection) setBlockSelection(false);
wordWrap = wrap;
- setVariableLineHeight();
resetCache(0, content.getLineCount());
horizontalScrollOffset = 0;
ScrollBar horizontalBar = getHorizontalBar();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java
index 86517a5e27..8dd8ac9c38 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java
@@ -912,7 +912,6 @@ TextLayout getTextLayout(int lineIndex) {
*/
lineSpacingComputing = true;
styledText.resetCache(lineIndex, 1);
- styledText.setVariableLineHeight();
styledText.setCaretLocation();
styledText.redraw();
} finally {
@@ -1049,8 +1048,8 @@ TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpac
if (styledText.isFixedLineHeight()) {
for (int i = 0; i < styleCount; i++) {
if (styles[i].isVariableHeight()) {
+ styledText.hasStyleWithVariableHeight = true;
styledText.verticalScrollOffset = -1;
- styledText.setVariableLineHeight();
styledText.redraw();
break;
}
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java
index b3fbd75b2e..dc654c6927 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java
@@ -64,15 +64,19 @@ import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.BidiUtil;
+import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.widgets.Caret;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
+import org.eclipse.test.Screenshots;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestWatcher;
/**
* Automated Test Suite for class org.eclipse.swt.custom.StyledText
@@ -93,6 +97,14 @@ Map<RGB, Color> colors = new HashMap<>();
private boolean listenerCalled;
private boolean listener2Called;
+@Rule public TestWatcher screenshotRule = new TestWatcher() {
+ @Override
+ protected void failed(Throwable e, org.junit.runner.Description description) {
+ super.failed(e, description);
+ Screenshots.takeScreenshot(description.getTestClass(), description.getMethodName());
+ }
+};
+
@Override
@Before
public void setUp() {
@@ -5296,7 +5308,6 @@ public void test_insertInBlockSelection() {
@Test
public void test_setStyleRanges_render() throws InterruptedException {
- Assume.assumeFalse("Bug 536588 prevents test to work on Mac", SwtTestUtil.isCocoa);
shell.setVisible(true);
text.setText("abc");
text.setMargins(0, 0, 0, 0);
@@ -5428,6 +5439,38 @@ private void testLineStyleListener(String content, LineStyleListener listener, B
* @return <code>true</code> if the given color was found in current text widget
* bounds
*/
+@Test
+public void test_variableToFixedLineHeight() throws InterruptedException {
+ GridData layoutData = new GridData(SWT.FILL, SWT.FILL,true, true);
+ text.setLayoutData(layoutData);
+ shell.setVisible(true);
+ text.setText("\nabc\n\nd");
+ text.setMargins(0, 0, 0, 0);
+ text.setSize(100, 100);
+ processEvents(1000, () -> Boolean.FALSE);
+ StyleRange range = new StyleRange();
+ range.start = 1;
+ range.length = 1;
+ Color colorForVariableHeight = text.getDisplay().getSystemColor(SWT.COLOR_RED);
+ range.background = colorForVariableHeight;
+ range.metrics = new GlyphMetrics(40, 0, 10);
+ text.setStyleRange(range);
+ // move to variable height and paint with red to check later whether
+ // redraw was done properly
+ processEvents(100, null);
+ range = new StyleRange();
+ range.start = 1;
+ range.length = 1;
+ range.fontStyle = SWT.BOLD;
+ range.metrics = null;
+ text.replaceStyleRanges(0, text.getCharCount(), new StyleRange[] {range});
+ // changing to fixed line height here should redraw widget until
+ // the bottom and clear the area (no more red)
+ processEvents(3000, () -> !hasPixel(text, colorForVariableHeight));
+ assertFalse(hasPixel(text, colorForVariableHeight));
+}
+
+
private boolean hasPixel(StyledText text, Color expectedColor) {
return hasPixel(text, expectedColor, null);
}

Back to the top