瀏覽代碼

Merge pull request #3681 from Gillibald/fixes/TextLayoutNoClipping

Enable clipping for canceled text layout
Benedikt Stebner 5 年之前
父節點
當前提交
78a33bc394
共有 2 個文件被更改,包括 36 次插入17 次删除
  1. 10 17
      src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs
  2. 26 0
      tests/Avalonia.Skia.UnitTests/TextLayoutTests.cs

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

+ 26 - 0
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