From 932f54316b03f2e9e4321b36780cc314315cdf78 Mon Sep 17 00:00:00 2001 From: Julien Lebosquain Date: Thu, 12 Sep 2024 21:16:06 +0200 Subject: [PATCH] Fixes geometry render bounds when curves are present (#16756) * Added failing geometry bounds tests * Fixed geometry bounds * Fixed RenderboundsTests --------- Co-authored-by: Benedikt Stebner --- src/Skia/Avalonia.Skia/GeometryImpl.cs | 4 +-- .../RenderBoundsTests.cs | 27 +++++++------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/Skia/Avalonia.Skia/GeometryImpl.cs b/src/Skia/Avalonia.Skia/GeometryImpl.cs index 47508970d5..7412ed72a7 100644 --- a/src/Skia/Avalonia.Skia/GeometryImpl.cs +++ b/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) diff --git a/tests/Avalonia.Skia.UnitTests/RenderBoundsTests.cs b/tests/Avalonia.Skia.UnitTests/RenderBoundsTests.cs index a659c2b8b2..6f8302576f 100644 --- a/tests/Avalonia.Skia.UnitTests/RenderBoundsTests.cs +++ b/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); } } }