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 deepika-u requested a review from niraj-modi as a code owner July 3, 2024 13:01
@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

   383 files  ±0     383 suites  ±0   5m 3s ⏱️ -17s
 4 287 tests +1   4 272 ✅ +1  15 💤 ±0  0 ❌ ±0 
12 153 runs  +3  12 067 ✅ +3  86 💤 ±0  0 ❌ ±0 

Results for commit a3510b6. ± Comparison against base commit 4bf1af8.

♻️ 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 deepika-u force-pushed the fix_for_issue184 branch 2 times, most recently from 79bb600 to 52e92e2 Compare August 6, 2024 06:44
@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.

@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)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@HeikoKlare
As per your suggestion i have added new junit tests with TextLayout#getLineCount() and TextLayout#getBounds().
Since this change is only with respect to windows, i have excluded mac, gtk for the tests to run.

I guess this makes it all complete as we discussed. If i missed out any, please do let me know.

Can you review it and take it forward please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please hold on, let me cross check and update you again.

Copy link
Contributor Author

@deepika-u deepika-u Dec 13, 2024

Choose a reason for hiding this comment

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

Hi @HeikoKlare
Sorry for the confusion caused.
I am successfull in adding only TextLayout#getLineCount() junit. I think we can go ahead with this pr now.

I have tried even TextLayout#getBounds() but had to withdraw as the behavior is not consistent across.
With the sample input taken,

  • On master, getBounds() is returning {0, 0, 30, 220} where width and height are 30, 220 respectively. [junit is failing]
  • On the branch where i committed my changes(fix_for_issue184), getBounds() is returning {0, 0, 43, 140}. [junit is passing]
  • To cross check, i have pulled the pr 1320 to local, getBounds() is returning {0, 0, 43, 140}. [junit is passing]
  • But on the build machine, getBounds() is returning {0, 0, 34, 105}. [junit is failing because it is getting 34 but expecting 43]. -> https://github.com/eclipse-platform/eclipse.platform.swt/actions/runs/12312890737/job/34365830603?pr=1320
    Neither able to understand the reason for the failure(to fix) nor able to replicate the problem locally to debug further.

Can you please check now?

@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.

@deepika-u deepika-u force-pushed the fix_for_issue184 branch 2 times, most recently from c368f7f to 514957c Compare October 25, 2024 11:43
@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.

@deepika-u deepika-u force-pushed the fix_for_issue184 branch 7 times, most recently from 63bcef0 to 1756000 Compare December 13, 2024 10:43
sequence comes. Added some junit tests as well. Updated getStyle() and
setStyle() accordingly. Added failing and success junits again.

Fixes eclipse-platform#184
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