Browse Source

Fix TransformToVisual not dealing with non-invertible transforms.

pull/5109/head
Dariusz Komosinski 6 years ago
parent
commit
0e7e861009
  1. 25
      src/Avalonia.Visuals/Matrix.cs
  2. 10
      src/Avalonia.Visuals/VisualExtensions.cs
  3. 19
      tests/Avalonia.Visuals.UnitTests/VisualTests.cs

25
src/Avalonia.Visuals/Matrix.cs

@ -282,16 +282,16 @@ namespace Avalonia
}
/// <summary>
/// Inverts the Matrix.
/// Attempts to invert the Matrix.
/// </summary>
/// <returns>The inverted matrix.</returns>
public Matrix Invert()
/// <returns>The inverted matrix or <see langword="null"/> when matrix is not invertible.</returns>
public Matrix? TryInvert()
{
double d = GetDeterminant();
if (MathUtilities.IsZero(d))
{
throw new InvalidOperationException("Transform is not invertible.");
return null;
}
return new Matrix(
@ -303,6 +303,23 @@ namespace Avalonia
((_m12 * _m31) - (_m11 * _m32)) / d);
}
/// <summary>
/// Inverts the Matrix.
/// </summary>
/// <exception cref="InvalidOperationException">Matrix is not invertible.</exception>
/// <returns>The inverted matrix.</returns>
public Matrix Invert()
{
Matrix? inverted = TryInvert();
if (!inverted.HasValue)
{
throw new InvalidOperationException("Transform is not invertible.");
}
return inverted.Value;
}
/// <summary>
/// Parses a <see cref="Matrix"/> string.
/// </summary>

10
src/Avalonia.Visuals/VisualExtensions.cs

@ -50,7 +50,15 @@ namespace Avalonia
{
var thisOffset = GetOffsetFrom(common, from);
var thatOffset = GetOffsetFrom(common, to);
return -thatOffset * thisOffset;
var thatOffsetInverted = thatOffset.TryInvert();
if (!thatOffsetInverted.HasValue)
{
return null;
}
return thatOffsetInverted.Value * thisOffset;
}
return null;

19
tests/Avalonia.Visuals.UnitTests/VisualTests.cs

@ -235,6 +235,25 @@ namespace Avalonia.Visuals.UnitTests
Assert.Equal(new Point(100, 100), point);
}
[Fact]
public void TransformToVisual_With_NonInvertible_RenderTransform_Should_Work()
{
var child = new Decorator
{
Width = 100,
Height = 100,
RenderTransform = new ScaleTransform() { ScaleX = 0, ScaleY = 0 }
};
var root = new TestRoot() { Child = child, Width = 400, Height = 400 };
root.Measure(Size.Infinity);
root.Arrange(new Rect(new Point(), root.DesiredSize));
var tr = root.TransformToVisual(child);
Assert.Null(tr);
}
[Fact]
public void Should_Not_Log_Binding_Error_When_Not_Attached_To_Logical_Tree()
{

Loading…
Cancel
Save