Skip to content

fix(text): preserve lines at rounded fractional heights - #21834

Merged
MrJul merged 3 commits into
AvaloniaUI:mainfrom
NathanDrake2406:nathan/fix-21786
Jul 24, 2026
Merged

fix(text): preserve lines at rounded fractional heights#21834
MrJul merged 3 commits into
AvaloniaUI:mainfrom
NathanDrake2406:nathan/fix-21786

Conversation

@NathanDrake2406

@NathanDrake2406 NathanDrake2406 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What does the pull request do?

Fixes #21786 by preventing a wrapped TextBlock from omitting its final line when a fractional LineHeight lands exactly on a display-scale rounded height.

What is the current behavior?

At 125% scaling, three 20.8-unit lines round to 62.4 logical units. Floating-point accumulation can evaluate the total as marginally above 62.4, so TextLayout treats the last line as exceeding MaxHeight and omits it.

What is the updated/expected behavior with this PR?

All three wrapped lines remain visible when the rounded layout height exactly fits them. Real max-height overflow continues to clip or trim text.

Validation:

  • Added a regression test for a 125%-scaled, wrapped TextBlock with LineHeight=20.8. The test fails before the fix with 2 lines instead of 3.
  • dotnet run --project tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj -- --filter-class "Avalonia.Controls.UnitTests.TextBlockTests"
    • Passed: 31 tests
  • dotnet run --project tests/Avalonia.Skia.UnitTests/Avalonia.Skia.UnitTests.csproj -- --filter-class "Avalonia.Skia.UnitTests.Media.TextFormatting.TextLayoutTests"
    • Passed: 69 tests; skipped: 2 platform/profiling-only tests

How was the solution implemented (if it is not obvious)?

The max-height comparison now uses the established tolerant MathUtilities.GreaterThan check instead of exact >. This is already used for text-width overflow and avoids treating ordinary floating-point precision error as an extra line.

Checklist

  • Added unit tests (if possible)?
  • Added XML documentation to any related classes? Not applicable: no public API changed.
  • Consider submitting a PR to https://github.com/AvaloniaUI/avalonia-docs with user documentation. Not applicable: this corrects existing behavior.

Breaking changes

None.

Obsoletions / Deprecations

None.

Fixed issues

Fixes #21786

A wrapped TextBlock with a fractional line height must retain every line when its desired height lands exactly on a fractional-scale pixel boundary.
TextLayout treated a floating-point accumulation error as a MaxHeight overflow. Use the established tolerant comparison so a line that exactly fits its rounded layout bounds is retained.
@NathanDrake2406
NathanDrake2406 marked this pull request as ready for review July 23, 2026 16:06
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.2.999-cibuild0067651-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@MrJul MrJul added bug backport-candidate-12.1.x Consider this PR for backporting to 12.1 branch labels Jul 24, 2026

@MrJul MrJul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Floating point errors strike again.
LGTM!

@MrJul
MrJul enabled auto-merge July 24, 2026 14:55
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.2.999-cibuild0067711-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@MrJul
MrJul added this pull request to the merge queue Jul 24, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 24, 2026
@MrJul
MrJul added this pull request to the merge queue Jul 24, 2026
Merged via the queue into AvaloniaUI:main with commit 480ed54 Jul 24, 2026
10 checks passed
MrJul added a commit that referenced this pull request Jul 29, 2026
* test(textblock): cover fractional layout rounding

A wrapped TextBlock with a fractional line height must retain every line when its desired height lands exactly on a fractional-scale pixel boundary.

* fix(text): preserve lines at rounded fractional heights

TextLayout treated a floating-point accumulation error as a MaxHeight overflow. Use the established tolerant comparison so a line that exactly fits its rounded layout bounds is retained.

---------

Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
@MrJul MrJul added backported-12.1.x and removed backport-candidate-12.1.x Consider this PR for backporting to 12.1 branch labels Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TextBlock can cull the last wrapped line with UseLayoutRounding, fractional LineHeight, and display scaling

3 participants