From 3f1ae4aad1cff234873be685319ed34d65a56eb9 Mon Sep 17 00:00:00 2001 From: Deepika Udayagiri Date: Mon, 12 Aug 2024 14:24:06 +0530 Subject: [PATCH] Corrected TextLayout to produce right number of lines when '\r\n' sequence comes. Updated review comments. Fixes #184 --- .../org/eclipse/swt/graphics/TextLayout.java | 34 +++++++--- .../Issue184_CarriageReturnHandled.java | 68 +++++++++++++++++++ 2 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Issue184_CarriageReturnHandled.java diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java index 4ec71e5988b..b7e8663a011 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java @@ -42,7 +42,7 @@ */ public final class TextLayout extends Resource { Font font; - String text, segmentsText; + String text, segmentsText, originalText; int lineSpacingInPoints; int ascent, descent; int alignment; @@ -309,7 +309,7 @@ public TextLayout (Device device) { styles[0] = new StyleItem(); styles[1] = new StyleItem(); stylesCount = 2; - text = ""; //$NON-NLS-1$ + text = originalText = ""; //$NON-NLS-1$ long[] ppv = new long[1]; OS.OleInitialize(0); if (COM.CoCreateInstance(COM.CLSID_CMultiLanguage, 0, COM.CLSCTX_INPROC_SERVER, COM.IID_IMLangFontLink2, ppv) == OS.S_OK) { @@ -2956,15 +2956,11 @@ StyleItem[] merge (long items, int itemCount) { linkBefore = false; } char ch = segmentsText.charAt(start); - switch (ch) { - case '\r': - case '\n': - item.lineBreak = true; - break; - case '\t': - item.tab = true; - break; + if (ch == '\r' && start + 1 < end) { + ch = segmentsText.charAt(start + 1); } + item.lineBreak = ch == '\n'; + item.tab = ch == '\t'; if (itemLimit == -1) { nextItemIndex = itemIndex + 1; OS.MoveMemory(scriptItem, items + nextItemIndex * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof); @@ -3455,6 +3451,22 @@ public void setStyle (TextStyle style, int start, int end) { int length = text.length(); if (length == 0) return; if (start > end) return; + + int startCount = 0; + int endCount = 0; + for (int crIndex = originalText.indexOf('\r', 0); crIndex >= 0; crIndex = originalText.indexOf('\r', crIndex + 1)) { + if (crIndex < start) { + ++startCount; + } else if (crIndex <= end) { + ++endCount; + } else { + break; + } + } + endCount = endCount + startCount; + start -= startCount; + end -= endCount; + start = Math.min(Math.max(0, start), length - 1); end = Math.min(Math.max(0, end), length - 1); int low = -1; @@ -3568,6 +3580,8 @@ public void setTabs (int[] tabs) { */ public void setText (String text) { checkLayout(); + this.originalText = text; + text = text.replace("\r", ""); if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); if (text.equals(this.text)) return; freeRuns(); diff --git a/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Issue184_CarriageReturnHandled.java b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Issue184_CarriageReturnHandled.java new file mode 100644 index 00000000000..6380fd8d3a1 --- /dev/null +++ b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Issue184_CarriageReturnHandled.java @@ -0,0 +1,68 @@ +package org.eclipse.swt.tests.manual; + +/* + * TextLayout example snippet: text with underline and strike through + * + * For a list of all SWT example snippets see + * http://www.eclipse.org/swt/snippets/ + * + * @since 3.1 + */ +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.widgets.*; + +public class Issue184_CarriageReturnHandled { + + private static FontData[] getFontData(Font font, int style) { + FontData[] fontDatas = font.getFontData(); + for (FontData fontData : fontDatas) { + fontData.setStyle(style); + } + return fontDatas; + } + + public static void main(String[] args) { + Display display = new Display(); + final Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.DOUBLE_BUFFERED); + shell.setText("Underline, Strike Out"); + String text1 = "\r\nde\nep\rika\r\rudaya\n\ngiri\r"; + + FontData[] fontData = getFontData(shell.getFont(), SWT.BOLD); + Font font = new Font(shell.getDisplay(), fontData); + + FontData[] fontData1 = getFontData(shell.getFont(), SWT.ITALIC | SWT.BOLD); + Font font1 = new Font(shell.getDisplay(), fontData1); + + FontData[] fontData2 = getFontData(shell.getFont(), SWT.BOLD); + Font font2 = new Font(shell.getDisplay(), fontData2); + + final TextLayout layout = new TextLayout(display); + layout.setText(text1); + + TextStyle style1 = new TextStyle(font, null, null); + layout.setStyle(style1, 3, 7); // eep in bold + + TextStyle style2 = new TextStyle(font1, null, null); + layout.setStyle(style2, 12, 18); // udaya in bold + + TextStyle style3 = new TextStyle(font2, null, null); + layout.setStyle(style3, 21, 24); // iri in bold + + int[] offsets = layout.getLineOffsets(); + shell.addListener(SWT.Paint, event -> { + Point point = new Point(10, 10); + int width = shell.getClientArea().width - 2 * point.x; + layout.setWidth(width); + layout.draw(event.gc, point.x, point.y); + }); + shell.setSize(400, 300); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + layout.dispose(); + display.dispose(); + } +}