Skip to content

Commit 6104592

Browse files
deepika-uHeikoKlare
authored andcommitted
Corrected TextLayout to produce right number of lines when '\r\n'
sequence comes. Added some junit tests as well. Updated getStyle() and setStyle() accordingly. Added failing and success junits again. Fixes eclipse-platform#184
1 parent 8845e70 commit 6104592

File tree

3 files changed

+183
-11
lines changed

3 files changed

+183
-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: 81 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
@@ -1219,4 +1273,31 @@ public void test_Bug579335_win32_StyledText_LongLine() {
12191273
font.dispose();
12201274
}
12211275
}
1276+
1277+
@Test
1278+
public void test_getLineCount() {
1279+
// Skipping this test for GTK and Cocoa as this pr #1320 applies only for
1280+
// windows platform.
1281+
// Without pr #1320(master) : Number of lines: 11 (for Cocoa it is : 10)
1282+
// Expected : Number of lines: 7 (for Cocoa it is : 10)
1283+
TextLayout layout = new TextLayout(display);
1284+
try {
1285+
String text = "\rabc\ndef\r\rghi\n\njkl\r\nmno\r\n\r\npqr\r";
1286+
layout.setText(text);
1287+
int lineCount = layout.getLineCount();
1288+
1289+
int expected = 0;
1290+
if (SwtTestUtil.isWindows) {
1291+
expected = 7;
1292+
} else if (SwtTestUtil.isCocoa) {
1293+
expected = 10;
1294+
} else if (SwtTestUtil.isGTK) {
1295+
expected = 11;
1296+
}
1297+
1298+
assertEquals(expected, lineCount);
1299+
} finally {
1300+
layout.dispose();
1301+
}
1302+
}
12221303
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 IBM and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
package org.eclipse.swt.tests.manual;
12+
13+
import org.eclipse.swt.*;
14+
import org.eclipse.swt.graphics.*;
15+
import org.eclipse.swt.widgets.*;
16+
17+
public class Issue184_CarriageReturnHandled {
18+
19+
private static FontData[] getFontData(Font font, int style) {
20+
FontData[] fontDatas = font.getFontData();
21+
for (FontData fontData : fontDatas) {
22+
fontData.setStyle(style);
23+
}
24+
return fontDatas;
25+
}
26+
27+
public static void main(String[] args) {
28+
Display display = new Display();
29+
final Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.DOUBLE_BUFFERED);
30+
shell.setText("Underline, Strike Out");
31+
String text1 = "\r\nde\nep\rika\r\rudaya\n\ngiri\r";
32+
33+
FontData[] fontData = getFontData(shell.getFont(), SWT.BOLD);
34+
Font font = new Font(shell.getDisplay(), fontData);
35+
36+
FontData[] fontData1 = getFontData(shell.getFont(), SWT.ITALIC | SWT.BOLD);
37+
Font font1 = new Font(shell.getDisplay(), fontData1);
38+
39+
FontData[] fontData2 = getFontData(shell.getFont(), SWT.BOLD);
40+
Font font2 = new Font(shell.getDisplay(), fontData2);
41+
42+
final TextLayout layout = new TextLayout(display);
43+
layout.setText(text1);
44+
45+
TextStyle style1 = new TextStyle(font, null, null);
46+
layout.setStyle(style1, 3, 7); // eep in bold
47+
48+
TextStyle style2 = new TextStyle(font1, null, null);
49+
layout.setStyle(style2, 12, 18); // udaya in bold
50+
51+
TextStyle style3 = new TextStyle(font2, null, null);
52+
layout.setStyle(style3, 21, 24); // iri in bold
53+
54+
shell.addListener(SWT.Paint, event -> {
55+
Point point = new Point(10, 10);
56+
int width = shell.getClientArea().width - 2 * point.x;
57+
layout.setWidth(width);
58+
layout.draw(event.gc, point.x, point.y);
59+
});
60+
shell.setSize(400, 300);
61+
shell.open();
62+
while (!shell.isDisposed()) {
63+
if (!display.readAndDispatch())
64+
display.sleep();
65+
}
66+
layout.dispose();
67+
display.dispose();
68+
}
69+
}

0 commit comments

Comments
 (0)