浏览代码

Add support for CombinedGeometry and GeometryGroup in Headless renderer (#14360)

yankun 1 年之前
父节点
当前提交
26564ec1c8

+ 9 - 2
src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs

@@ -2,6 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.CodeAnalysis;
 using System.IO;
 using System.IO;
+using System.Linq;
 using System.Runtime.InteropServices;
 using System.Runtime.InteropServices;
 using Avalonia.Media;
 using Avalonia.Media;
 using Avalonia.Platform;
 using Avalonia.Platform;
@@ -48,8 +49,14 @@ namespace Avalonia.Headless
         }
         }
 
 
         public IStreamGeometryImpl CreateStreamGeometry() => new HeadlessStreamingGeometryStub();
         public IStreamGeometryImpl CreateStreamGeometry() => new HeadlessStreamingGeometryStub();
-        public IGeometryImpl CreateGeometryGroup(FillRule fillRule, IReadOnlyList<IGeometryImpl> children) => throw new NotImplementedException();
-        public IGeometryImpl CreateCombinedGeometry(GeometryCombineMode combineMode, IGeometryImpl g1, IGeometryImpl g2) => throw new NotImplementedException();
+
+        public IGeometryImpl CreateGeometryGroup(FillRule fillRule, IReadOnlyList<IGeometryImpl> 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<object> surfaces) => new HeadlessRenderTarget();
         public IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces) => new HeadlessRenderTarget();
         public bool IsLost => false;
         public bool IsLost => false;

+ 68 - 0
tests/Avalonia.Headless.UnitTests/RenderingTests.cs

@@ -1,5 +1,6 @@
 using System.Collections.ObjectModel;
 using System.Collections.ObjectModel;
 using Avalonia.Controls;
 using Avalonia.Controls;
+using Avalonia.Controls.Shapes;
 using Avalonia.Layout;
 using Avalonia.Layout;
 using Avalonia.Media;
 using Avalonia.Media;
 using Avalonia.Threading;
 using Avalonia.Threading;
@@ -36,6 +37,73 @@ public class RenderingTests
 
 
         Assert.NotNull(frame);
         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
 #if NUNIT
     [AvaloniaTest, Timeout(10000)]
     [AvaloniaTest, Timeout(10000)]