Browse Source

Use cheaper transforms in Viewbox.

Dariusz Komosinski 3 years ago
parent
commit
220a8a8df9
2 changed files with 49 additions and 42 deletions
  1. 3 2
      src/Avalonia.Controls/Viewbox.cs
  2. 46 40
      tests/Avalonia.Controls.UnitTests/ViewboxTests.cs

+ 3 - 2
src/Avalonia.Controls/Viewbox.cs

@@ -1,4 +1,5 @@
 using Avalonia.Media;
+using Avalonia.Media.Immutable;
 using Avalonia.Metadata;
 
 namespace Avalonia.Controls
@@ -8,7 +9,7 @@ namespace Avalonia.Controls
     /// </summary>
     public class Viewbox : Control
     {
-        private ViewboxContainer _containerVisual;
+        private readonly ViewboxContainer _containerVisual;
 
         /// <summary>
         /// Defines the <see cref="Stretch"/> property.
@@ -136,7 +137,7 @@ namespace Avalonia.Controls
                 var childSize = child.DesiredSize;
                 var scale = Stretch.CalculateScaling(finalSize, childSize, StretchDirection);
 
-                InternalTransform = new ScaleTransform(scale.X, scale.Y);
+                InternalTransform = new ImmutableTransform(Matrix.CreateScale(scale.X, scale.Y));
 
                 child.Arrange(new Rect(childSize));
 

+ 46 - 40
tests/Avalonia.Controls.UnitTests/ViewboxTests.cs

@@ -19,11 +19,10 @@ namespace Avalonia.Controls.UnitTests
             target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
 
             Assert.Equal(new Size(200, 100), target.DesiredSize);
-            var scaleTransform = target.InternalTransform as ScaleTransform;
-
-            Assert.NotNull(scaleTransform);
-            Assert.Equal(2.0, scaleTransform.ScaleX);
-            Assert.Equal(2.0, scaleTransform.ScaleY);
+            
+            Assert.True(TryGetScale(target, out Vector scale));
+            Assert.Equal(2.0, scale.X);
+            Assert.Equal(2.0, scale.Y);
         }
 
         [Fact]
@@ -37,11 +36,10 @@ namespace Avalonia.Controls.UnitTests
             target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
 
             Assert.Equal(new Size(100, 50), target.DesiredSize);
-            var scaleTransform = target.InternalTransform as ScaleTransform;
-
-            Assert.NotNull(scaleTransform);
-            Assert.Equal(1.0, scaleTransform.ScaleX);
-            Assert.Equal(1.0, scaleTransform.ScaleY);
+            
+            Assert.True(TryGetScale(target, out Vector scale));
+            Assert.Equal(1.0, scale.X);
+            Assert.Equal(1.0, scale.Y);
         }
 
         [Fact]
@@ -55,11 +53,10 @@ namespace Avalonia.Controls.UnitTests
             target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
 
             Assert.Equal(new Size(200, 200), target.DesiredSize);
-            var scaleTransform = target.InternalTransform as ScaleTransform;
-
-            Assert.NotNull(scaleTransform);
-            Assert.Equal(2.0, scaleTransform.ScaleX);
-            Assert.Equal(4.0, scaleTransform.ScaleY);
+            
+            Assert.True(TryGetScale(target, out Vector scale));
+            Assert.Equal(2.0, scale.X);
+            Assert.Equal(4.0, scale.Y);
         }
 
         [Fact]
@@ -73,11 +70,10 @@ namespace Avalonia.Controls.UnitTests
             target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
 
             Assert.Equal(new Size(200, 200), target.DesiredSize);
-            var scaleTransform = target.InternalTransform as ScaleTransform;
-
-            Assert.NotNull(scaleTransform);
-            Assert.Equal(4.0, scaleTransform.ScaleX);
-            Assert.Equal(4.0, scaleTransform.ScaleY);
+            
+            Assert.True(TryGetScale(target, out Vector scale));
+            Assert.Equal(4.0, scale.X);
+            Assert.Equal(4.0, scale.Y);
         }
 
         [Fact]
@@ -91,11 +87,10 @@ namespace Avalonia.Controls.UnitTests
             target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
 
             Assert.Equal(new Size(400, 200), target.DesiredSize);
-            var scaleTransform = target.InternalTransform as ScaleTransform;
-
-            Assert.NotNull(scaleTransform);
-            Assert.Equal(4.0, scaleTransform.ScaleX);
-            Assert.Equal(4.0, scaleTransform.ScaleY);
+            
+            Assert.True(TryGetScale(target, out Vector scale));
+            Assert.Equal(4.0, scale.X);
+            Assert.Equal(4.0, scale.Y);
         }
 
         [Fact]
@@ -109,11 +104,10 @@ namespace Avalonia.Controls.UnitTests
             target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
 
             Assert.Equal(new Size(200, 100), target.DesiredSize);
-            var scaleTransform = target.InternalTransform as ScaleTransform;
-
-            Assert.NotNull(scaleTransform);
-            Assert.Equal(2.0, scaleTransform.ScaleX);
-            Assert.Equal(2.0, scaleTransform.ScaleY);
+            
+            Assert.True(TryGetScale(target, out Vector scale));
+            Assert.Equal(2.0, scale.X);
+            Assert.Equal(2.0, scale.Y);
         }
 
         [Theory]
@@ -137,11 +131,9 @@ namespace Avalonia.Controls.UnitTests
 
             Assert.Equal(new Size(expectedWidth, expectedHeight), target.DesiredSize);
 
-            var scaleTransform = target.InternalTransform as ScaleTransform;
-
-            Assert.NotNull(scaleTransform);
-            Assert.Equal(expectedScale, scaleTransform.ScaleX);
-            Assert.Equal(expectedScale, scaleTransform.ScaleY);
+            Assert.True(TryGetScale(target, out Vector scale));
+            Assert.Equal(expectedScale, scale.X);
+            Assert.Equal(expectedScale, scale.Y);
         }
 
         [Theory]
@@ -165,11 +157,9 @@ namespace Avalonia.Controls.UnitTests
 
             Assert.Equal(new Size(expectedWidth, expectedHeight), target.DesiredSize);
 
-            var scaleTransform = target.InternalTransform as ScaleTransform;
-
-            Assert.NotNull(scaleTransform);
-            Assert.Equal(expectedScale, scaleTransform.ScaleX);
-            Assert.Equal(expectedScale, scaleTransform.ScaleY);
+            Assert.True(TryGetScale(target, out Vector scale));
+            Assert.Equal(expectedScale, scale.X);
+            Assert.Equal(expectedScale, scale.Y);
         }
 
         [Fact]
@@ -190,5 +180,21 @@ namespace Avalonia.Controls.UnitTests
             Assert.Empty(target.GetLogicalChildren());
             Assert.Null(child.GetLogicalParent());
         }
+
+        private bool TryGetScale(Viewbox viewbox, out Vector scale)
+        {
+            if (viewbox.InternalTransform is null)
+            {
+                scale = default;
+                return false;
+            }
+
+            var matrix = viewbox.InternalTransform.Value;
+
+            Matrix.TryDecomposeTransform(matrix, out var decomposed);
+
+            scale = decomposed.Scale;
+            return true;
+        }
     }
 }