diff --git a/src/Avalonia.Controls/Shapes/Shape.cs b/src/Avalonia.Controls/Shapes/Shape.cs index 0387328a46..57dbeba1cc 100644 --- a/src/Avalonia.Controls/Shapes/Shape.cs +++ b/src/Avalonia.Controls/Shapes/Shape.cs @@ -195,7 +195,7 @@ namespace Avalonia.Controls.Shapes if (deferCalculateTransform) { _calculateTransformOnArrange = true; - return DefiningGeometry.Bounds.Size; + return DefiningGeometry?.Bounds.Size ?? Size.Empty; } else { @@ -217,17 +217,22 @@ namespace Avalonia.Controls.Shapes private Size CalculateShapeSizeAndSetTransform(Size availableSize) { - // This should probably use GetRenderBounds(strokeThickness) but then the calculations - // will multiply the stroke thickness as well, which isn't correct. - var (size, transform) = CalculateSizeAndTransform(availableSize, DefiningGeometry.Bounds, Stretch); - - if (_transform != transform) + if (DefiningGeometry != null) { - _transform = transform; - _renderedGeometry = null; + // This should probably use GetRenderBounds(strokeThickness) but then the calculations + // will multiply the stroke thickness as well, which isn't correct. + var (size, transform) = CalculateSizeAndTransform(availableSize, DefiningGeometry.Bounds, Stretch); + + if (_transform != transform) + { + _transform = transform; + _renderedGeometry = null; + } + + return size; } - return size; + return Size.Empty; } internal static (Size, Matrix) CalculateSizeAndTransform(Size availableSize, Rect shapeBounds, Stretch Stretch) diff --git a/src/Avalonia.Visuals/Media/DrawingContext.cs b/src/Avalonia.Visuals/Media/DrawingContext.cs index e7d6df5a93..fd593db991 100644 --- a/src/Avalonia.Visuals/Media/DrawingContext.cs +++ b/src/Avalonia.Visuals/Media/DrawingContext.cs @@ -109,6 +109,8 @@ namespace Avalonia.Media /// The geometry. public void DrawGeometry(IBrush brush, Pen pen, Geometry geometry) { + Contract.Requires(geometry != null); + if (brush != null || PenIsVisible(pen)) { PlatformImpl.DrawGeometry(brush, pen, geometry.PlatformImpl); diff --git a/src/Avalonia.Visuals/Media/GeometryDrawing.cs b/src/Avalonia.Visuals/Media/GeometryDrawing.cs index a26a5341c8..ac0cc1c17d 100644 --- a/src/Avalonia.Visuals/Media/GeometryDrawing.cs +++ b/src/Avalonia.Visuals/Media/GeometryDrawing.cs @@ -31,7 +31,10 @@ public override void Draw(DrawingContext context) { - context.DrawGeometry(Brush, Pen, Geometry); + if (Geometry != null) + { + context.DrawGeometry(Brush, Pen, Geometry); + } } public override Rect GetBounds() @@ -41,4 +44,4 @@ return Geometry?.GetRenderBounds(pen) ?? new Rect(); } } -} \ No newline at end of file +} diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs index 46d264e518..2d01b117d9 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs @@ -89,9 +89,14 @@ namespace Avalonia.Rendering.SceneGraph /// public override bool HitTest(Point p) { - p *= Transform.Invert(); - return (Brush != null && Geometry.FillContains(p)) || - (Pen != null && Geometry.StrokeContains(Pen, p)); + if (Transform.HasInverse) + { + p *= Transform.Invert(); + return (Brush != null && Geometry.FillContains(p)) || + (Pen != null && Geometry.StrokeContains(Pen, p)); + } + + return false; } } } diff --git a/tests/Avalonia.Controls.UnitTests/Shapes/PathTests.cs b/tests/Avalonia.Controls.UnitTests/Shapes/PathTests.cs new file mode 100644 index 0000000000..05224c2495 --- /dev/null +++ b/tests/Avalonia.Controls.UnitTests/Shapes/PathTests.cs @@ -0,0 +1,16 @@ +using Avalonia.Controls.Shapes; +using Xunit; + +namespace Avalonia.Controls.UnitTests.Shapes +{ + public class PathTests + { + [Fact] + public void Path_With_Null_Data_Does_Not_Throw_On_Measure() + { + var target = new Path(); + + target.Measure(Size.Infinity); + } + } +} diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs index 2060cc7170..6a1f08a384 100644 --- a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs @@ -61,6 +61,19 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph Assert.Equal(1, bitmap.RefCount); } + [Fact] + public void HitTest_On_Geometry_Node_With_Zero_Transform_Does_Not_Throw() + { + var geometry = Mock.Of(); + var geometryNode = new GeometryNode( + new Matrix(), + Brushes.Black, + null, + geometry); + + geometryNode.HitTest(new Point()); + } + private class TestDrawOperation : DrawOperation { public TestDrawOperation(Rect bounds, Matrix transform, Pen pen)