Browse Source

Include last line when constraint is surpassed

Benedikt Schroeder 5 years ago
parent
commit
f7aa466803

+ 10 - 17
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);

+ 42 - 16
tests/Avalonia.Skia.UnitTests/TextLayoutTests.cs

@@ -29,10 +29,10 @@ namespace Avalonia.Skia.UnitTests
 
                 var layout = new TextLayout(
                     s_multiLineText,
-                    Typeface.Default, 
+                    Typeface.Default,
                     12.0f,
                     Brushes.Black.ToImmutable(),
-                    textStyleOverrides : spans);
+                    textStyleOverrides: spans);
 
                 var textLine = layout.TextLines[0];
 
@@ -72,16 +72,16 @@ namespace Avalonia.Skia.UnitTests
                         12.0f,
                         Brushes.Black.ToImmutable(),
                         textWrapping: TextWrapping.Wrap,
-                        maxWidth : 25);
+                        maxWidth: 25);
 
                     var actual = new TextLayout(
                         s_multiLineText,
                         Typeface.Default,
                         12.0f,
                         Brushes.Black.ToImmutable(),
-                        textWrapping : TextWrapping.Wrap,
-                        maxWidth : 25,
-                        textStyleOverrides : spans);
+                        textWrapping: TextWrapping.Wrap,
+                        maxWidth: 25,
+                        textStyleOverrides: spans);
 
                     Assert.Equal(expected.TextLines.Count, actual.TextLines.Count);
 
@@ -115,7 +115,7 @@ namespace Avalonia.Skia.UnitTests
                     Typeface.Default,
                     12.0f,
                     Brushes.Black.ToImmutable(),
-                    textStyleOverrides : spans);
+                    textStyleOverrides: spans);
 
                 var textLine = layout.TextLines[0];
 
@@ -153,7 +153,7 @@ namespace Avalonia.Skia.UnitTests
                     Typeface.Default,
                     12.0f,
                     Brushes.Black.ToImmutable(),
-                    textStyleOverrides : spans);
+                    textStyleOverrides: spans);
 
                 var textLine = layout.TextLines[0];
 
@@ -190,7 +190,7 @@ namespace Avalonia.Skia.UnitTests
                     Typeface.Default,
                     12.0f,
                     Brushes.Black.ToImmutable(),
-                    textStyleOverrides : spans);
+                    textStyleOverrides: spans);
 
                 var textLine = layout.TextLines[0];
 
@@ -301,8 +301,8 @@ namespace Avalonia.Skia.UnitTests
                     Typeface.Default,
                     12.0f,
                     Brushes.Black.ToImmutable(),
-                    textWrapping : TextWrapping.Wrap,
-                    maxWidth : 180,
+                    textWrapping: TextWrapping.Wrap,
+                    maxWidth: 180,
                     textStyleOverrides: spans);
 
                 Assert.Equal(
@@ -332,8 +332,8 @@ namespace Avalonia.Skia.UnitTests
                     Typeface.Default,
                     12.0f,
                     Brushes.Black.ToImmutable(),
-                    maxWidth : 200, 
-                    maxHeight : 125,
+                    maxWidth: 200,
+                    maxHeight: 125,
                     textStyleOverrides: spans);
 
                 Assert.Equal(foreground, layout.TextLines[0].TextRuns[1].Style.Foreground);
@@ -430,7 +430,7 @@ namespace Avalonia.Skia.UnitTests
 
                 Assert.Equal(5, ((ShapedTextRun)layout.TextLines[0].TextRuns[0]).GlyphRun.GlyphClusters[5]);
 
-                if(expectedLength == 7)
+                if (expectedLength == 7)
                 {
                     Assert.Equal(5, ((ShapedTextRun)layout.TextLines[0].TextRuns[0]).GlyphRun.GlyphClusters[6]);
                 }
@@ -480,12 +480,38 @@ 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
-                .With(renderInterface: new PlatformRenderInterface(null), 
+                .With(renderInterface: new PlatformRenderInterface(null),
                     textShaperImpl: new TextShaperImpl(),
-                    fontManagerImpl : new CustomFontManagerImpl()));
+                    fontManagerImpl: new CustomFontManagerImpl()));
 
             return disposable;
         }