From bb66280ea1fa80c9aba92bcd7ec77b91fb355857 Mon Sep 17 00:00:00 2001 From: "Klare, Heiko" Date: Tue, 31 Mar 2026 10:20:51 +0200 Subject: [PATCH] [Win32] Consider SWT.DRAW_DELIMITER flag when drawing text with GDI+ The GC.drawText() implementation falls back to using GDI instead of GDI+ (even if enabled) in many cases for historic reasons. There were issues with rendering tabs back then. One of the few cases where GDI+ is used is when glyphs that are non existing for GDI are used. In that case, however, the DRAW_DELIMITER flag is not properly considered. The behavior is always as if the flag was enabled, i.e., line delimiters is always drawn even if the flag is not set. This change corrects the behavior of the GDI+ text drawing implementation to consider if the DRAW_DELIMITER flag is not set. In consequence, strings with glyphs that are not supported by GDI are now rendered without line breaks if undesired as per defined flags. Contributes to https://github.com/eclipse-platform/eclipse.platform.swt/issues/3091 --- .../win32/org/eclipse/swt/graphics/GC.java | 3 +++ .../junit/Test_org_eclipse_swt_graphics_GC.java | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java index 06429400a56..fa44dbe351f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java @@ -3037,6 +3037,9 @@ private RectF drawText(long gdipGraphics, char[] buffer, int start, int length, private void drawTextGDIP(long gdipGraphics, String string, int x, int y, int flags, boolean draw, Point size) { boolean needsBounds = !draw || (flags & SWT.DRAW_TRANSPARENT) == 0; char[] buffer; + if ((flags & SWT.DRAW_DELIMITER) == 0) { + string = string.replaceAll("[\\r\\n]+", ""); + } int length = string.length(); if (length != 0) { buffer = string.toCharArray(); diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java index 95965f72e96..e01c9cdecc4 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java @@ -954,6 +954,18 @@ public void test_textExtentLjava_lang_StringI() { assertEquals(SWT.ERROR_GRAPHIC_DISPOSED, e.code); } +@Test +public void test_textExtentLjava_lang_StringI_disabledLineDelimiter() { + gc.setAdvanced(false); + Point ptWithoutAdvanced = gc.textExtent("abc\u4E2D" + System.lineSeparator() + "def", 0); + gc.setAdvanced(true); + Point ptWithAdvanced = gc.textExtent("abc\u4E2D" + System.lineSeparator() + "def", 0); + // Due to slightly different rendering, size must not be identical but similar in advanced/non-advanced mode + assertTrue(Math.abs(ptWithAdvanced.x - ptWithoutAdvanced.x) <= 2); + assertTrue(Math.abs(ptWithAdvanced.y - ptWithoutAdvanced.y) <= 2); + gc.dispose(); +} + @Test public void test_toString() { String s = gc.toString();