diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs index 3f0cf7c680..4b5568e71a 100644 --- a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs +++ b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs @@ -233,16 +233,16 @@ namespace Avalonia.Media.TextFormatting var textLine = TextFormatter.Current.FormatLine(textSource, 0, MaxWidth, _paragraphProperties); + UpdateBounds(textLine, ref left, ref right, ref bottom); + + textLines.Add(textLine); + if (!double.IsPositiveInfinity(MaxHeight) && bottom + textLine.LineMetrics.Size.Height > MaxHeight) { currentPosition = _text.Length; break; } - UpdateBounds(textLine, ref left, ref right, ref bottom); - - textLines.Add(textLine); - if (_paragraphProperties.TextTrimming != TextTrimming.None) { currentPosition += remainingLength; @@ -254,22 +254,15 @@ namespace Avalonia.Media.TextFormatting currentPosition += textLine.Text.Length; } + } - if (lineBreaker.Current.Required && currentPosition == _text.Length) - { - var emptyTextLine = CreateEmptyTextLine(currentPosition); - - if (!double.IsPositiveInfinity(MaxHeight) && bottom + emptyTextLine.LineMetrics.Size.Height > MaxHeight) - { - break; - } - - UpdateBounds(emptyTextLine, ref left, ref right, ref bottom); + if (lineBreaker.Current.Required && currentPosition == _text.Length) + { + var emptyTextLine = CreateEmptyTextLine(currentPosition); - textLines.Add(emptyTextLine); + UpdateBounds(emptyTextLine, ref left, ref right, ref bottom); - break; - } + textLines.Add(emptyTextLine); } Bounds = new Rect(left, 0, right, bottom); diff --git a/tests/Avalonia.Skia.UnitTests/TextLayoutTests.cs b/tests/Avalonia.Skia.UnitTests/TextLayoutTests.cs index 702e2118f5..1f89a5833c 100644 --- a/tests/Avalonia.Skia.UnitTests/TextLayoutTests.cs +++ b/tests/Avalonia.Skia.UnitTests/TextLayoutTests.cs @@ -480,6 +480,32 @@ namespace Avalonia.Skia.UnitTests } } + [InlineData("0123456789\r0123456789", 2)] + [InlineData("0123456789", 1)] + [Theory] + public void Should_Include_Last_Line_When_Constraint_Is_Surpassed(string text, int numberOfLines) + { + using (Start()) + { + var glyphTypeface = Typeface.Default.GlyphTypeface; + + var emHeight = glyphTypeface.DesignEmHeight; + + var lineHeight = (glyphTypeface.Descent - glyphTypeface.Ascent) * (12.0 / emHeight); + + var layout = new TextLayout( + text, + Typeface.Default, + 12, + Brushes.Black.ToImmutable(), + maxHeight: lineHeight * numberOfLines - lineHeight * 0.5); + + Assert.Equal(numberOfLines, layout.TextLines.Count); + + Assert.Equal(numberOfLines * lineHeight, layout.Bounds.Height); + } + } + public static IDisposable Start() { var disposable = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface