Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Clipping if only one character text overflows #99146

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

Merged
merged 2 commits into from
Apr 14, 2022

Conversation

xu-baolin
Copy link
Member

Fixes #99140

@flutter-dashboard flutter-dashboard bot added a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. labels Feb 25, 2022
@xu-baolin xu-baolin requested a review from goderbauer February 25, 2022 10:27
@@ -644,7 +650,7 @@ class RenderParagraph extends RenderBox
size = constraints.constrain(textSize);

final bool didOverflowHeight = size.height < textSize.height || textDidExceedMaxLines;
final bool didOverflowWidth = size.width < textSize.width;
final bool didOverflowWidth = size.width < textSize.width || size.width < _textPainter.longestLine;
Copy link
Member

Choose a reason for hiding this comment

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

Why would _textPainter.longestLine ever be smaller than textSize.width (which is _textPainter.size,width) for a one char long text? That seems odd. Is there a bug in how textPainter calculates its actual width?

Copy link
Member

Choose a reason for hiding this comment

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

We also have TextWidthBasis which essentially changed _textPainter.size.width to be _textPainter.longestLine. I am not too familiar with that setting, though.

/cc @justinmc who added it a while back.

Copy link
Member Author

Choose a reason for hiding this comment

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

Why would _textPainter.longestLine ever be smaller than textSize.width (which is _textPainter.size,width) for a one char long text? That seems odd. Is there a bug in how textPainter calculates its actual width?

The textPainter.size.width always returns the layout constraints.width, this should be the implementation of the engine layer. @LongCatIsLooong may know the details.

Copy link
Contributor

Choose a reason for hiding this comment

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

_textPainter.longestLine is the width of the longest line of actual text. _textPainter.width is either the same thing or the constraints width depending on TextWidthBasis (code) as you guys noted.

So it's possible and even common for _textPainter.longestLine to be shorter than _textPainter.width, for example:

Screen Shot 2022-03-22 at 9 23 40 AM

Here _textPainter.longestLine is just the width of that single character (a few pixels), while _textPainter.width is the width of the green Container (100px).

So the condition in the code here (size.width < _textPainter.longestLine) makes sense to me. That will be true when the available space is less wide than a single character.

Copy link
Contributor

Choose a reason for hiding this comment

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

PS Sorry it took me so long to respond here! I'm bad with my notifications recently.

@xu-baolin xu-baolin requested a review from justinmc March 1, 2022 09:01
Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

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

LGTM 👍

Just a nit about an assert. The discussion around the width conditional seems ok to me.

@@ -644,7 +650,7 @@ class RenderParagraph extends RenderBox
size = constraints.constrain(textSize);

final bool didOverflowHeight = size.height < textSize.height || textDidExceedMaxLines;
final bool didOverflowWidth = size.width < textSize.width;
final bool didOverflowWidth = size.width < textSize.width || size.width < _textPainter.longestLine;
Copy link
Contributor

Choose a reason for hiding this comment

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

_textPainter.longestLine is the width of the longest line of actual text. _textPainter.width is either the same thing or the constraints width depending on TextWidthBasis (code) as you guys noted.

So it's possible and even common for _textPainter.longestLine to be shorter than _textPainter.width, for example:

Screen Shot 2022-03-22 at 9 23 40 AM

Here _textPainter.longestLine is just the width of that single character (a few pixels), while _textPainter.width is the width of the green Container (100px).

So the condition in the code here (size.width < _textPainter.longestLine) makes sense to me. That will be true when the available space is less wide than a single character.

@@ -644,7 +650,7 @@ class RenderParagraph extends RenderBox
size = constraints.constrain(textSize);

final bool didOverflowHeight = size.height < textSize.height || textDidExceedMaxLines;
final bool didOverflowWidth = size.width < textSize.width;
final bool didOverflowWidth = size.width < textSize.width || size.width < _textPainter.longestLine;
Copy link
Contributor

Choose a reason for hiding this comment

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

PS Sorry it took me so long to respond here! I'm bad with my notifications recently.

@fluttergithubbot
Copy link
Contributor

This pull request is not suitable for automatic merging in its current state.

  • The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label.

@justinmc
Copy link
Contributor

The failed Google tests were a few visual diff tests where the rightmost pixel of some text had a very slight, unnoticeable change in opacity. It's slightly strange that this happened for text that wasn't a single character long, but probably just due to floating point math for the antialiasing. I've set the Google tests to "passing", but we'll have to accept the new reference images after merge.

@xu-baolin
Copy link
Member Author

The failed Google tests were a few visual diff tests where the rightmost pixel of some text had a very slight, unnoticeable change in opacity. It's slightly strange that this happened for text that wasn't a single character long, but probably just due to floating point math for the antialiasing. I've set the Google tests to "passing", but we'll have to accept the new reference images after merge.

Interestingly, if this patch breaks things, it must be that size.width < _textPainter.longestLine is satisfied, and no clipping has occurred before. After clipping, the edges of the characters change slightly. I think this kind of scene is intended, right?

@justinmc
Copy link
Contributor

justinmc commented Mar 30, 2022

I think it might be this: In the case where TextWidthBasis.longestLine is used and the parent's width tightly wraps the text, then size.width and _textPainter.longestLine should be equal. However, due to some floating point error in their calculation, one is very very slightly different, and size.width < _textPainter.longestLine is true. The text gets clipped, and some tiny subpixel change in the rendered text occurs.

Maybe we should try using something like applyFloatingPointHack here and see if it fixes the Google tests? Or maybe we should just consider it correct and say it should be clipped...

If you want to try the floating point hack thing, I can re-run the Google tests and see if it has any effect.

@xu-baolin
Copy link
Member Author

I think it might be this: In the case where TextWidthBasis.longestLine is used and the parent's width tightly wraps the text, then size.width and _textPainter.longestLine should be equal. However, due to some floating point error in their calculation, one is very very slightly different, and size.width < _textPainter.longestLine is true. The text gets clipped, and some tiny subpixel change in the rendered text occurs.

Something's not quite right here, in this scenario, textSize.width is no smaller than _textPainter.longestLine because of applyFloatingPointHack, it is not possible that size.width >= textSize.width but size.width < _textPainter.longestLine

Could you help to file a test to repro the google test? Or just make this breaking intended?

I have no idea make which double value hack to check the test now, or do you have any thoughts?

@xu-baolin
Copy link
Member Author

@justinmc Hey, Could we merge this and accept the new golden file? : )

@fluttergithubbot fluttergithubbot merged commit 08e467d into flutter:master Apr 14, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 14, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Apr 14, 2022
justinmc added a commit that referenced this pull request Apr 18, 2022
justinmc added a commit that referenced this pull request Apr 18, 2022
)

This reverts commit 08e467d (Google test failures after merge).
xu-baolin added a commit that referenced this pull request Apr 19, 2022
godofredoc added a commit that referenced this pull request Apr 23, 2022
) (#102389)

This reverts commit 08e467d (Google test failures after merge).

Co-authored-by: Justin McCandless <[email protected]>
xu-baolin added a commit that referenced this pull request May 18, 2022
justinmc pushed a commit that referenced this pull request Jun 29, 2022
XilaiZhang added a commit to XilaiZhang/flutter that referenced this pull request Jul 1, 2022
XilaiZhang added a commit to XilaiZhang/flutter that referenced this pull request Jul 1, 2022
XilaiZhang added a commit to XilaiZhang/flutter that referenced this pull request Jul 1, 2022
XilaiZhang added a commit that referenced this pull request Jul 1, 2022
XilaiZhang added a commit that referenced this pull request Jul 1, 2022
XilaiZhang added a commit that referenced this pull request Jul 6, 2022
* Revert "Reland "Clipping if only one character text overflows (#99146)" (#102130)"

This reverts commit 3f43d9f.

* Revert "Implement frameData for TestWindow (#105537)"

This reverts commit 21841d7.
camsim99 pushed a commit to camsim99/flutter that referenced this pull request Aug 10, 2022
camsim99 pushed a commit to camsim99/flutter that referenced this pull request Aug 10, 2022
camsim99 pushed a commit to camsim99/flutter that referenced this pull request Aug 10, 2022
…lutter#107168)

* Revert "Reland "Clipping if only one character text overflows (flutter#99146)" (flutter#102130)"

This reverts commit 3f43d9f.

* Revert "Implement frameData for TestWindow (flutter#105537)"

This reverts commit 21841d7.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Text does not clip if only one character text overflows
5 participants