-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Fix issue with OverhangLeading #18438
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
Conversation
MinTextWidth is the minimal width required to draw a TextLayout without needing to wrap or trim a line. Including the whitespace here is wrong. |
You can test this PR using the following package version. |
This is really what the previous code was doing. But we couldn't see it because of the bounds: _metrics.MinTextWidth = Math.Max(_metrics.MinTextWidth, currentLine.Bounds.Width);
_metrics.MinTextWidth = Math.Max(_metrics.MinTextWidth, currentLine.InkBounds.Width); And then Avalonia/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs Lines 1395 to 1411 in 7087595
So, if this is incorrect, the previous code was incorrect as well. |
Yes, as mentioned, the metrics were also incorrect in the previous version. We can include the trailing whitespace for MinTextWidth. That is fine. But we need to add the OverhangLeading to it. If some glyphs are overhanging at the start, the value of MinTextWidth will be wrong. That is the reason why I wanted to change the implementation to only use the actual bounds. But this broke other things. |
Ok, then we need a test for this. Do you have an example text layout that I could add to this PR regarding |
https://learn.microsoft.com/en-us/windows/win32/intl/uniscribe-glossary This shows what overhang leading and trailing should be. In the end MinTextWidth is the sum of OverhangLeading + Width + OverhangTrailing but if we want to include trailing whitespace we need to change it to OverhangLeading + Math.Max(Width + OverhangTrailing, WidthIncludingTrailingWhitespace) |
Thanks, I have a repro with f italic, so we can work from there. |
https://fonts.google.com/specimen/Source+Serif+4 I have used SourceSerif4_36pt-Italic.ttf This should show up leading and trailing overhang |
…ing same textWidth
…r the OverhangLeading Add tests for OverhangLeading and OverhangTrailing
So the commit 7813c96 is reverting #16601 because this previous PR was discarding entirely the OverhangLeading. Causing issues later in For the commit e5dca61, I discovered that the measuring code was different between Overall, considering that text rendering is really tricky, I would really advice to not land a code fix without a unit test. Even if unit tests can test wrong things and that's "ok", we can at least better evaluate the impact of a code change in such critical code path. I believe also that the existing code regarding text rendering is missing lots of unit tests. In addition to the unit tests added in this PR, I have verified that |
I have made a revert in 3979c9f to make |
Hey, there is actually a comparison image test |
Thank you for looking into this. You are right that the text processing part of Avalonia needs better unit test coverage. This is something I want to improve. These kinds of issues clearly show that I did not do a great job in that area. |
I think we need a unit test for monospace font alignment #16601
|
It is possible that the layout slightly changed so the test image is no longer valid |
I'm not sure, looking at it, the previous image looked more correct. I'm investigating negative and positive hang, because before we were |
Ok, I hope I'm close to fix the different problems. I have now Direct2D backend to fix as well. |
Latest fixes are trying to address remaining issues. I believe the rendering should be ok for Skia. For Direct2D, it has fixed issues (so it's closer to Skia) but it is also introducing slight shift that I haven't figured out (the metrics from Harfbuzz are different than from Skia for the same font). Also the handling of the position of the bounding box for the glyph run is not perfect. I have added tests for OverhandLeading and mono fonts for both Skia and Direct2D. But yeah, it's not perfect - and it is starting to take too much time on my side 😅 (I'm no longer evaluating/using Avalonia these days) |
Y we need a test that ensures overhang values are valid for multi line text layouts where lines of different length are positioned at the center. Current metrics calculation might only work with left and right alignment. I really appreciate you work. Let me know if you need assistance. |
Good catch, yes, I can see that alignment is not respected. |
You can test this PR using the following package version. |
Ok, so after testing multilines, I have started to update the code to more "properly" handle it. But I think that there is a fundamental problem according to overhang leading/trailing and how they need to be processed in Avalonia. For example, I have corrected the calculation and the rendering so that it renders properly: Now, if you use a similar text in HTML/CSS you will get more something like this: Notice that the overhang leading/trailing is not part of the bounding box. Also the alignment (center) doesn't take into account the overhang leading/trailing in HTML/CSS. While in Avalonia, it is - well because I have normalized around this rule in this PR - so that the total width for the measure is:
Which is not what HTML/CSS are doing. The problem of including So, I'm asking if when there is a negative OverhangLeading, we should accept that it goes outside of the box like HTML/CSS? I don't know what is going to be the impact of that change, but it feels more correct. It looks like you need to add some padding to mitigate this, and this is expected. |
Ok, after testing WPF, this is what we get (couldn't get it working with the same font, so it's Arial): ![]() So, we can see that the behavior is similar to what I propose, which would be a departure from the current behavior, but probably more expected. Probably need additional vetting beyond @Gillibald, thoughts? |
We should follow the behavior of other well adapted technologies. And as you said not doing so causes other issues |
… measuring and remove clip by default. But it requires further support with NeedsClipBounds
The last commit 900add1 has a primary support for better TextBlock rendering but is incomplete (some tests are failing). The reason is that it requires quite more work to complete the fix. 😞 Unfortunately, the logic is not that simple, because WPF does trigger a clip when e.g. a user specified Width is specified (and other conditions). Basically, they have the concept of And is then used in It will basically require replicating such behavior, and while it is doable, it is non-trivial. Unfortunately, I have spent too much time on this, and I can't work on that PR anymore (I'm not a user of Avalonia currently). So, my apologies, I will have to leave this PR as-is and I will let someone from the Avalon Team or from the community to continue from there. Hope you understand. 🙏 |
Thank you for your contribution. I will take over from here. I appreciate your work. |
Keep ClipToBounds=true default for TextBlock
You can test this PR using the following package version. |
You can test this PR using the following package version. |
* Fix issue with MinTextWidth (Fixes #18372) * Make sure that MeasureOverride for TextPresenter and TextBlock are using same textWidth * Revert #16601 that is introducing an invalid calculation for the OverhangLeading Add tests for OverhangLeading and OverhangTrailing * Revert MinTextWidth * Fix tests to not rely on fixed values * Fix remaining issues * Fix comment in Direct2D1 GlyphRunImpl.cs * Fix Direct2D1 rendering * Fix gold images * Restore TextLineImpl * Update gold image * Restore Math.Max on OverhangLeading and Trailing * Adopt similar behavior to WPF: don't use OverhangLeading/Trailing for measuring and remove clip by default. But it requires further support with NeedsClipBounds * Remove MinTextWidth Keep ClipToBounds=true default for TextBlock * Revert change --------- Co-authored-by: Benedikt Stebner <[email protected]> #Conflicts: # src/Avalonia.Controls/TextBlock.cs # tests/Avalonia.Controls.UnitTests/TextBlockTests.cs
* Fix issue with MinTextWidth (Fixes #18372) * Make sure that MeasureOverride for TextPresenter and TextBlock are using same textWidth * Revert #16601 that is introducing an invalid calculation for the OverhangLeading Add tests for OverhangLeading and OverhangTrailing * Revert MinTextWidth * Fix tests to not rely on fixed values * Fix remaining issues * Fix comment in Direct2D1 GlyphRunImpl.cs * Fix Direct2D1 rendering * Fix gold images * Restore TextLineImpl * Update gold image * Restore Math.Max on OverhangLeading and Trailing * Adopt similar behavior to WPF: don't use OverhangLeading/Trailing for measuring and remove clip by default. But it requires further support with NeedsClipBounds * Remove MinTextWidth Keep ClipToBounds=true default for TextBlock * Revert change --------- Co-authored-by: Benedikt Stebner <[email protected]>
What does the pull request do?
Fixes an issue from previous PRs #16601 and #18310 that changed the behavior of the calculation of
OverhangLeading
.What is the current behavior?
OverhangLeading
is 0 inTextLayout.UpdateMetrics
.What is the updated/expected behavior with this PR?
OverhangLeading
should be correctly propagated fromGlypRunImpl
toTextLayout.UpdateMetrics
.How was the solution implemented (if it's not obvious)?
In the PR.
Checklist
Breaking changes
None
Obsoletions / Deprecations
None
Fixed issues
Fixes #18372