Browse Source

Fixes/drawing brush transform (#14978)

* Apply brush transform to SKPicture instead to the local matrix of the resulting SKShader

* Add unit test
Implement Direct2D1
pull/14954/head
Benedikt Stebner 2 years ago
committed by GitHub
parent
commit
6eb9d7a17e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 14
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  2. 6
      src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
  3. 30
      tests/Avalonia.RenderTests/Media/ImageBrushTests.cs
  4. BIN
      tests/TestFiles/Direct2D1/Media/ImageBrush/ImageBrush_Should_Render_With_Transform.expected.png
  5. BIN
      tests/TestFiles/Skia/Media/ImageBrush/ImageBrush_Should_Render_With_Transform.expected.png

14
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -1150,6 +1150,11 @@ namespace Avalonia.Skia
var tileBrush = content.Brush;
var transform = rect.TopLeft == default ? Matrix.Identity : Matrix.CreateTranslation(-rect.X, -rect.Y);
if (content.Transform is not null)
{
transform = content.Transform.Value * transform;
}
var calc = new TileBrushCalculator(tileBrush, contentSize, targetRect.Size);
transform *= calc.IntermediateTransform;
@ -1186,15 +1191,6 @@ namespace Avalonia.Skia
paintTransform = SKMatrix.Concat(paintTransform,
SKMatrix.CreateScale((float)(96.0 / _intermediateSurfaceDpi.X), (float)(96.0 / _intermediateSurfaceDpi.Y)));
if (tileBrush.Transform is { })
{
var origin = tileBrush.TransformOrigin.ToPixels(targetRect);
var offset = Matrix.CreateTranslation(origin);
var brushTransform = (-offset) * tileBrush.Transform.Value * (offset);
paintTransform = paintTransform.PreConcat(brushTransform.ToSKMatrix());
}
if (tileBrush.DestinationRect.Unit == RelativeUnit.Relative)
paintTransform =
paintTransform.PreConcat(SKMatrix.CreateTranslation((float)targetRect.X, (float)targetRect.Y));

6
src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs

@ -622,6 +622,12 @@ namespace Avalonia.Direct2D1.Media
using (var ctx = new RenderTarget(intermediate).CreateDrawingContext(true))
{
intermediate.Clear(null);
if (sceneBrush?.Transform is not null)
{
ctx.Transform *= sceneBrush.Transform.Value;
}
sceneBrushContent.Render(ctx,
rect.TopLeft == default ? null : Matrix.CreateTranslation(-rect.X, -rect.Y));
}

30
tests/Avalonia.RenderTests/Media/ImageBrushTests.cs

@ -460,5 +460,35 @@ namespace Avalonia.Direct2D1.RenderTests.Media
await RenderToFile(new RelativePointTestPrimitivesHelper(brush), testName);
CompareImages(testName);
}
[Fact]
public async Task ImageBrush_Should_Render_With_Transform()
{
var image = new Image
{
Width = 200,
Height = 200,
Source = new DrawingImage
{
Drawing = new GeometryDrawing
{
Brush = new DrawingBrush
{
Transform = new TranslateTransform { X = 10, Y = 10 },
Drawing = new GeometryDrawing
{
Brush = Brushes.MediumBlue,
Geometry = new RectangleGeometry { Rect = new Rect(0, 0, 48, 48) }
}
},
Geometry = new RectangleGeometry { Rect = new Rect(0, 0, 48, 48) }
}
}
};
await RenderToFile(image);
CompareImages();
}
}
}

BIN
tests/TestFiles/Direct2D1/Media/ImageBrush/ImageBrush_Should_Render_With_Transform.expected.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

BIN
tests/TestFiles/Skia/Media/ImageBrush/ImageBrush_Should_Render_With_Transform.expected.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Loading…
Cancel
Save