diff --git a/Source/OxyPlot.Maui.Skia/OxyPlot.Maui.Skia.csproj b/Source/OxyPlot.Maui.Skia/OxyPlot.Maui.Skia.csproj
index 9b271a6..0891f67 100644
--- a/Source/OxyPlot.Maui.Skia/OxyPlot.Maui.Skia.csproj
+++ b/Source/OxyPlot.Maui.Skia/OxyPlot.Maui.Skia.csproj
@@ -36,8 +36,8 @@
-
-
+
+
diff --git a/Source/OxyPlot.Maui.Skia/SkiaRenderContext.cs b/Source/OxyPlot.Maui.Skia/SkiaRenderContext.cs
index 0c0f383..8bc5a48 100644
--- a/Source/OxyPlot.Maui.Skia/SkiaRenderContext.cs
+++ b/Source/OxyPlot.Maui.Skia/SkiaRenderContext.cs
@@ -17,6 +17,7 @@ internal class SkiaRenderContext : IRenderContext, IDisposable
private readonly Dictionary shaperCache = new();
private readonly Dictionary typefaceCache = new();
private SKPaint paint = new();
+ private SKFont font = new();
private SKPath path = new();
///
@@ -130,7 +131,7 @@ public void DrawImage(
double destWidth,
double destHeight,
double opacity,
- bool interpolate)
+ bool interpolate = false)
{
if (source == null)
{
@@ -138,13 +139,22 @@ public void DrawImage(
}
var bytes = source.GetData();
- var image = SKBitmap.Decode(bytes);
+ var bmp = SKBitmap.Decode(bytes);
var src = new SKRect((float)srcX, (float)srcY, (float)(srcX + srcWidth), (float)(srcY + srcHeight));
var dest = new SKRect(this.Convert(destX), this.Convert(destY), this.Convert(destX + destWidth), this.Convert(destY + destHeight));
- var paint = this.GetImagePaint(opacity, interpolate);
- this.SkCanvas.DrawBitmap(image, src, dest, paint);
+ var paint = this.GetImagePaint(opacity);
+ if (interpolate)
+ {
+ var sampling = new SKSamplingOptions(SKFilterMode.Linear, SKMipmapMode.Linear);
+ var img = SKImage.FromBitmap(bmp);
+ this.SkCanvas.DrawImage(img, src, dest, sampling, paint);
+ }
+ else
+ {
+ this.SkCanvas.DrawBitmap(bmp, src, dest, paint);
+ }
}
///
@@ -364,14 +374,15 @@ public void DrawText(
return;
}
- var paint = this.GetTextPaint(fontFamily, fontSize, fontWeight, out var shaper);
+ var font = this.GetTextFont(fontFamily, fontSize, fontWeight, out var shaper);
+ var paint = this.GetTextPaint();
paint.Color = fill.ToSKColor();
var x = this.Convert(p.X);
var y = this.Convert(p.Y);
var lines = StringHelper.SplitLines(text);
- var lineHeight = paint.GetFontMetrics(out var metrics);
+ var lineHeight = font.GetFontMetrics(out var metrics);
var deltaY = verticalAlignment switch
{
@@ -389,7 +400,7 @@ public void DrawText(
{
if (this.UseTextShaping)
{
- var width = this.MeasureText(line, shaper, paint);
+ var width = this.MeasureText(line, shaper, font);
var deltaX = horizontalAlignment switch
{
HorizontalAlignment.Left => 0,
@@ -398,12 +409,11 @@ public void DrawText(
_ => throw new ArgumentOutOfRangeException(nameof(horizontalAlignment))
};
- this.paint.TextAlign = SKTextAlign.Left;
- this.SkCanvas.DrawShapedText(shaper, line, deltaX, deltaY, paint);
+ this.SkCanvas.DrawShapedText(shaper, line, deltaX, deltaY, SKTextAlign.Left, font, paint);
}
else
{
- paint.TextAlign = horizontalAlignment switch
+ var align = horizontalAlignment switch
{
HorizontalAlignment.Left => SKTextAlign.Left,
HorizontalAlignment.Center => SKTextAlign.Center,
@@ -411,7 +421,7 @@ public void DrawText(
_ => throw new ArgumentOutOfRangeException(nameof(horizontalAlignment))
};
- this.SkCanvas.DrawText(line, 0, deltaY, paint);
+ this.SkCanvas.DrawText(line, 0, deltaY, align, font, paint);
}
deltaY += lineHeight;
@@ -427,9 +437,10 @@ public OxySize MeasureText(string text, string fontFamily = null, double fontSiz
}
var lines = StringHelper.SplitLines(text);
- var paint = this.GetTextPaint(fontFamily, fontSize, fontWeight, out var shaper);
- var height = paint.GetFontMetrics(out _) * lines.Length;
- var width = lines.Max(line => this.MeasureText(line, shaper, paint));
+ var font = this.GetTextFont(fontFamily, fontSize, fontWeight, out var shaper);
+ var paint = this.GetTextPaint();
+ var height = font.GetFontMetrics(out _) * lines.Length;
+ var width = lines.Max(line => this.MeasureText(line, shaper, font));
return new OxySize(this.ConvertBack(width), this.ConvertBack(height));
}
@@ -739,12 +750,10 @@ private SKPaint GetFillPaint(OxyColor fillColor, EdgeRenderingMode edgeRendering
/// This modifies and returns the local instance.
///
/// The opacity.
- /// A value indicating whether interpolation should be used.
/// The paint.
- private SKPaint GetImagePaint(double opacity, bool interpolate)
+ private SKPaint GetImagePaint(double opacity)
{
this.paint.Color = new SKColor(0, 0, 0, (byte)(255 * opacity));
- this.paint.FilterQuality = interpolate ? SKFilterQuality.High : SKFilterQuality.None;
this.paint.IsAntialias = true;
return this.paint;
}
@@ -833,17 +842,17 @@ private SKPaint GetStrokePaint(OxyColor strokeColor, double strokeThickness, Edg
}
///
- /// Gets a containing information needed to render text.
+ /// Gets a containing information needed to render text.
///
///
- /// This modifies and returns the local instance.
+ /// This modifies and returns the local instance.
///
/// The font family.
/// The font size.
/// The font weight.
/// The font shaper.
- /// The paint.
- private SKPaint GetTextPaint(string fontFamily, double fontSize, double fontWeight, out SKShaper shaper)
+ /// The font.
+ private SKFont GetTextFont(string fontFamily, double fontSize, double fontWeight, out SKShaper shaper)
{
var fontDescriptor = new FontDescriptor(fontFamily, fontWeight);
if (!this.typefaceCache.TryGetValue(fontDescriptor, out var typeface))
@@ -865,12 +874,24 @@ private SKPaint GetTextPaint(string fontFamily, double fontSize, double fontWeig
shaper = null;
}
- this.paint.Typeface = typeface;
- this.paint.TextSize = this.Convert(fontSize);
+ this.font.Typeface = typeface;
+ this.font.Size = this.Convert(fontSize);
+ this.font.Hinting = this.RendersToScreen ? SKFontHinting.Full : SKFontHinting.None;
+ this.font.Subpixel = this.RendersToScreen;
+ return this.font;
+ }
+
+ ///
+ /// Gets a containing information needed to render text.
+ ///
+ ///
+ /// This modifies and returns the local instance.
+ ///
+ /// The paint.
+ private SKPaint GetTextPaint()
+ {
this.paint.IsAntialias = true;
this.paint.Style = SKPaintStyle.Fill;
- this.paint.HintingLevel = this.RendersToScreen ? SKPaintHinting.Full : SKPaintHinting.NoHinting;
- this.paint.SubpixelText = this.RendersToScreen;
return this.paint;
}
@@ -879,36 +900,37 @@ private SKPaint GetTextPaint(string fontFamily, double fontSize, double fontWeig
///
/// The text to measure.
/// The text shaper.
- /// The paint.
+ /// The font.
/// The width of the text when rendered using the specified shaper and paint.
- private float MeasureText(string text, SKShaper shaper, SKPaint paint)
+ private float MeasureText(string text, SKShaper shaper, SKFont font)
{
if (!this.UseTextShaping)
{
- return paint.MeasureText(text);
+ return font.MeasureText(text);
}
// we have to get a bit creative here as SKShaper does not offer a direct overload for this.
// see also https://github.com/mono/SkiaSharp/blob/master/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz.Shared/SKShaper.cs
using var buffer = new HarfBuzzSharp.Buffer();
- switch (paint.TextEncoding)
- {
- case SKTextEncoding.Utf8:
- buffer.AddUtf8(text);
- break;
- case SKTextEncoding.Utf16:
- buffer.AddUtf16(text);
- break;
- case SKTextEncoding.Utf32:
- buffer.AddUtf32(text);
- break;
- default:
- throw new NotSupportedException("TextEncoding is not supported.");
- }
+
+ // switch (paint.TextEncoding)
+ // {
+ // case SKTextEncoding.Utf8:
+ buffer.AddUtf8(text);
+ // break;
+ // case SKTextEncoding.Utf16:
+ // buffer.AddUtf16(text);
+ // break;
+ // case SKTextEncoding.Utf32:
+ // buffer.AddUtf32(text);
+ // break;
+ // default:
+ // throw new NotSupportedException("TextEncoding is not supported.");
+ // }
buffer.GuessSegmentProperties();
- shaper.Shape(buffer, paint);
- return buffer.GlyphPositions.Sum(gp => gp.XAdvance) * paint.TextSize / 512;
+ shaper.Shape(buffer, font);
+ return buffer.GlyphPositions.Sum(gp => gp.XAdvance) * font.Size / 512;
}
///