Browse Source

Fix DPI scaling with Skia.

scenegraph-after-breakage
Steven Kirk 9 years ago
parent
commit
69c43cb645
  1. 23
      src/Skia/Avalonia.Skia/BitmapImpl.cs
  2. 16
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  3. 3
      src/Skia/Avalonia.Skia/FramebufferRenderTarget.cs
  4. 4
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

23
src/Skia/Avalonia.Skia/BitmapImpl.cs

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Rendering;
using SkiaSharp;
@ -12,6 +8,9 @@ namespace Avalonia.Skia
{
class BitmapImpl : IRenderTargetBitmapImpl, IWritableBitmapImpl
{
private double _dpiX;
private double _dpiY;
public SKBitmap Bitmap { get; private set; }
public BitmapImpl(SKBitmap bm)
@ -19,12 +18,16 @@ namespace Avalonia.Skia
Bitmap = bm;
PixelHeight = bm.Height;
PixelWidth = bm.Width;
_dpiX = 96;
_dpiY = 96;
}
public BitmapImpl(int width, int height, PixelFormat? fmt = null)
public BitmapImpl(int width, int height, double dpiX, double dpiY, PixelFormat? fmt = null)
{
PixelHeight = height;
PixelWidth = width;
_dpiX = dpiX;
_dpiY = dpiY;
var colorType = fmt?.ToSkColorType() ?? SKImageInfo.PlatformColorType;
var runtime = AvaloniaLocator.Current?.GetService<IRuntimePlatform>()?.GetRuntimeInfo();
if (runtime?.IsDesktop == true && runtime?.OperatingSystem == OperatingSystemType.Linux)
@ -68,8 +71,8 @@ namespace Avalonia.Skia
{
private readonly SKSurface _surface;
public BitmapDrawingContext(SKBitmap bitmap, IVisualBrushRenderer visualBrushRenderer)
: this(CreateSurface(bitmap), visualBrushRenderer)
public BitmapDrawingContext(SKBitmap bitmap, double dpiX, double dpiY, IVisualBrushRenderer visualBrushRenderer)
: this(CreateSurface(bitmap), dpiX, dpiY, visualBrushRenderer)
{
}
@ -83,8 +86,8 @@ namespace Avalonia.Skia
return rv;
}
public BitmapDrawingContext(SKSurface surface, IVisualBrushRenderer visualBrushRenderer)
: base(surface.Canvas, visualBrushRenderer)
public BitmapDrawingContext(SKSurface surface, double dpiX, double dpiY, IVisualBrushRenderer visualBrushRenderer)
: base(surface.Canvas, dpiX, dpiY, visualBrushRenderer)
{
_surface = surface;
}
@ -98,7 +101,7 @@ namespace Avalonia.Skia
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
{
return new BitmapDrawingContext(Bitmap, visualBrushRenderer);
return new BitmapDrawingContext(Bitmap, _dpiX, _dpiY, visualBrushRenderer);
}
public void Save(Stream stream)

16
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -11,6 +11,8 @@ namespace Avalonia.Skia
{
internal class DrawingContextImpl : IDrawingContextImpl
{
private readonly double _dpiX;
private readonly double _dpiY;
private readonly Matrix? _postTransform;
private readonly IDisposable[] _disposables;
private readonly IVisualBrushRenderer _visualBrushRenderer;
@ -20,12 +22,16 @@ namespace Avalonia.Skia
public DrawingContextImpl(
SKCanvas canvas,
double dpiX,
double dpiY,
IVisualBrushRenderer visualBrushRenderer,
Matrix? postTransform = null,
params IDisposable[] disposables)
{
if (postTransform.HasValue && !postTransform.Value.IsIdentity)
_postTransform = postTransform;
_dpiX = dpiX;
_dpiY = dpiY;
if (dpiX != 96 || dpiY != 96)
_postTransform = Matrix.CreateScale(dpiX / 96, dpiY / 96);
_visualBrushRenderer = visualBrushRenderer;
_disposables = disposables;
Canvas = canvas;
@ -217,7 +223,7 @@ namespace Avalonia.Skia
if (intermediateSize.Width >= 1 && intermediateSize.Height >= 1)
{
var intermediate = new BitmapImpl((int)intermediateSize.Width, (int)intermediateSize.Height);
var intermediate = new BitmapImpl((int)intermediateSize.Width, (int)intermediateSize.Height, _dpiX, _dpiY);
using (var ctx = intermediate.CreateDrawingContext(_visualBrushRenderer))
{
@ -242,7 +248,7 @@ namespace Avalonia.Skia
if (tileBrush != null && tileBrushImage != null)
{
var calc = new TileBrushCalculator(tileBrush, new Size(tileBrushImage.PixelWidth, tileBrushImage.PixelHeight), targetSize);
var bitmap = new BitmapImpl((int)calc.IntermediateSize.Width, (int)calc.IntermediateSize.Height);
var bitmap = new BitmapImpl((int)calc.IntermediateSize.Width, (int)calc.IntermediateSize.Height, _dpiX, _dpiY);
rv.AddDisposable(bitmap);
using (var context = bitmap.CreateDrawingContext(null))
{

3
src/Skia/Avalonia.Skia/FramebufferRenderTarget.cs

@ -76,8 +76,7 @@ namespace Avalonia.Skia
canvas.RestoreToCount(0);
canvas.Save();
canvas.ResetMatrix();
var scale = Matrix.CreateScale(fb.Dpi.Width / 96, fb.Dpi.Height / 96);
return new DrawingContextImpl(canvas, visualBrushRenderer, scale, canvas, surface, shim, fb);
return new DrawingContextImpl(canvas, fb.Dpi.Width, fb.Dpi.Height, visualBrushRenderer, canvas, surface, shim, fb);
}
}
}

4
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -77,7 +77,7 @@ namespace Avalonia.Skia
if (height < 1)
throw new ArgumentException("Height can't be less than 1", nameof(height));
return new BitmapImpl(width, height);
return new BitmapImpl(width, height, dpiX, dpiY);
}
public virtual IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces)
@ -90,7 +90,7 @@ namespace Avalonia.Skia
public IWritableBitmapImpl CreateWritableBitmap(int width, int height, PixelFormat? format = null)
{
return new BitmapImpl(width, height, format);
return new BitmapImpl(width, height, 96, 96, format);
}
}
}

Loading…
Cancel
Save