Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java18
-rw-r--r--tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java51
-rw-r--r--tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Widget.java17
3 files changed, 80 insertions, 6 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 651869e8b9..cba08a72c0 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
@@ -10156,24 +10156,24 @@ private SortedSet<Integer> computeModifiedLines(int[] referenceRanges, StyleRang
while (currentOffset < content.getCharCount() && (referenceRangeIndex < referenceStyles.length || newRangeIndex < newRanges.length)) {
int nextMilestoneOffset = Integer.MAX_VALUE; // next new range start/end after current offset
- while (referenceRangeIndex < referenceStyles.length && lastRangeOffset(referenceRanges, referenceRangeIndex) < currentOffset) {
+ while (referenceRangeIndex < referenceStyles.length && endRangeOffset(referenceRanges, referenceRangeIndex) <= currentOffset) {
referenceRangeIndex++;
}
StyleRange referenceStyleAtCurrentOffset = defaultStyle;
if (isInRange(referenceRanges, referenceRangeIndex, currentOffset)) { // has styling
referenceStyleAtCurrentOffset = referenceStyles[referenceRangeIndex];
- nextMilestoneOffset = Math.min(nextMilestoneOffset, lastRangeOffset(referenceRanges, referenceRangeIndex) + 1); //just after current range
+ nextMilestoneOffset = Math.min(nextMilestoneOffset, endRangeOffset(referenceRanges, referenceRangeIndex));
} else if (referenceRangeIndex + 1 < referenceStyles.length) { // no range, default styling
nextMilestoneOffset = referenceRanges[2 * (referenceRangeIndex + 1)]; // beginning of next range
}
- while (newRangeIndex < newStyles.length && lastRangeOffset(newRanges, newRangeIndex) < currentOffset) {
+ while (newRangeIndex < newStyles.length && endRangeOffset(newRanges, newRangeIndex) <= currentOffset) {
newRangeIndex++;
}
StyleRange newStyleAtCurrentOffset = defaultStyle;
if (isInRange(newRanges, newRangeIndex, currentOffset)) {
newStyleAtCurrentOffset = newStyles[newRangeIndex];
- nextMilestoneOffset = Math.min(nextMilestoneOffset, lastRangeOffset(newRanges, newRangeIndex) + 1);
+ nextMilestoneOffset = Math.min(nextMilestoneOffset, endRangeOffset(newRanges, newRangeIndex));
} else if (newRangeIndex + 1 < newStyles.length) {
nextMilestoneOffset = newRanges[2 * (newRangeIndex + 1)];
}
@@ -10207,10 +10207,16 @@ private boolean isInRange(int[] ranges, int styleIndex, int offset) {
}
int start = ranges[2 * styleIndex];
int length = ranges[2 * styleIndex + 1];
- return offset >= start && offset <= start + length;
+ return offset >= start && offset < start + length;
}
-private int lastRangeOffset(int[] ranges, int styleIndex) {
+/**
+ * The offset on which the range ends (excluded)
+ * @param ranges
+ * @param styleIndex
+ * @return
+ */
+private int endRangeOffset(int[] ranges, int styleIndex) {
if (styleIndex < 0 || 2 * styleIndex > ranges.length) {
throw new IllegalArgumentException();
}
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 470204641b..0e159fa396 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
@@ -48,7 +48,10 @@ import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.GlyphMetrics;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
@@ -59,6 +62,7 @@ import org.eclipse.swt.widgets.Caret;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.junit.After;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
@@ -5198,6 +5202,53 @@ public void test_insertInBlockSelection() {
+ System.getProperty("line.separator")));
}
+@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);
+ text.pack();
+ processEvents(1000, () -> hasPixel(text, text.getBackground()) && !hasPixel(text, text.getDisplay().getSystemColor(SWT.COLOR_RED)));
+ assertTrue(hasPixel(text, text.getBackground()));
+ assertFalse(hasPixel(text, text.getDisplay().getSystemColor(SWT.COLOR_RED)));
+ text.setStyleRanges(new StyleRange[] {
+ new StyleRange(0, 1, null, text.getDisplay().getSystemColor(SWT.COLOR_RED)),
+ new StyleRange(2, 1, null, text.getDisplay().getSystemColor(SWT.COLOR_RED)),
+ });
+ processEvents(100, () ->
+ hasPixel(text, text.getBackground()) &&
+ hasPixel(text, text.getDisplay().getSystemColor(SWT.COLOR_RED)));
+ assertTrue(hasPixel(text, text.getBackground()));
+ assertTrue(hasPixel(text, text.getDisplay().getSystemColor(SWT.COLOR_RED)));
+ text.replaceStyleRanges(0, 3, new StyleRange[] {
+ new StyleRange(0, 3, null, text.getDisplay().getSystemColor(SWT.COLOR_RED)),
+ });
+ processEvents(1000, () -> !hasPixel(text, text.getBackground()) && hasPixel(text, text.getDisplay().getSystemColor(SWT.COLOR_RED)));
+ assertFalse(hasPixel(text, text.getBackground()));
+ assertTrue(hasPixel(text, text.getDisplay().getSystemColor(SWT.COLOR_RED)));
+}
+
+private boolean hasPixel(StyledText text, Color expectedColor) {
+ GC gc = new GC(text);
+ final Image image = new Image(text.getDisplay(), text.getSize().x, text.getSize().y);
+ gc.copyArea(image, 0, 0);
+ gc.dispose();
+ ImageData imageData = image.getImageData();
+ RGB expectedRGB = expectedColor.getRGB();
+ for (int x = 1; x < image.getBounds().width - 1; x++) { // ignore first and last columns
+ for (int y = 0; y < image.getBounds().height; y++) {
+ RGB pixelRGB = imageData.palette.getRGB(imageData.getPixel(x, y));
+ if (expectedRGB.equals(pixelRGB)) {
+ image.dispose();
+ return true;
+ }
+ }
+ }
+ image.dispose();
+ return false;
+}
+
private String blockSelectionTestText() {
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < 20; i++) {
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Widget.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Widget.java
index d821a23c86..8c0d9c3fc5 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Widget.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Widget.java
@@ -16,6 +16,8 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.util.function.BooleanSupplier;
+
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.GC;
@@ -207,6 +209,21 @@ protected String getClassName() {
return clazz;
}
+protected void processEvents(int timeoutMs, BooleanSupplier condition) throws InterruptedException {
+ if (condition == null) {
+ condition = () -> false;
+ }
+ long targetTimestamp = System.currentTimeMillis() + timeoutMs;
+ while (!condition.getAsBoolean()) {
+ if (!shell.getDisplay().readAndDispatch()) {
+ if (System.currentTimeMillis() < targetTimestamp) {
+ Thread.sleep(50);
+ } else {
+ return;
+ }
+ }
+ }
+}
}

Back to the top