From 26564ec1c8477910c9ee034f7ca314d3cf453faf Mon Sep 17 00:00:00 2001 From: yankun Date: Fri, 26 Jan 2024 12:12:02 +0100 Subject: [PATCH] Add support for CombinedGeometry and GeometryGroup in Headless renderer (#14360) --- .../HeadlessPlatformRenderInterface.cs | 11 ++- .../RenderingTests.cs | 68 +++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs b/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs index 5d603143de..1d4bae7e6a 100644 --- a/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs +++ b/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Linq; using System.Runtime.InteropServices; using Avalonia.Media; using Avalonia.Platform; @@ -48,8 +49,14 @@ namespace Avalonia.Headless } public IStreamGeometryImpl CreateStreamGeometry() => new HeadlessStreamingGeometryStub(); - public IGeometryImpl CreateGeometryGroup(FillRule fillRule, IReadOnlyList children) => throw new NotImplementedException(); - public IGeometryImpl CreateCombinedGeometry(GeometryCombineMode combineMode, IGeometryImpl g1, IGeometryImpl g2) => throw new NotImplementedException(); + + public IGeometryImpl CreateGeometryGroup(FillRule fillRule, IReadOnlyList children) => + new HeadlessGeometryStub(children.Count != 0 ? + children.Select(c => c.Bounds).Aggregate((a, b) => a.Union(b)) : + default); + + public IGeometryImpl CreateCombinedGeometry(GeometryCombineMode combineMode, IGeometryImpl g1, IGeometryImpl g2) + => new HeadlessGeometryStub(g1.Bounds.Union(g2.Bounds)); public IRenderTarget CreateRenderTarget(IEnumerable surfaces) => new HeadlessRenderTarget(); public bool IsLost => false; diff --git a/tests/Avalonia.Headless.UnitTests/RenderingTests.cs b/tests/Avalonia.Headless.UnitTests/RenderingTests.cs index 591863bcdb..119b17cf2f 100644 --- a/tests/Avalonia.Headless.UnitTests/RenderingTests.cs +++ b/tests/Avalonia.Headless.UnitTests/RenderingTests.cs @@ -1,5 +1,6 @@ using System.Collections.ObjectModel; using Avalonia.Controls; +using Avalonia.Controls.Shapes; using Avalonia.Layout; using Avalonia.Media; using Avalonia.Threading; @@ -36,6 +37,73 @@ public class RenderingTests Assert.NotNull(frame); } + +#if NUNIT + [AvaloniaTest, Timeout(10000)] +#elif XUNIT + [AvaloniaFact(Timeout = 10000)] +#endif + public void Should_Not_Crash_On_GeometryGroup() + { + var window = new Window + { + Content = new ContentControl + { + HorizontalAlignment = HorizontalAlignment.Stretch, + VerticalAlignment = VerticalAlignment.Stretch, + Padding = new Thickness(4), + Content = new PathIcon + { + Data = new GeometryGroup() + { + Children = new GeometryCollection(new [] + { + new RectangleGeometry(new Rect(0, 0, 50, 50)), + new RectangleGeometry(new Rect(50, 50, 100, 100)) + }) + } + } + }, + SizeToContent = SizeToContent.WidthAndHeight + }; + + window.Show(); + + var frame = window.CaptureRenderedFrame(); + + Assert.NotNull(frame); + } + +#if NUNIT + [AvaloniaTest, Timeout(10000)] +#elif XUNIT + [AvaloniaFact(Timeout = 10000)] +#endif + public void Should_Not_Crash_On_CombinedGeometry() + { + var window = new Window + { + Content = new ContentControl + { + HorizontalAlignment = HorizontalAlignment.Stretch, + VerticalAlignment = VerticalAlignment.Stretch, + Padding = new Thickness(4), + Content = new PathIcon + { + Data = new CombinedGeometry(GeometryCombineMode.Union, + new RectangleGeometry(new Rect(0, 0, 50, 50)), + new RectangleGeometry(new Rect(50, 50, 100, 100))) + } + }, + SizeToContent = SizeToContent.WidthAndHeight + }; + + window.Show(); + + var frame = window.CaptureRenderedFrame(); + + Assert.NotNull(frame); + } #if NUNIT [AvaloniaTest, Timeout(10000)]