@@ -17,6 +17,7 @@ internal class SkiaRenderContext : IRenderContext, IDisposable
17
17
private readonly Dictionary < FontDescriptor , SKShaper > shaperCache = new ( ) ;
18
18
private readonly Dictionary < FontDescriptor , SKTypeface > typefaceCache = new ( ) ;
19
19
private SKPaint paint = new ( ) ;
20
+ private SKFont font = new ( ) ;
20
21
private SKPath path = new ( ) ;
21
22
22
23
/// <summary>
@@ -130,21 +131,30 @@ public void DrawImage(
130
131
double destWidth ,
131
132
double destHeight ,
132
133
double opacity ,
133
- bool interpolate )
134
+ bool interpolate = false )
134
135
{
135
136
if ( source == null )
136
137
{
137
138
return ;
138
139
}
139
140
140
141
var bytes = source . GetData ( ) ;
141
- var image = SKBitmap . Decode ( bytes ) ;
142
+ var bmp = SKBitmap . Decode ( bytes ) ;
142
143
143
144
var src = new SKRect ( ( float ) srcX , ( float ) srcY , ( float ) ( srcX + srcWidth ) , ( float ) ( srcY + srcHeight ) ) ;
144
145
var dest = new SKRect ( this . Convert ( destX ) , this . Convert ( destY ) , this . Convert ( destX + destWidth ) , this . Convert ( destY + destHeight ) ) ;
145
146
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
+ }
148
158
}
149
159
150
160
/// <inheritdoc/>
@@ -364,14 +374,15 @@ public void DrawText(
364
374
return ;
365
375
}
366
376
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 ( ) ;
368
379
paint . Color = fill . ToSKColor ( ) ;
369
380
370
381
var x = this . Convert ( p . X ) ;
371
382
var y = this . Convert ( p . Y ) ;
372
383
373
384
var lines = StringHelper . SplitLines ( text ) ;
374
- var lineHeight = paint . GetFontMetrics ( out var metrics ) ;
385
+ var lineHeight = font . GetFontMetrics ( out var metrics ) ;
375
386
376
387
var deltaY = verticalAlignment switch
377
388
{
@@ -389,7 +400,7 @@ public void DrawText(
389
400
{
390
401
if ( this . UseTextShaping )
391
402
{
392
- var width = this . MeasureText ( line , shaper , paint ) ;
403
+ var width = this . MeasureText ( line , shaper , font ) ;
393
404
var deltaX = horizontalAlignment switch
394
405
{
395
406
HorizontalAlignment . Left => 0 ,
@@ -398,20 +409,19 @@ public void DrawText(
398
409
_ => throw new ArgumentOutOfRangeException ( nameof ( horizontalAlignment ) )
399
410
} ;
400
411
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 ) ;
403
413
}
404
414
else
405
415
{
406
- paint . TextAlign = horizontalAlignment switch
416
+ var align = horizontalAlignment switch
407
417
{
408
418
HorizontalAlignment . Left => SKTextAlign . Left ,
409
419
HorizontalAlignment . Center => SKTextAlign . Center ,
410
420
HorizontalAlignment . Right => SKTextAlign . Right ,
411
421
_ => throw new ArgumentOutOfRangeException ( nameof ( horizontalAlignment ) )
412
422
} ;
413
423
414
- this . SkCanvas . DrawText ( line , 0 , deltaY , paint ) ;
424
+ this . SkCanvas . DrawText ( line , 0 , deltaY , align , font , paint ) ;
415
425
}
416
426
417
427
deltaY += lineHeight ;
@@ -427,9 +437,10 @@ public OxySize MeasureText(string text, string fontFamily = null, double fontSiz
427
437
}
428
438
429
439
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 ) ) ;
433
444
434
445
return new OxySize ( this . ConvertBack ( width ) , this . ConvertBack ( height ) ) ;
435
446
}
@@ -739,12 +750,10 @@ private SKPaint GetFillPaint(OxyColor fillColor, EdgeRenderingMode edgeRendering
739
750
/// This modifies and returns the local <see cref="paint"/> instance.
740
751
/// </remarks>
741
752
/// <param name="opacity">The opacity.</param>
742
- /// <param name="interpolate">A value indicating whether interpolation should be used.</param>
743
753
/// <returns>The paint.</returns>
744
- private SKPaint GetImagePaint ( double opacity , bool interpolate )
754
+ private SKPaint GetImagePaint ( double opacity )
745
755
{
746
756
this . paint . Color = new SKColor ( 0 , 0 , 0 , ( byte ) ( 255 * opacity ) ) ;
747
- this . paint . FilterQuality = interpolate ? SKFilterQuality . High : SKFilterQuality . None ;
748
757
this . paint . IsAntialias = true ;
749
758
return this . paint ;
750
759
}
@@ -833,17 +842,17 @@ private SKPaint GetStrokePaint(OxyColor strokeColor, double strokeThickness, Edg
833
842
}
834
843
835
844
/// <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.
837
846
/// </summary>
838
847
/// <remarks>
839
- /// This modifies and returns the local <see cref="paint "/> instance.
848
+ /// This modifies and returns the local <see cref="font "/> instance.
840
849
/// </remarks>
841
850
/// <param name="fontFamily">The font family.</param>
842
851
/// <param name="fontSize">The font size.</param>
843
852
/// <param name="fontWeight">The font weight.</param>
844
853
/// <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 )
847
856
{
848
857
var fontDescriptor = new FontDescriptor ( fontFamily , fontWeight ) ;
849
858
if ( ! this . typefaceCache . TryGetValue ( fontDescriptor , out var typeface ) )
@@ -865,12 +874,24 @@ private SKPaint GetTextPaint(string fontFamily, double fontSize, double fontWeig
865
874
shaper = null ;
866
875
}
867
876
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
+ {
870
893
this . paint . IsAntialias = true ;
871
894
this . paint . Style = SKPaintStyle . Fill ;
872
- this . paint . HintingLevel = this . RendersToScreen ? SKPaintHinting . Full : SKPaintHinting . NoHinting ;
873
- this . paint . SubpixelText = this . RendersToScreen ;
874
895
return this . paint ;
875
896
}
876
897
@@ -879,36 +900,37 @@ private SKPaint GetTextPaint(string fontFamily, double fontSize, double fontWeig
879
900
/// </summary>
880
901
/// <param name="text">The text to measure.</param>
881
902
/// <param name="shaper">The text shaper.</param>
882
- /// <param name="paint ">The paint .</param>
903
+ /// <param name="font ">The font .</param>
883
904
/// <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 )
885
906
{
886
907
if ( ! this . UseTextShaping )
887
908
{
888
- return paint . MeasureText ( text ) ;
909
+ return font . MeasureText ( text ) ;
889
910
}
890
911
891
912
// we have to get a bit creative here as SKShaper does not offer a direct overload for this.
892
913
// see also https://github.com/mono/SkiaSharp/blob/master/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz.Shared/SKShaper.cs
893
914
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
+ // }
908
930
909
931
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 ;
912
934
}
913
935
914
936
/// <summary>
0 commit comments