From 6eb9d7a17ea18d0724125bd3116dc522edec6f5d Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Fri, 15 Mar 2024 09:12:30 +0100 Subject: [PATCH] Fixes/drawing brush transform (#14978) * Apply brush transform to SKPicture instead to the local matrix of the resulting SKShader * Add unit test Implement Direct2D1 --- src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 14 +++----- .../Media/DrawingContextImpl.cs | 6 ++++ .../Media/ImageBrushTests.cs | 30 ++++++++++++++++++ ..._Should_Render_With_Transform.expected.png | Bin 0 -> 555 bytes ..._Should_Render_With_Transform.expected.png | Bin 0 -> 564 bytes 5 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 tests/TestFiles/Direct2D1/Media/ImageBrush/ImageBrush_Should_Render_With_Transform.expected.png create mode 100644 tests/TestFiles/Skia/Media/ImageBrush/ImageBrush_Should_Render_With_Transform.expected.png diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index bbce08b536..2b058d8fb7 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/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)); diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs index 7de448235a..3ddaf5986d 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs +++ b/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)); } diff --git a/tests/Avalonia.RenderTests/Media/ImageBrushTests.cs b/tests/Avalonia.RenderTests/Media/ImageBrushTests.cs index 640aed2ea8..699d0ea089 100644 --- a/tests/Avalonia.RenderTests/Media/ImageBrushTests.cs +++ b/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(); + } } } diff --git a/tests/TestFiles/Direct2D1/Media/ImageBrush/ImageBrush_Should_Render_With_Transform.expected.png b/tests/TestFiles/Direct2D1/Media/ImageBrush/ImageBrush_Should_Render_With_Transform.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..957cddecb85ddf3e7d480745a32971ad2bb1a65a GIT binary patch literal 555 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrgO+)zif>q$2L^<&C@z4g$;voBu^GR`alH;f;5i<@tuK45$S!Na#*}%OCUI rYQx!`Vik%4988T0qr||5fxj{Tr*vkHJ*wjQps4e7^>bP0l+XkKGEHId literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Skia/Media/ImageBrush/ImageBrush_Should_Render_With_Transform.expected.png b/tests/TestFiles/Skia/Media/ImageBrush/ImageBrush_Should_Render_With_Transform.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..5a0d77cbd23718382c16e483b303999b1457ad55 GIT binary patch literal 564 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yu@pObhHwBu4M$1`0|Vo0PZ!6K ziaBpDJMtb15MekN-qgCvfwjo6dFi8s%giV9FG;di-;@Mu#0MVaZ@bF)yypANw_A5L z{jOZcXYst^yv+QoqIb?Gmomi6bX1UFX&NO4HVh8&&pgg*Zl