Skip to content

Commit

Permalink
Corrected TextLayout to produce right number of lines when '\r\n'
Browse files Browse the repository at this point in the history
sequence comes. Updated review comments.

Fixes #184
  • Loading branch information
deepika-u committed Sep 30, 2024
1 parent ebe6ec4 commit 8b4764a
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,62 @@ public void test_setStyle() {
assertNull(layout.getStyle(4));
assertNull(layout.getStyle(5));
layout.dispose();

layout = new TextLayout (display);
layout.setText("\rabc\ndef\r\rghi\n\njkl\r\nmno\r\n\r\npqr\r");
layout.setStyle(s1, 0, 5);//abcd
assertEquals(s1, layout.getStyle(0));
assertEquals(s1, layout.getStyle(1));
assertEquals(s1, layout.getStyle(2));
assertEquals(s1, layout.getStyle(3));
assertEquals(s1, layout.getStyle(4));
assertEquals(s1, layout.getStyle(5));

layout.setStyle (s2, 7, 10);//fg
assertEquals(s2, layout.getStyle(7));
assertEquals(s2, layout.getStyle(8));
assertEquals(s2, layout.getStyle(9));
assertEquals(s2, layout.getStyle(10));

layout.setStyle (s3, 11, 18);//hijkl
assertEquals(s3, layout.getStyle(12));
assertEquals(s3, layout.getStyle(13));
assertEquals(s3, layout.getStyle(14));
assertEquals(s3, layout.getStyle(15));

layout.setStyle (s4, 19, 24);//mno
assertEquals(s4, layout.getStyle(19));
assertEquals(s4, layout.getStyle(20));
assertEquals(s4, layout.getStyle(19));
assertEquals(s4, layout.getStyle(22));
assertEquals(s4, layout.getStyle(23));
assertEquals(s4, layout.getStyle(24));

layout.setStyle (null, 0, 3);//abc
assertNull(layout.getStyle(0));

layout.setStyle(s1, 0, 9);//abcdef
assertEquals(s1, layout.getStyle(8));

layout.setStyle (s2, 1, 24);//abcdefghijklmno
assertEquals(s2, layout.getStyle(7));
assertEquals(s2, layout.getStyle(8));
assertEquals(s2, layout.getStyle(14));
assertEquals(s2, layout.getStyle(18));
assertEquals(s2, layout.getStyle(22));
assertEquals(s2, layout.getStyle(23));
assertEquals(s2, layout.getStyle(24));

layout.setStyle (s3, 0, 30);//abcdefghijklmnopqr
assertEquals(s3, layout.getStyle(0));
assertEquals(s3, layout.getStyle(1));
assertEquals(s3, layout.getStyle(30));

layout.setStyle (s4, 1, 30);//abcdefghijklmnopqr
assertEquals(s4, layout.getStyle(1));
assertEquals(s4, layout.getStyle(29));
assertEquals(s4, layout.getStyle(30));
layout.dispose();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
}

0 comments on commit 8b4764a

Please sign in to comment.