From 638fd1e70c97e7cb1714184090823ece8ac80fe9 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 24 Nov 2018 20:26:40 +0100 Subject: [PATCH] Fix DPI scaling for Skia tile brushes. --- src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 48 +++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 1bfd7fd90d..076d69ae4a 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -225,10 +225,7 @@ namespace Avalonia.Skia /// public IRenderTargetBitmapImpl CreateLayer(Size size) { - var normalizedDpi = new Vector(_dpi.X / SkiaPlatform.DefaultDpi.X, _dpi.Y / SkiaPlatform.DefaultDpi.Y); - var pixelSize = size * normalizedDpi; - - return CreateRenderTarget((int) pixelSize.Width, (int) pixelSize.Height, _dpi); + return CreateRenderTarget(size); } /// @@ -387,26 +384,27 @@ namespace Avalonia.Skia /// Target size. /// Tile brush to use. /// Tile brush image. - /// The bitmap interpolation mode. private void ConfigureTileBrush(ref PaintWrapper paintWrapper, Size targetSize, ITileBrush tileBrush, IDrawableBitmapImpl tileBrushImage) { - var calc = new TileBrushCalculator(tileBrush, - new Size(tileBrushImage.PixelSize.Width, tileBrushImage.PixelSize.Height), targetSize); - - var intermediate = CreateRenderTarget( - (int)calc.IntermediateSize.Width, - (int)calc.IntermediateSize.Height, _dpi); + var calc = new TileBrushCalculator(tileBrush, tileBrushImage.PixelSize.ToSize(_dpi), targetSize); + var intermediate = CreateRenderTarget(calc.IntermediateSize); paintWrapper.AddDisposable(intermediate); using (var context = intermediate.CreateDrawingContext(null)) { - var rect = new Rect(0, 0, tileBrushImage.PixelSize.Width, tileBrushImage.PixelSize.Height); + var sourceRect = new Rect(tileBrushImage.PixelSize.ToSize(96)); + var targetRect = new Rect(tileBrushImage.PixelSize.ToSize(_dpi)); context.Clear(Colors.Transparent); context.PushClip(calc.IntermediateClip); context.Transform = calc.IntermediateTransform; - context.DrawImage(RefCountable.CreateUnownedNotClonable(tileBrushImage), 1, rect, rect, tileBrush.BitmapInterpolationMode); + context.DrawImage( + RefCountable.CreateUnownedNotClonable(tileBrushImage), + 1, + sourceRect, + targetRect, + tileBrush.BitmapInterpolationMode); context.PopClip(); } @@ -433,7 +431,14 @@ namespace Avalonia.Skia var image = intermediate.SnapshotImage(); paintWrapper.AddDisposable(image); - using (var shader = image.ToShader(tileX, tileY, tileTransform)) + var paintTransform = default(SKMatrix); + + SKMatrix.Concat( + ref paintTransform, + tileTransform, + SKMatrix.MakeScale((float)(96.0 / _dpi.X), (float)(96.0 / _dpi.Y))); + + using (var shader = image.ToShader(tileX, tileY, paintTransform)) { paintWrapper.Paint.Shader = shader; } @@ -457,7 +462,7 @@ namespace Avalonia.Skia if (intermediateSize.Width >= 1 && intermediateSize.Height >= 1) { - var intermediate = CreateRenderTarget((int)intermediateSize.Width, (int)intermediateSize.Height, _dpi); + var intermediate = CreateRenderTarget(intermediateSize); using (var ctx = intermediate.CreateDrawingContext(visualBrushRenderer)) { @@ -609,18 +614,17 @@ namespace Avalonia.Skia /// /// Create new render target compatible with this drawing context. /// - /// Width. - /// Height. - /// Drawing dpi. + /// The size of the render target in DIPs. /// Pixel format. /// - private SurfaceRenderTarget CreateRenderTarget(int width, int height, Vector dpi, PixelFormat? format = null) + private SurfaceRenderTarget CreateRenderTarget(Size size, PixelFormat? format = null) { + var pixelSize = PixelSize.FromSize(size, _dpi); var createInfo = new SurfaceRenderTarget.CreateInfo { - Width = width, - Height = height, - Dpi = dpi, + Width = pixelSize.Width, + Height = pixelSize.Height, + Dpi = _dpi, Format = format, DisableTextLcdRendering = !_canTextUseLcdRendering, GrContext = _grContext