Skip to content

Commit e05f6fc

Browse files
committed
Corrected TextLayout to produce right number of lines when '\r\n'
sequence comes. Added some junit tests as well. Updated getStyle() and setStyle() accordingly. Fixes #184
1 parent 2b675ad commit e05f6fc

File tree

3 files changed

+155
-11
lines changed

3 files changed

+155
-11
lines changed

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

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
*/
4343
public final class TextLayout extends Resource {
4444
Font font;
45-
String text, segmentsText;
45+
String text, segmentsText, originalText;
4646
int lineSpacingInPoints;
4747
int ascent, descent;
4848
int alignment;
@@ -309,7 +309,7 @@ public TextLayout (Device device) {
309309
styles[0] = new StyleItem();
310310
styles[1] = new StyleItem();
311311
stylesCount = 2;
312-
text = ""; //$NON-NLS-1$
312+
text = originalText = ""; //$NON-NLS-1$
313313
long[] ppv = new long[1];
314314
OS.OleInitialize(0);
315315
if (COM.CoCreateInstance(COM.CLSID_CMultiLanguage, 0, COM.CLSCTX_INPROC_SERVER, COM.IID_IMLangFontLink2, ppv) == OS.S_OK) {
@@ -2724,8 +2724,16 @@ private int getScaledVerticalIndent() {
27242724
*/
27252725
public TextStyle getStyle (int offset) {
27262726
checkLayout();
2727-
int length = text.length();
2727+
int length = originalText.length();
27282728
if (!(0 <= offset && offset < length)) SWT.error(SWT.ERROR_INVALID_RANGE);
2729+
int crCount = 0, subStringLength = originalText.subSequence(0, offset+1).length();
2730+
for (int crIndex = 0; crIndex < subStringLength; crIndex++) {
2731+
if (originalText.charAt(crIndex) == '\r') {
2732+
crCount++;
2733+
}
2734+
}
2735+
offset = offset - crCount;
2736+
27292737
for (int i=1; i<stylesCount; i++) {
27302738
if (styles[i].start > offset) {
27312739
return styles[i - 1].style;
@@ -2956,15 +2964,11 @@ StyleItem[] merge (long items, int itemCount) {
29562964
linkBefore = false;
29572965
}
29582966
char ch = segmentsText.charAt(start);
2959-
switch (ch) {
2960-
case '\r':
2961-
case '\n':
2962-
item.lineBreak = true;
2963-
break;
2964-
case '\t':
2965-
item.tab = true;
2966-
break;
2967+
if (ch == '\r' && start + 1 < end) {
2968+
ch = segmentsText.charAt(start + 1);
29672969
}
2970+
item.lineBreak = ch == '\n';
2971+
item.tab = ch == '\t';
29682972
if (itemLimit == -1) {
29692973
nextItemIndex = itemIndex + 1;
29702974
OS.MoveMemory(scriptItem, items + nextItemIndex * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof);
@@ -3455,6 +3459,22 @@ public void setStyle (TextStyle style, int start, int end) {
34553459
int length = text.length();
34563460
if (length == 0) return;
34573461
if (start > end) return;
3462+
3463+
int startCount = 0;
3464+
int endCount = 0;
3465+
for (int crIndex = originalText.indexOf('\r', 0); crIndex >= 0; crIndex = originalText.indexOf('\r', crIndex + 1)) {
3466+
if (crIndex < start) {
3467+
++startCount;
3468+
} else if (crIndex <= end) {
3469+
++endCount;
3470+
} else {
3471+
break;
3472+
}
3473+
}
3474+
endCount = endCount + startCount;
3475+
start -= startCount;
3476+
end -= endCount;
3477+
34583478
start = Math.min(Math.max(0, start), length - 1);
34593479
end = Math.min(Math.max(0, end), length - 1);
34603480
int low = -1;
@@ -3568,6 +3588,8 @@ public void setTabs (int[] tabs) {
35683588
*/
35693589
public void setText (String text) {
35703590
checkLayout();
3591+
this.originalText = text;
3592+
text = text.replace("\r", "");
35713593
if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
35723594
if (text.equals(this.text)) return;
35733595
freeRuns();

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_TextLayout.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,60 @@ public void test_setStyle() {
547547
assertNull(layout.getStyle(4));
548548
assertNull(layout.getStyle(5));
549549
layout.dispose();
550+
551+
layout = new TextLayout (display);
552+
layout.setText("\rabc\ndef\r\rghi\n\njkl\r\nmno\r\n\r\npqr\r");
553+
layout.setStyle(s1, 0, 5);//abcd
554+
layout.setStyle (s2, 7, 10);//fg
555+
layout.setStyle (s3, 11, 18);//hijkl
556+
layout.setStyle (s4, 19, 24);//mno
557+
assertEquals(s1, layout.getStyle(0));
558+
assertEquals(s1, layout.getStyle(1));
559+
assertEquals(s1, layout.getStyle(3));
560+
assertEquals(s1, layout.getStyle(4));
561+
assertEquals(s1, layout.getStyle(5));
562+
563+
assertEquals(s2, layout.getStyle(7));
564+
assertEquals(s2, layout.getStyle(8));
565+
assertEquals(s2, layout.getStyle(9));
566+
assertEquals(s2, layout.getStyle(10));
567+
568+
assertEquals(s3, layout.getStyle(12));
569+
assertEquals(s3, layout.getStyle(13));
570+
assertEquals(s3, layout.getStyle(14));
571+
assertEquals(s3, layout.getStyle(15));
572+
573+
assertEquals(s4, layout.getStyle(19));
574+
assertEquals(s4, layout.getStyle(20));
575+
assertEquals(s4, layout.getStyle(22));
576+
assertEquals(s4, layout.getStyle(23));
577+
assertEquals(s4, layout.getStyle(24));
578+
579+
layout.setStyle (null, 0, 3);//abc
580+
assertNull(layout.getStyle(0));
581+
582+
layout.setStyle(s1, 0, 9);//abcdef
583+
assertEquals(s1, layout.getStyle(8));
584+
585+
layout.setStyle (s2, 1, 24);//abcdefghijklmno
586+
assertEquals(s2, layout.getStyle(7));
587+
assertEquals(s2, layout.getStyle(8));
588+
assertEquals(s2, layout.getStyle(14));
589+
assertEquals(s2, layout.getStyle(18));
590+
assertEquals(s2, layout.getStyle(22));
591+
assertEquals(s2, layout.getStyle(23));
592+
assertEquals(s2, layout.getStyle(24));
593+
594+
layout.setStyle (s3, 0, 30);//abcdefghijklmnopqr
595+
assertEquals(s3, layout.getStyle(0));
596+
assertEquals(s3, layout.getStyle(1));
597+
assertEquals(s3, layout.getStyle(30));
598+
599+
layout.setStyle (s4, 1, 30);//abcdefghijklmnopqr
600+
assertEquals(s4, layout.getStyle(1));
601+
assertEquals(s4, layout.getStyle(29));
602+
assertEquals(s4, layout.getStyle(30));
603+
layout.dispose();
550604
}
551605

552606
@Test
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package org.eclipse.swt.tests.manual;
2+
3+
/*
4+
* TextLayout example snippet: text with underline and strike through
5+
*
6+
* For a list of all SWT example snippets see
7+
* http://www.eclipse.org/swt/snippets/
8+
*
9+
* @since 3.1
10+
*/
11+
import org.eclipse.swt.*;
12+
import org.eclipse.swt.graphics.*;
13+
import org.eclipse.swt.widgets.*;
14+
15+
public class Issue184_CarriageReturnHandled {
16+
17+
private static FontData[] getFontData(Font font, int style) {
18+
FontData[] fontDatas = font.getFontData();
19+
for (FontData fontData : fontDatas) {
20+
fontData.setStyle(style);
21+
}
22+
return fontDatas;
23+
}
24+
25+
public static void main(String[] args) {
26+
Display display = new Display();
27+
final Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.DOUBLE_BUFFERED);
28+
shell.setText("Underline, Strike Out");
29+
String text1 = "\r\nde\nep\rika\r\rudaya\n\ngiri\r";
30+
31+
FontData[] fontData = getFontData(shell.getFont(), SWT.BOLD);
32+
Font font = new Font(shell.getDisplay(), fontData);
33+
34+
FontData[] fontData1 = getFontData(shell.getFont(), SWT.ITALIC | SWT.BOLD);
35+
Font font1 = new Font(shell.getDisplay(), fontData1);
36+
37+
FontData[] fontData2 = getFontData(shell.getFont(), SWT.BOLD);
38+
Font font2 = new Font(shell.getDisplay(), fontData2);
39+
40+
final TextLayout layout = new TextLayout(display);
41+
layout.setText(text1);
42+
43+
TextStyle style1 = new TextStyle(font, null, null);
44+
layout.setStyle(style1, 3, 7); // eep in bold
45+
46+
TextStyle style2 = new TextStyle(font1, null, null);
47+
layout.setStyle(style2, 12, 18); // udaya in bold
48+
49+
TextStyle style3 = new TextStyle(font2, null, null);
50+
layout.setStyle(style3, 21, 24); // iri in bold
51+
52+
int[] offsets = layout.getLineOffsets();
53+
shell.addListener(SWT.Paint, event -> {
54+
Point point = new Point(10, 10);
55+
int width = shell.getClientArea().width - 2 * point.x;
56+
layout.setWidth(width);
57+
layout.draw(event.gc, point.x, point.y);
58+
});
59+
shell.setSize(400, 300);
60+
shell.open();
61+
while (!shell.isDisposed()) {
62+
if (!display.readAndDispatch())
63+
display.sleep();
64+
}
65+
layout.dispose();
66+
display.dispose();
67+
}
68+
}

0 commit comments

Comments
 (0)