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 253411851f..890b681fb2 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 @@ -3040,6 +3040,10 @@ private void drawTextGDIP(long gdipGraphics, String string, int x, int y, int fl char[] buffer; if ((flags & SWT.DRAW_DELIMITER) == 0) { string = string.replaceAll("[\\r\\n]+", ""); + } else { + // Graphics_DrawString only recognises \n as a line break, not bare \r. + // Normalise \r\n -> \n first, then lone \r -> \n (order matters). + string = string.replace("\r\n", "\n").replace("\r", "\n"); } int length = string.length(); if (length != 0) { 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 8d5eafc830..78b385d651 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 @@ -968,6 +968,45 @@ public void test_textExtentLjava_lang_StringI_disabledLineDelimiter() { gc.dispose(); } +/** + * @see Issue 3091 + */ +@Test +public void test_textExtentLjava_lang_StringI_lineDelimiterVariants() { + // 中 has no glyph in common Latin fonts; on Win32 this causes useGDIP() to + // return true, routing text through drawTextGDIP() / Graphics_DrawString. + String withLF = "a中\nb"; + String withCR = "a中\rb"; + String withCRLF = "a中\r\nb"; + int flags = SWT.DRAW_DELIMITER; + + gc.setAdvanced(false); + Point lfNonAdv = gc.textExtent(withLF, flags); + Point crNonAdv = gc.textExtent(withCR, flags); + Point crlfNonAdv = gc.textExtent(withCRLF, flags); + + gc.setAdvanced(true); + Point lfAdv = gc.textExtent(withLF, flags); + Point crAdv = gc.textExtent(withCR, flags); + Point crlfAdv = gc.textExtent(withCRLF, flags); + + // All three line-ending types must produce the same text height in non-advanced mode. + assertEquals(lfNonAdv.y, crNonAdv.y, + "Non-advanced: CR must produce the same height as LF with DRAW_DELIMITER"); + assertEquals(lfNonAdv.y, crlfNonAdv.y, + "Non-advanced: CRLF must produce the same height as LF with DRAW_DELIMITER"); + + // Advanced mode must agree with non-advanced within minor rendering tolerance. + // On Win32, \r and \r\n must be normalised to \n before passing to + // Graphics_DrawString, which does not treat bare \r as a line delimiter. + assertTrue(Math.abs(lfAdv.y - lfNonAdv.y) <= 2, + "LF: advanced height must match non-advanced"); + assertTrue(Math.abs(crAdv.y - crNonAdv.y) <= 2, + "CR: advanced height must match non-advanced"); + assertTrue(Math.abs(crlfAdv.y - crlfNonAdv.y) <= 2, + "CRLF: advanced height must match non-advanced"); +} + @Test public void test_toString() { String s = gc.toString();