@@ -17,6 +17,7 @@ internal class SkiaRenderContext : IRenderContext, IDisposable
1717 private readonly Dictionary < FontDescriptor , SKShaper > shaperCache = new ( ) ;
1818 private readonly Dictionary < FontDescriptor , SKTypeface > typefaceCache = new ( ) ;
1919 private SKPaint paint = new ( ) ;
20+ private SKFont font = new ( ) ;
2021 private SKPath path = new ( ) ;
2122
2223 /// <summary>
@@ -130,21 +131,30 @@ public void DrawImage(
130131 double destWidth ,
131132 double destHeight ,
132133 double opacity ,
133- bool interpolate )
134+ bool interpolate = false )
134135 {
135136 if ( source == null )
136137 {
137138 return ;
138139 }
139140
140141 var bytes = source . GetData ( ) ;
141- var image = SKBitmap . Decode ( bytes ) ;
142+ var bmp = SKBitmap . Decode ( bytes ) ;
142143
143144 var src = new SKRect ( ( float ) srcX , ( float ) srcY , ( float ) ( srcX + srcWidth ) , ( float ) ( srcY + srcHeight ) ) ;
144145 var dest = new SKRect ( this . Convert ( destX ) , this . Convert ( destY ) , this . Convert ( destX + destWidth ) , this . Convert ( destY + destHeight ) ) ;
145146
146- var paint = this . GetImagePaint ( opacity , interpolate ) ;
147- this . SkCanvas . DrawBitmap ( image , src , dest , paint ) ;
147+ var paint = this . GetImagePaint ( opacity ) ;
148+ if ( interpolate )
149+ {
150+ var sampling = new SKSamplingOptions ( SKFilterMode . Linear , SKMipmapMode . Linear ) ;
151+ var img = SKImage . FromBitmap ( bmp ) ;
152+ this . SkCanvas . DrawImage ( img , src , dest , sampling , paint ) ;
153+ }
154+ else
155+ {
156+ this . SkCanvas . DrawBitmap ( bmp , src , dest , paint ) ;
157+ }
148158 }
149159
150160 /// <inheritdoc/>
@@ -364,14 +374,15 @@ public void DrawText(
364374 return ;
365375 }
366376
367- var paint = this . GetTextPaint ( fontFamily , fontSize , fontWeight , out var shaper ) ;
377+ var font = this . GetTextFont ( fontFamily , fontSize , fontWeight , out var shaper ) ;
378+ var paint = this . GetTextPaint ( ) ;
368379 paint . Color = fill . ToSKColor ( ) ;
369380
370381 var x = this . Convert ( p . X ) ;
371382 var y = this . Convert ( p . Y ) ;
372383
373384 var lines = StringHelper . SplitLines ( text ) ;
374- var lineHeight = paint . GetFontMetrics ( out var metrics ) ;
385+ var lineHeight = font . GetFontMetrics ( out var metrics ) ;
375386
376387 var deltaY = verticalAlignment switch
377388 {
@@ -389,7 +400,7 @@ public void DrawText(
389400 {
390401 if ( this . UseTextShaping )
391402 {
392- var width = this . MeasureText ( line , shaper , paint ) ;
403+ var width = this . MeasureText ( line , shaper , font ) ;
393404 var deltaX = horizontalAlignment switch
394405 {
395406 HorizontalAlignment . Left => 0 ,
@@ -398,20 +409,19 @@ public void DrawText(
398409 _ => throw new ArgumentOutOfRangeException ( nameof ( horizontalAlignment ) )
399410 } ;
400411
401- this . paint . TextAlign = SKTextAlign . Left ;
402- this . SkCanvas . DrawShapedText ( shaper , line , deltaX , deltaY , paint ) ;
412+ this . SkCanvas . DrawShapedText ( shaper , line , deltaX , deltaY , SKTextAlign . Left , font , paint ) ;
403413 }
404414 else
405415 {
406- paint . TextAlign = horizontalAlignment switch
416+ var align = horizontalAlignment switch
407417 {
408418 HorizontalAlignment . Left => SKTextAlign . Left ,
409419 HorizontalAlignment . Center => SKTextAlign . Center ,
410420 HorizontalAlignment . Right => SKTextAlign . Right ,
411421 _ => throw new ArgumentOutOfRangeException ( nameof ( horizontalAlignment ) )
412422 } ;
413423
414- this . SkCanvas . DrawText ( line , 0 , deltaY , paint ) ;
424+ this . SkCanvas . DrawText ( line , 0 , deltaY , align , font , paint ) ;
415425 }
416426
417427 deltaY += lineHeight ;
@@ -427,9 +437,10 @@ public OxySize MeasureText(string text, string fontFamily = null, double fontSiz
427437 }
428438
429439 var lines = StringHelper . SplitLines ( text ) ;
430- var paint = this . GetTextPaint ( fontFamily , fontSize , fontWeight , out var shaper ) ;
431- var height = paint . GetFontMetrics ( out _ ) * lines . Length ;
432- var width = lines . Max ( line => this . MeasureText ( line , shaper , paint ) ) ;
440+ var font = this . GetTextFont ( fontFamily , fontSize , fontWeight , out var shaper ) ;
441+ var paint = this . GetTextPaint ( ) ;
442+ var height = font . GetFontMetrics ( out _ ) * lines . Length ;
443+ var width = lines . Max ( line => this . MeasureText ( line , shaper , font ) ) ;
433444
434445 return new OxySize ( this . ConvertBack ( width ) , this . ConvertBack ( height ) ) ;
435446 }
@@ -739,12 +750,10 @@ private SKPaint GetFillPaint(OxyColor fillColor, EdgeRenderingMode edgeRendering
739750 /// This modifies and returns the local <see cref="paint"/> instance.
740751 /// </remarks>
741752 /// <param name="opacity">The opacity.</param>
742- /// <param name="interpolate">A value indicating whether interpolation should be used.</param>
743753 /// <returns>The paint.</returns>
744- private SKPaint GetImagePaint ( double opacity , bool interpolate )
754+ private SKPaint GetImagePaint ( double opacity )
745755 {
746756 this . paint . Color = new SKColor ( 0 , 0 , 0 , ( byte ) ( 255 * opacity ) ) ;
747- this . paint . FilterQuality = interpolate ? SKFilterQuality . High : SKFilterQuality . None ;
748757 this . paint . IsAntialias = true ;
749758 return this . paint ;
750759 }
@@ -833,17 +842,17 @@ private SKPaint GetStrokePaint(OxyColor strokeColor, double strokeThickness, Edg
833842 }
834843
835844 /// <summary>
836- /// Gets a <see cref="SKPaint "/> containing information needed to render text.
845+ /// Gets a <see cref="SKFont "/> containing information needed to render text.
837846 /// </summary>
838847 /// <remarks>
839- /// This modifies and returns the local <see cref="paint "/> instance.
848+ /// This modifies and returns the local <see cref="font "/> instance.
840849 /// </remarks>
841850 /// <param name="fontFamily">The font family.</param>
842851 /// <param name="fontSize">The font size.</param>
843852 /// <param name="fontWeight">The font weight.</param>
844853 /// <param name="shaper">The font shaper.</param>
845- /// <returns>The paint .</returns>
846- private SKPaint GetTextPaint ( string fontFamily , double fontSize , double fontWeight , out SKShaper shaper )
854+ /// <returns>The font .</returns>
855+ private SKFont GetTextFont ( string fontFamily , double fontSize , double fontWeight , out SKShaper shaper )
847856 {
848857 var fontDescriptor = new FontDescriptor ( fontFamily , fontWeight ) ;
849858 if ( ! this . typefaceCache . TryGetValue ( fontDescriptor , out var typeface ) )
@@ -865,12 +874,24 @@ private SKPaint GetTextPaint(string fontFamily, double fontSize, double fontWeig
865874 shaper = null ;
866875 }
867876
868- this . paint . Typeface = typeface ;
869- this . paint . TextSize = this . Convert ( fontSize ) ;
877+ this . font . Typeface = typeface ;
878+ this . font . Size = this . Convert ( fontSize ) ;
879+ this . font . Hinting = this . RendersToScreen ? SKFontHinting . Full : SKFontHinting . None ;
880+ this . font . Subpixel = this . RendersToScreen ;
881+ return this . font ;
882+ }
883+
884+ /// <summary>
885+ /// Gets a <see cref="SKPaint"/> containing information needed to render text.
886+ /// </summary>
887+ /// <remarks>
888+ /// This modifies and returns the local <see cref="paint"/> instance.
889+ /// </remarks>
890+ /// <returns>The paint.</returns>
891+ private SKPaint GetTextPaint ( )
892+ {
870893 this . paint . IsAntialias = true ;
871894 this . paint . Style = SKPaintStyle . Fill ;
872- this . paint . HintingLevel = this . RendersToScreen ? SKPaintHinting . Full : SKPaintHinting . NoHinting ;
873- this . paint . SubpixelText = this . RendersToScreen ;
874895 return this . paint ;
875896 }
876897
@@ -879,36 +900,37 @@ private SKPaint GetTextPaint(string fontFamily, double fontSize, double fontWeig
879900 /// </summary>
880901 /// <param name="text">The text to measure.</param>
881902 /// <param name="shaper">The text shaper.</param>
882- /// <param name="paint ">The paint .</param>
903+ /// <param name="font ">The font .</param>
883904 /// <returns>The width of the text when rendered using the specified shaper and paint.</returns>
884- private float MeasureText ( string text , SKShaper shaper , SKPaint paint )
905+ private float MeasureText ( string text , SKShaper shaper , SKFont font )
885906 {
886907 if ( ! this . UseTextShaping )
887908 {
888- return paint . MeasureText ( text ) ;
909+ return font . MeasureText ( text ) ;
889910 }
890911
891912 // we have to get a bit creative here as SKShaper does not offer a direct overload for this.
892913 // see also https://github.com/mono/SkiaSharp/blob/master/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz.Shared/SKShaper.cs
893914 using var buffer = new HarfBuzzSharp . Buffer ( ) ;
894- switch ( paint . TextEncoding )
895- {
896- case SKTextEncoding . Utf8 :
897- buffer . AddUtf8 ( text ) ;
898- break ;
899- case SKTextEncoding . Utf16 :
900- buffer . AddUtf16 ( text ) ;
901- break ;
902- case SKTextEncoding . Utf32 :
903- buffer . AddUtf32 ( text ) ;
904- break ;
905- default :
906- throw new NotSupportedException ( "TextEncoding is not supported." ) ;
907- }
915+
916+ // switch (paint.TextEncoding)
917+ // {
918+ // case SKTextEncoding.Utf8:
919+ buffer . AddUtf8 ( text ) ;
920+ // break;
921+ // case SKTextEncoding.Utf16:
922+ // buffer.AddUtf16(text);
923+ // break;
924+ // case SKTextEncoding.Utf32:
925+ // buffer.AddUtf32(text);
926+ // break;
927+ // default:
928+ // throw new NotSupportedException("TextEncoding is not supported.");
929+ // }
908930
909931 buffer . GuessSegmentProperties ( ) ;
910- shaper . Shape ( buffer , paint ) ;
911- return buffer . GlyphPositions . Sum ( gp => gp . XAdvance ) * paint . TextSize / 512 ;
932+ shaper . Shape ( buffer , font ) ;
933+ return buffer . GlyphPositions . Sum ( gp => gp . XAdvance ) * font . Size / 512 ;
912934 }
913935
914936 /// <summary>
0 commit comments