diff --git a/src/Avalonia.Base/Layout/LayoutManager.cs b/src/Avalonia.Base/Layout/LayoutManager.cs index c64c2714c3..f9ea436bb7 100644 --- a/src/Avalonia.Base/Layout/LayoutManager.cs +++ b/src/Avalonia.Base/Layout/LayoutManager.cs @@ -423,12 +423,16 @@ namespace Avalonia.Layout // Translate the viewport into this control's coordinate space. viewport = viewport.Translate(-control.Bounds.Position); - if (control != target && control.RenderTransform is object) + if (control != target && control.RenderTransform is { } transform) { - var origin = control.RenderTransformOrigin.ToPixels(control.Bounds.Size); - var offset = Matrix.CreateTranslation(origin); - var renderTransform = (-offset) * control.RenderTransform.Value.Invert() * (offset); - viewport = viewport.TransformToAABB(renderTransform); + if (transform.Value.TryInvert(out var invertedMatrix)) + { + var origin = control.RenderTransformOrigin.ToPixels(control.Bounds.Size); + var offset = Matrix.CreateTranslation(origin); + viewport = viewport.TransformToAABB(-offset * invertedMatrix * offset); + } + else + viewport = default; } } diff --git a/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_EffectiveViewportChanged.cs b/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_EffectiveViewportChanged.cs index 5a493cb741..63eb6589ca 100644 --- a/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_EffectiveViewportChanged.cs +++ b/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_EffectiveViewportChanged.cs @@ -341,6 +341,32 @@ namespace Avalonia.Base.UnitTests.Layout }); } + // https://github.com/AvaloniaUI/Avalonia/issues/12452 + [Fact] + public async Task Zero_ScaleTransform_Sets_Empty_EffectiveViewport() + { + await RunOnUIThread.Execute(async () => + { + var effectiveViewport = new Rect(Size.Infinity); + + var root = CreateRoot(); + var target = new Canvas { Width = 100, Height = 100 }; + var parent = new Border { Width = 100, Height = 100, Child = target }; + + target.EffectiveViewportChanged += (_, e) => effectiveViewport = e.EffectiveViewport; + + root.Child = parent; + + await ExecuteInitialLayoutPass(root); + + parent.RenderTransform = new ScaleTransform(0, 0); + + await ExecuteLayoutPass(root); + + Assert.Equal(new Rect(0, 0, 0, 0), effectiveViewport); + }); + } + private static TestRoot CreateRoot() => new TestRoot { Width = 1200, Height = 900 }; private static Task ExecuteInitialLayoutPass(TestRoot root)