Browse Source

Fixes geometry render bounds when curves are present (#16756)

* Added failing geometry bounds tests

* Fixed geometry bounds

* Fixed RenderboundsTests

---------

Co-authored-by: Benedikt Stebner <[email protected]>
Julien Lebosquain 1 year ago
parent
commit
932f54316b

+ 2 - 2
src/Skia/Avalonia.Skia/GeometryImpl.cs

@@ -82,7 +82,7 @@ namespace Avalonia.Skia
                 _pathCache.UpdateIfNeeded(StrokePath, pen);
                 var bounds = _pathCache.RenderBounds;
                 if (StrokePath != FillPath && FillPath != null)
-                    bounds = bounds.Union(FillPath.Bounds.ToAvaloniaRect());
+                    bounds = bounds.Union(FillPath.TightBounds.ToAvaloniaRect());
                 return bounds;
             }
         }
@@ -178,7 +178,7 @@ namespace Avalonia.Skia
             private Rect? _renderBounds;
             private static readonly SKPath s_emptyPath = new();
             
-            public Rect RenderBounds => _renderBounds ??= (_path ?? _cachedFor ?? s_emptyPath).Bounds.ToAvaloniaRect();
+            public Rect RenderBounds => _renderBounds ??= (_path ?? _cachedFor ?? s_emptyPath).TightBounds.ToAvaloniaRect();
             public SKPath ExpandedPath => _path ?? s_emptyPath;
 
             public void UpdateIfNeeded(SKPath? strokePath, IPen? pen)

+ 10 - 17
tests/Avalonia.Skia.UnitTests/RenderBoundsTests.cs

@@ -1,9 +1,4 @@
-using System;
-using Avalonia.Controls.Shapes;
-using Avalonia.Layout;
-using Avalonia.Media;
-using Avalonia.Platform;
-using Avalonia.Rendering;
+using Avalonia.Media;
 using Avalonia.UnitTests;
 using Xunit;
 
@@ -13,12 +8,13 @@ namespace Avalonia.Skia.UnitTests
     {
         [Theory,
             InlineData("M10 20 L 20 10 L 30 20", PenLineCap.Round, PenLineJoin.Miter, 2, 10, 
-                8.585786819458008, 8.585786819458008, 22.828428268432617, 12.828428268432617),
+                9, 8.585786819458008, 22.000001907348633, 12.414215087890625),
             InlineData("M10 10 L 20 10", PenLineCap.Round, PenLineJoin.Miter,2, 10,
                 9,9,12,2),
             InlineData("M10 10 L 20 15 L 10 20", PenLineCap.Flat, PenLineJoin.Miter, 2, 20,
-                9.552786827087402, 9.105572700500488, 12.683281898498535, 11.788853645324707)
-        
+                9.552786827087402, 9.105572700500488, 12.683281898498535, 11.788853645324707),
+            InlineData("M0,0 A128,128 0 0 0 128,0", PenLineCap.Flat, PenLineJoin.Bevel, 0, 0,
+                0, 0, 128, 17.14875030517578)
         ]
         public void RenderBoundsAreCorrectlyCalculated(string path, PenLineCap cap, PenLineJoin join, double thickness, double miterLimit, double x, double y, double width, double height)
         {
@@ -29,14 +25,11 @@ namespace Avalonia.Skia.UnitTests
                 var pen = new Pen(Brushes.Black, thickness, null, cap, join, miterLimit);
                 var bounds = geo.GetRenderBounds(pen);
                 var tolerance = 0.001;
-                if (
-                    Math.Abs(bounds.X - x) > tolerance
-                    || Math.Abs(bounds.Y - y) > tolerance
-                    || Math.Abs(bounds.Width - width) > tolerance
-                    || Math.Abs(bounds.Height - height) > tolerance)
-                    Assert.Fail($"Expected {x}:{y}:{width}:{height}, got {bounds}");
-                
-                Assert.Equal(new Rect(x, y, width, height), bounds);
+
+                Assert.Equal(bounds.X, x, tolerance);
+                Assert.Equal(bounds.Y, y, tolerance);
+                Assert.Equal(bounds.Width, width, tolerance);
+                Assert.Equal(bounds.Height, height, tolerance);
             }
         }
     }