Skip to content

Commit 20e6c08

Browse files
committed
[Win32] Disable obsolete fallback for drawing text without GDI+
A check in GC.drawText() makes the implementation fall back to the text rendering based on glyphs and their positions calculated by GDI even when GDI+ is used in all cases except when it contains specific characters that GDI cannot handle. This was necessary more than a decade ago because specific Chinese characters were not properly rendered by GDI+. But this is quite non-intuitive as in case GDI+/advance mode is enabled the consumer will usually expected GDI+ to be used for rendering. In addition, the problematic scenario from back then works fine now. This change thus adapts the GC.drawText() implementation to use plain GDI+ whenever it is enabled. The fallback code is preserved but only executed if a newly introduced system property is enabled. This allows to switch back to previous behavior in case unexpected regressions are found. The property is to be removed in a future release in case no regressions are found. May fix #3091
1 parent 5f5ff9e commit 20e6c08

File tree

2 files changed

+47
-2
lines changed
  • bundles/org.eclipse.swt

2 files changed

+47
-2
lines changed

bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/GCWin32Tests.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.eclipse.swt.graphics;
1515

1616
import static org.junit.Assert.assertEquals;
17+
import static org.junit.jupiter.api.Assertions.assertTrue;
1718

1819
import java.util.concurrent.*;
1920

@@ -60,6 +61,37 @@ public void drawnElementsShouldScaleUpToTheRightZoomLevel() {
6061
GC gc = GC.win32_new(shell, new GCData());
6162
gc.getGCData().nativeZoom = zoom * scalingFactor;
6263
gc.getGCData().lineWidth = 10;
63-
assertEquals("Drawn elements should scale to the right value", gc.getGCData().lineWidth, gc.getLineWidth() * scalingFactor, 0);
64+
assertEquals("Drawn elements should scale to the right value", gc.getGCData().lineWidth,
65+
gc.getLineWidth() * scalingFactor, 0);
66+
}
67+
68+
/**
69+
* Regression test for https://github.com/eclipse-platform/eclipse.platform.swt/issues/3091
70+
*/
71+
@Test
72+
public void test_drawTextLjava_lang_StringII_advanced_unterlined() {
73+
Display display = Display.getDefault();
74+
FontData defaultFontFata = display.getSystemFont().getFontData()[0];
75+
defaultFontFata.data.lfUnderline = 1;
76+
Font font = new Font(display, defaultFontFata);
77+
Image image = new Image(display, 100, 100);
78+
try {
79+
GC gc = new GC(image);
80+
gc.setFont(font);
81+
gc.setAdvanced(true);
82+
gc.drawText("Hello World", 10, 50);
83+
ImageData imageData = image.getImageData();
84+
boolean anyPixelUnderTextIsNotEmpty = false;
85+
for (int i = 0; i < imageData.width * imageData.height; i++) {
86+
if (imageData.getPixel(i % imageData.width, i / imageData.width) != -1) {
87+
anyPixelUnderTextIsNotEmpty = true;
88+
break;
89+
}
90+
}
91+
assertTrue(anyPixelUnderTextIsNotEmpty);
92+
} finally {
93+
image.dispose();
94+
font.dispose();
95+
}
6496
}
6597
}

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ public final class GC extends Resource {
109109
static final float[] LINE_DASHDOT_ZERO = new float[]{9, 6, 3, 6};
110110
static final float[] LINE_DASHDOTDOT_ZERO = new float[]{9, 3, 3, 3, 3, 3};
111111

112+
private static final String USE_GDI_TEXT_RENDERING_WITH_GDPI = "org.eclipse.swt.internal.win32.useGDITextRenderingWithGDIP";
113+
112114
/**
113115
* Prevents uninitialized instances from being created outside the package.
114116
*/
@@ -2832,7 +2834,18 @@ private void drawTextInPixels (String string, int x, int y, int flags) {
28322834
OS.SetBkMode(handle, oldBkMode);
28332835
}
28342836

2835-
private boolean useGDIP (long hdc, char[] buffer) {
2837+
private boolean useGDIP(long hdc, char[] buffer) {
2838+
// If the system property is set to true, then GDI text rendering may be used
2839+
// even when GDI+/advanced mode is enabled.
2840+
// The property exists to allow backward compatibility with long standing
2841+
// behavior of using GDI text rendering even when GDI+ was enabled was enforced,
2842+
// introduced because of issues with the GDI+ text rendering a long time ago. In
2843+
// case no regressions occur because of using GDI+ text rendering, this property
2844+
// should be removed and GDI+ text rendering should be used by default when
2845+
// GDI+/advanced mode is enabled.
2846+
if (!Boolean.getBoolean(USE_GDI_TEXT_RENDERING_WITH_GDPI)) {
2847+
return true;
2848+
}
28362849
short[] glyphs = new short[buffer.length];
28372850
OS.GetGlyphIndices(hdc, buffer, buffer.length, glyphs, OS.GGI_MARK_NONEXISTING_GLYPHS);
28382851
for (int i = 0; i < glyphs.length; i++) {

0 commit comments

Comments
 (0)