diff --git a/src/Avalonia.Visuals/Media/Transformation/TransformParser.cs b/src/Avalonia.Visuals/Media/Transformation/TransformParser.cs index 2a3912832b..85f4f5fec1 100644 --- a/src/Avalonia.Visuals/Media/Transformation/TransformParser.cs +++ b/src/Avalonia.Visuals/Media/Transformation/TransformParser.cs @@ -198,16 +198,12 @@ namespace Avalonia.Media.Transformation VerifyZeroOrUnit(function, in scaleX, Unit.None); VerifyZeroOrUnit(function, in scaleY, Unit.None); - if (function == TransformFunction.ScaleX) - { - scaleY = UnitValue.Zero; - } - else if (function == TransformFunction.ScaleY) + if (function == TransformFunction.ScaleY) { scaleY = scaleX; - scaleX = UnitValue.Zero; + scaleX = UnitValue.One; } - else if (count == 1) + else if (function == TransformFunction.Scale && count == 1) { scaleY = scaleX; } @@ -233,19 +229,11 @@ namespace Avalonia.Media.Transformation VerifyZeroOrAngle(function, in skewX); VerifyZeroOrAngle(function, in skewY); - if (function == TransformFunction.SkewX) - { - skewY = UnitValue.Zero; - } - else if (function == TransformFunction.SkewY) + if (function == TransformFunction.SkewY) { skewY = skewX; skewX = UnitValue.Zero; } - else if (count == 1) - { - skewY = skewX; - } builder.AppendSkew(ToRadians(in skewX), ToRadians(in skewY)); @@ -286,19 +274,11 @@ namespace Avalonia.Media.Transformation VerifyZeroOrUnit(function, in translateX, Unit.Pixel); VerifyZeroOrUnit(function, in translateY, Unit.Pixel); - if (function == TransformFunction.TranslateX) - { - translateY = UnitValue.Zero; - } - else if (function == TransformFunction.TranslateY) + if (function == TransformFunction.TranslateY) { translateY = translateX; translateX = UnitValue.Zero; } - else if (count == 1) - { - translateY = translateX; - } builder.AppendTranslate(translateX.Value, translateY.Value); @@ -358,6 +338,7 @@ namespace Avalonia.Media.Transformation switch (unit) { case Unit.Radian: + case Unit.Gradian: case Unit.Degree: case Unit.Turn: { diff --git a/tests/Avalonia.Visuals.UnitTests/Media/TransformOperationsTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/TransformOperationsTests.cs index 8b4ccba57d..856b4615a5 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/TransformOperationsTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/TransformOperationsTests.cs @@ -6,6 +6,93 @@ namespace Avalonia.Visuals.UnitTests.Media { public class TransformOperationsTests { + [Theory] + [InlineData("translate(10px)", 10d, 0d)] + [InlineData("translate(10px, 10px)", 10d, 10d)] + [InlineData("translate(0px, 10px)", 0d, 10d)] + [InlineData("translate(10px, 0px)", 10d, 0d)] + [InlineData("translateX(10px)", 10d, 0d)] + [InlineData("translateY(10px)", 0d, 10d)] + public void Can_Parse_Translation(string data, double x, double y) + { + var transform = TransformOperations.Parse(data); + + var operations = transform.Operations; + + Assert.Single(operations); + Assert.Equal(TransformOperation.OperationType.Translate, operations[0].Type); + Assert.Equal(x, operations[0].Data.Translate.X); + Assert.Equal(y, operations[0].Data.Translate.Y); + } + + [Theory] + [InlineData("rotate(90deg)", 90d)] + [InlineData("rotate(0.5turn)", 180d)] + [InlineData("rotate(200grad)", 180d)] + [InlineData("rotate(3.14159265rad)", 180d)] + public void Can_Parse_Rotation(string data, double angleDeg) + { + var transform = TransformOperations.Parse(data); + + var operations = transform.Operations; + + Assert.Single(operations); + Assert.Equal(TransformOperation.OperationType.Rotate, operations[0].Type); + Assert.Equal(MathUtilities.Deg2Rad(angleDeg), operations[0].Data.Rotate.Angle, 4); + } + + [Theory] + [InlineData("scale(10)", 10d, 10d)] + [InlineData("scale(10, 10)", 10d, 10d)] + [InlineData("scale(0, 10)", 0d, 10d)] + [InlineData("scale(10, 0)", 10d, 0d)] + [InlineData("scaleX(10)", 10d, 1d)] + [InlineData("scaleY(10)", 1d, 10d)] + public void Can_Parse_Scale(string data, double x, double y) + { + var transform = TransformOperations.Parse(data); + + var operations = transform.Operations; + + Assert.Single(operations); + Assert.Equal(TransformOperation.OperationType.Scale, operations[0].Type); + Assert.Equal(x, operations[0].Data.Scale.X); + Assert.Equal(y, operations[0].Data.Scale.Y); + } + + [Theory] + [InlineData("skew(90deg)", 90d, 0d)] + [InlineData("skew(0.5turn)", 180d, 0d)] + [InlineData("skew(200grad)", 180d, 0d)] + [InlineData("skew(3.14159265rad)", 180d, 0d)] + [InlineData("skewX(90deg)", 90d, 0d)] + [InlineData("skewX(0.5turn)", 180d, 0d)] + [InlineData("skewX(200grad)", 180d, 0d)] + [InlineData("skewX(3.14159265rad)", 180d, 0d)] + [InlineData("skew(0, 90deg)", 0d, 90d)] + [InlineData("skew(0, 0.5turn)", 0d, 180d)] + [InlineData("skew(0, 200grad)", 0d, 180d)] + [InlineData("skew(0, 3.14159265rad)", 0d, 180d)] + [InlineData("skewY(90deg)", 0d, 90d)] + [InlineData("skewY(0.5turn)", 0d, 180d)] + [InlineData("skewY(200grad)", 0d, 180d)] + [InlineData("skewY(3.14159265rad)", 0d, 180d)] + [InlineData("skew(90deg, 90deg)", 90d, 90d)] + [InlineData("skew(0.5turn, 0.5turn)", 180d, 180d)] + [InlineData("skew(200grad, 200grad)", 180d, 180d)] + [InlineData("skew(3.14159265rad, 3.14159265rad)", 180d, 180d)] + public void Can_Parse_Skew(string data, double x, double y) + { + var transform = TransformOperations.Parse(data); + + var operations = transform.Operations; + + Assert.Single(operations); + Assert.Equal(TransformOperation.OperationType.Skew, operations[0].Type); + Assert.Equal(MathUtilities.Deg2Rad(x), operations[0].Data.Skew.X, 4); + Assert.Equal(MathUtilities.Deg2Rad(y), operations[0].Data.Skew.Y, 4); + } + [Fact] public void Can_Parse_Compound_Operations() { @@ -37,6 +124,15 @@ namespace Avalonia.Visuals.UnitTests.Media var data = "matrix(1,2,3,4,5,6)"; var transform = TransformOperations.Parse(data); + + var operations = transform.Operations; + + Assert.Single(operations); + Assert.Equal(TransformOperation.OperationType.Matrix, operations[0].Type); + + var expectedMatrix = new Matrix(1, 2, 3, 4, 5, 6); + + Assert.Equal(expectedMatrix, operations[0].Matrix); } [Theory] @@ -59,9 +155,9 @@ namespace Avalonia.Visuals.UnitTests.Media } [Theory] - [InlineData(0d, 10d, 0d)] - [InlineData(0.5d, 5d, 10d)] - [InlineData(1d, 0d, 20d)] + [InlineData(0d, 10d, 1d)] + [InlineData(0.5d, 5.5d, 10.5d)] + [InlineData(1d, 1d, 20d)] public void Can_Interpolate_Scale(double progress, double x, double y) { var from = TransformOperations.Parse("scaleX(10)");