Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Corrected TextLayout to produce right number of lines when '\r\n' sequence comes. #1320

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

deepika-u
Copy link
Contributor

Corrected TextLayout to produce right number of lines when '\r\n' sequence comes.

Fixes #184

@sravanlakkimsetti
@niraj-modi
@merks
Can one of you review this fix please.

@deepika-u
Copy link
Contributor Author

Anyone testing this pr can use the below snippet.
simple test case is with text1.
complex test case is with text2.

package org.eclipse.swt.bugs4;

/*
 * 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 {

	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 text = "Here is 1.\r\n\r\nsome text that is 2.\r\nunderlined or 3.\rstruck out or 4.\nboth.";
		String text1 = "0123456789\r\n\r\n0123456789\r\n0123456789\r0123456789\n0123456789";
		String text2 = "\r\n0123456789\r\n\r\n01\r\n456789\r\n0123456789\r0123456789\n0123456789";

		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);
		layout.setText(text2);

		TextStyle style1 = new TextStyle(font, null, null);
		//layout.setStyle(style1, 0, 16);
		layout.setStyle(style1, 5, 16);

		TextStyle style2 = new TextStyle(font1, null, null);
		layout.setStyle(style2, 21, 24);

		TextStyle style3 = new TextStyle(font2, null, null);
		layout.setStyle(style3, 27, 31);
		//layout.setStyle(style3, 25, 29);

		int[] offsets = layout.getLineOffsets();
		System.out.println(offsets.length);
		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();
	}
}

Copy link
Contributor

github-actions bot commented Jul 3, 2024

Test Results

   483 files  ±0     483 suites  ±0   8m 28s ⏱️ +15s
 4 095 tests ±0   4 085 ✅ ±0   7 💤 ±0  3 ❌ ±0 
16 173 runs  ±0  16 080 ✅ ±0  90 💤 ±0  3 ❌ ±0 

For more details on these failures, see this check.

Results for commit 514957c. ± Comparison against base commit fdb2fa5.

♻️ This comment has been updated with latest results.

@@ -2952,8 +2952,11 @@ StyleItem[] merge (long items, int itemCount) {
linkBefore = false;
}
char ch = segmentsText.charAt(start);
if(ch == '\r') {
ch = segmentsText.charAt(start+1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is a boundcheck required here maybe? Just assume a single \r at end of line would read bejond the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes agree

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am checking on further if the string in full is just a "\r", what needs to be done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you agree to my changes, i can squash the commits.

@deepika-u deepika-u force-pushed the fix_for_issue184 branch 2 times, most recently from 89bd04a to aae8e16 Compare July 9, 2024 04:48
@deepika-u
Copy link
Contributor Author

@niraj-modi @merks
Can you also please review this?

@laeubi : Do you have any additional comments on this fix? or are we good to merge this?

Copy link
Contributor

@merks merks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have time for a more detailed for the next days. But some comments generally follow a for or if keyword with a space.

String text, segmentsText;
int lineSpacingInPoints;
String text, segmentsText, originalText;
int lineSpacingInPoints, previousCountNextLine = 0, previousEnd = -1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initializing to 0 is pointless and actually generates more byte code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated initialization as part of constructor.

case '\t':
item.tab = true;
break;
if(ch == '\r' && (start+1 < end)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formatting of if( is poor. The () around the < condition is redundant and odd that it's not used for the == test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corrected it.

loop = previousEnd+1;
else
loop = previousEnd;
for(int i = loop; i < end; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here for( is not nice format.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corrected it.

@deepika-u deepika-u force-pushed the fix_for_issue184 branch 3 times, most recently from 0740eef to 26a2d76 Compare July 15, 2024 07:57
this.originalText = text;
String[] strings = text.split("\r");
text = "";
for(int i = 0; i < strings.length; i++)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formatting of this for loop could also be improved.

@deepika-u deepika-u force-pushed the fix_for_issue184 branch 2 times, most recently from e60de1d to 223b000 Compare July 16, 2024 06:15
this.originalText = text;
String[] strings = text.split("\r");
text = "";
for (int i = 0; i < strings.length; i++)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be done using a map reduction. Anyway, please add braces to the for loop

reference

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's this a complicated and poorly performance way of doing test.replace("\r", "")?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@merks yes, looks like it. Your approach is the best to me!

Copy link
Contributor Author

@deepika-u deepika-u Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me test and update here back.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @merks for your feedback, after updating this i found a better way of fixing the issue. So new change is updated, you may please review now.

else
loop = previousEnd;
for (int i = loop; i < end; i++) {
if (originalText.charAt(i) == '\r' && originalText.charAt(i+1) =='\n')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is i + 1 necessarily < end?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me check it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are correct, when string ends with \r, it is resulting OOB exception. So corrected it.

@deepika-u
Copy link
Contributor Author

@niraj-modi
Can you also please review this? so that it can be merged before M3.

@merks @laeubi @Wittmaxi : Do you have any additional comments on this fix? or are we good to merge this?

@deepika-u deepika-u force-pushed the fix_for_issue184 branch 3 times, most recently from 2e2b765 to 4d7e7e8 Compare August 9, 2024 06:18
@deepika-u
Copy link
Contributor Author

@merks @laeubi @Wittmaxi
Can one of you review the changes please.

@merks
Copy link
Contributor

merks commented Aug 9, 2024

@deepika-u

Could you please squash this to a single commit?

@deepika-u
Copy link
Contributor Author

deepika-u commented Aug 12, 2024

@deepika-u

Could you please squash this to a single commit?

Done.

Font font2 = new Font(shell.getDisplay(), fontData2);

final TextLayout layout = new TextLayout(display);
//layout.setText(text);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but why is there this much commented-out code?

Copy link
Contributor Author

@deepika-u deepika-u Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are the various test cases tried and the respective outputs against them, if required anyone can rerun depending on their need so i have retained in commented section. The possible combinations i can think of with \r and \n are put in the string, out of which 3 test cases are showcased in this snippet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but why is there this much commented-out code?

Apart from the manual test case, the fix is reviewed and approved? do you mean that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deepika please remove the comment code and update the PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, looks good now :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks alot for the review.

@deepika-u
Copy link
Contributor Author

deepika-u commented Sep 4, 2024

@merks : All review suggestions are implemented, can you take a look please? if it can be approved.

@merks
Copy link
Contributor

merks commented Sep 4, 2024

Wouldn't it be better for there to be actual tests that run with every build?

@deepika-u
Copy link
Contributor Author

Wouldn't it be better for there to be actual tests that run with every build?

Apart from this manual test(tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Issue184_CarriageReturnHandled.java) which is already added, please let me know what else needs to be done, so that this can be taken forward. Can you point me to a sample kind of instance? to refer.

@deepika-u deepika-u force-pushed the fix_for_issue184 branch 2 times, most recently from 8b4764a to 63a46d7 Compare October 7, 2024 11:16
@deepika-u
Copy link
Contributor Author

@merks : I have added some junits for the fix. Can you check now please?

@BeckerWdf
Copy link
Contributor

is this only an issue on Windows? May the macOS and Linux implementation have the same issue?

@deepika-u
Copy link
Contributor Author

is this only an issue on Windows? May the macOS and Linux implementation have the same issue?

@BeckerWdf : Atleast from the parent #184 => this is marked as only windows issue and i have implemented the fix only for windows. In the past i remember vaguely but when tested with mac, the behavior on mac Vs behavior on windows (before the fix) were different. So took it up as windows specific issue.

@BeckerWdf
Copy link
Contributor

is this only an issue on Windows? May the macOS and Linux implementation have the same issue?

@BeckerWdf : Atleast from the parent #184 => this is marked as only windows issue and i have implemented the fix only for windows. In the past i remember vaguely but when tested with mac, the behavior on mac Vs behavior on windows (before the fix) were different. So took it up as windows specific issue.

Thanks.

@deepika-u
Copy link
Contributor Author

deepika-u commented Oct 14, 2024

@merks :
I have added some junits for this fix. Can you make some time to move this forward? I know you are super busy these days but yeah please need your inputs on this.

@deepika-u
Copy link
Contributor Author

@merks
We have crossed the M2 milestone for 4.34 and entered into M3 already. Can you find some time to check on this please so that atleast for this release, its available for customers.

Copy link
Contributor

@merks merks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks okay to me.

That being said, I would prefer that at least one other person deeply involved in SWT reviews this too.

@merks
Copy link
Contributor

merks commented Oct 21, 2024

@HeikoKlare

Do you know who else might be good to review this?

@deepika-u
Copy link
Contributor Author

@sratz @jukzi @laeubi @HeikoKlare
Can one of you review this please.
@merks thanks alot for your time.
But he feels if anyone else also reviews it would be great. - Thanks alot in advance, hoping this would go in 4.34.

Copy link
Contributor

@HeikoKlare HeikoKlare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not worked on TextLayout so far. Thus, unfortunately, I cannot say with high confidence whether the overall change is okay. Still, from what I understand, the conceptual change and the code for it looks sound to me. I've tested the proposed change with the snippet in the original issue and it indeed fixes it.

I have remarks regarding the automated and manual test. In particular the automated test does not seem to be an adequate regression test, as the same test succeeds on master, thus it does not seem to cover the addressed issue.

@@ -0,0 +1,68 @@
package org.eclipse.swt.tests.manual;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add missing copyright header

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

TextStyle style3 = new TextStyle(font2, null, null);
layout.setStyle(style3, 21, 24); // iri in bold

int[] offsets = layout.getLineOffsets();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable is unused and thus produces a warning. It should be safe to just delete this line of code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

@@ -547,6 +547,60 @@ public void test_setStyle() {
assertNull(layout.getStyle(4));
assertNull(layout.getStyle(5));
layout.dispose();

layout = new TextLayout (display);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test with these changes succeeds on master, so it's not a regression test for the changes made in this PR. Can you adapt the test so that it serves as a regression test for the addressed issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we have not changed the behavior of the api's. The original behavior of the api's still work the same. We are internally detecting, correcting and passing the corrected content in specific cases only. We dint even add new api's. It is only the look and feel by which you can make out if some extra lines are expected or not expected varies. - is my understanding.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I mistakenly expected the added test to be a regression test for the fix because of #1320 (comment)

Still, this change is no refactoring but affects the behavior of public APIs (e.g., TextLayout#draw(...) behaves differently). I guess that, e.g., also TextLayout#getBounds() now behaves differently, so wouldn't it be possible to have a regression test comparing the bounds of two configurations that should actually result in the bounds but did not do before this change (or vice versa)?

@HeikoKlare
Copy link
Contributor

And one additional remark: since the TextLayout is very essential and we do not seem to have completely confident reviews so far, I am not sure whether we should bring this kind of change in M3. Maybe it makes more sense to bring in the next M1 to have better implicit testing until it is finally released? The issue has been there for quite a long time without higher complains that I am not sure whether the gain outweighs the risk of regression.

sequence comes. Added some junit tests as well. Updated getStyle() and
setStyle() accordingly.

Fixes eclipse-platform#184
@deepika-u
Copy link
Contributor Author

deepika-u commented Oct 25, 2024

And one additional remark: since the TextLayout is very essential and we do not seem to have completely confident reviews so far, I am not sure whether we should bring this kind of change in M3. Maybe it makes more sense to bring in the next M1 to have better implicit testing until it is finally released? The issue has been there for quite a long time without higher complains that I am not sure whether the gain outweighs the risk of regression.

Thanks for your opinion. Since it is already tested now by various people, i feel we are safe to merge this. Considering the M3 deadline is 8th Nov(2 weeks far and not away like 2days or so) and we can give it a try. If something is breaking we'll revert it immediately and rectify to make it to next M1? Atleast this risk we can take to improve SWT - i feel so in particularly such long standing issues when they passed all the stages of fixing, review, successfully verified.
This is a windows specific change and not on common code in particluar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TextLayout Produces Wrong Lines for '\r\n'
8 participants