From 488108aab24c59547e4cac443e28bd41d2f7f0bc Mon Sep 17 00:00:00 2001 From: amwx <40413319+amwx@users.noreply.github.com> Date: Fri, 22 Apr 2022 21:34:27 -0400 Subject: [PATCH] Support for TransformOrigin in Skia DC --- src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 39 ++++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 2548b9f5aa..7e0360d691 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -180,7 +180,8 @@ namespace Avalonia.Skia var size = geometry.Bounds.Size; using (var fill = brush != null ? CreatePaint(_fillPaint, brush, size) : default(PaintWrapper)) - using (var stroke = pen?.Brush != null ? CreatePaint(_strokePaint, pen, size) : default(PaintWrapper)) + using (var stroke = pen?.Brush != null ? CreatePaint(_strokePaint, pen, + size.Inflate(new Thickness(pen?.Thickness / 2 ?? 0))) : default(PaintWrapper)) { if (fill.Paint != null) { @@ -397,7 +398,7 @@ namespace Avalonia.Skia if (pen?.Brush != null) { - using (var paint = CreatePaint(_strokePaint, pen, rect.Rect.Size)) + using (var paint = CreatePaint(_strokePaint, pen, rect.Rect.Size.Inflate(new Thickness(pen?.Thickness / 2 ?? 0)))) { if (paint.Paint is object) { @@ -432,7 +433,7 @@ namespace Avalonia.Skia if (pen?.Brush != null) { - using (var paint = CreatePaint(_strokePaint, pen, rect.Size)) + using (var paint = CreatePaint(_strokePaint, pen, rect.Size.Inflate(new Thickness(pen?.Thickness / 2 ?? 0)))) { if (paint.Paint is object) { @@ -624,8 +625,12 @@ namespace Avalonia.Skia } else { + var transformOrigin = linearGradient.TransformOrigin.ToPixels(targetSize); + var offset = Matrix.CreateTranslation(transformOrigin); + var transform = (-offset) * linearGradient.Transform.Value * (offset); + using (var shader = - SKShader.CreateLinearGradient(start, end, stopColors, stopOffsets, tileMode, linearGradient.Transform.Value.ToSKMatrix())) + SKShader.CreateLinearGradient(start, end, stopColors, stopOffsets, tileMode, transform.ToSKMatrix())) { paintWrapper.Paint.Shader = shader; } @@ -653,8 +658,12 @@ namespace Avalonia.Skia } else { + var transformOrigin = radialGradient.TransformOrigin.ToPixels(targetSize); + var offset = Matrix.CreateTranslation(transformOrigin); + var transform = (-offset) * radialGradient.Transform.Value * (offset); + using (var shader = - SKShader.CreateRadialGradient(center, radius, stopColors, stopOffsets, tileMode, radialGradient.Transform.Value.ToSKMatrix())) + SKShader.CreateRadialGradient(center, radius, stopColors, stopOffsets, tileMode, transform.ToSKMatrix())) { paintWrapper.Paint.Shader = shader; } @@ -693,9 +702,14 @@ namespace Avalonia.Skia } else { + + var transformOrigin = radialGradient.TransformOrigin.ToPixels(targetSize); + var offset = Matrix.CreateTranslation(transformOrigin); + var transform = (-offset) * radialGradient.Transform.Value * (offset); + using (var shader = SKShader.CreateCompose( SKShader.CreateColor(reversedColors[0]), - SKShader.CreateTwoPointConicalGradient(center, radius, origin, 0, reversedColors, reversedStops, tileMode, radialGradient.Transform.Value.ToSKMatrix()) + SKShader.CreateTwoPointConicalGradient(center, radius, origin, 0, reversedColors, reversedStops, tileMode, transform.ToSKMatrix()) )) { paintWrapper.Paint.Shader = shader; @@ -716,7 +730,12 @@ namespace Avalonia.Skia if (conicGradient.Transform is { }) { - rotation = rotation.PreConcat(conicGradient.Transform.Value.ToSKMatrix()); + + var transformOrigin = conicGradient.TransformOrigin.ToPixels(targetSize); + var offset = Matrix.CreateTranslation(transformOrigin); + var transform = (-offset) * conicGradient.Transform.Value * (offset); + + rotation = rotation.PreConcat(transform.ToSKMatrix()); } using (var shader = @@ -793,7 +812,11 @@ namespace Avalonia.Skia if (tileBrush.Transform is { }) { - paintTransform = paintTransform.PreConcat(tileBrush.Transform.Value.ToSKMatrix()); + var origin = tileBrush.TransformOrigin.ToPixels(targetSize); + var offset = Matrix.CreateTranslation(origin); + var transform = (-offset) * tileBrush.Transform.Value * (offset); + + paintTransform = paintTransform.PreConcat(transform.ToSKMatrix()); } using (var shader = image.ToShader(tileX, tileY, paintTransform))