From 3b91783868b8c78f7dba8d890633b55c18b9a93e Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Wed, 8 Sep 2021 20:24:54 +0200 Subject: [PATCH] IsAntialias should also control the Edging This is for compatibility and consistency. Before 2.80, the anti-aliasing flag would also affect the font edging. After 2.80, the properties were separate and now we have to make sure the paint updates the edging based on what the anti-aliasing and LCD rendering indicate. --- binding/Binding/SKPaint.cs | 26 ++++++++++-- externals/skia | 2 +- tests/Tests/SKPaintTest.cs | 87 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 4 deletions(-) diff --git a/binding/Binding/SKPaint.cs b/binding/Binding/SKPaint.cs index 391a9814563..e53ed28930b 100644 --- a/binding/Binding/SKPaint.cs +++ b/binding/Binding/SKPaint.cs @@ -14,6 +14,7 @@ public enum SKPaintHinting public unsafe class SKPaint : SKObject, ISKSkipObjectRegistration { private SKFont font; + private bool lcdRenderText; internal SKPaint (IntPtr handle, bool owns) : base (handle, owns) @@ -38,6 +39,8 @@ public SKPaint (SKFont font) if (Handle == IntPtr.Zero) throw new InvalidOperationException ("Unable to create a new SKPaint instance."); + + LcdRenderText = font.Edging == SKFontEdging.SubpixelAntialias; } protected override void Dispose (bool disposing) => @@ -55,7 +58,10 @@ public void Reset () => public bool IsAntialias { get => SkiaApi.sk_paint_is_antialias (Handle); - set => SkiaApi.sk_paint_set_antialias (Handle, value); + set { + SkiaApi.sk_paint_set_antialias (Handle, value); + UpdateFontEdging (value); + } } public bool IsDither { @@ -81,8 +87,11 @@ public bool SubpixelText { } public bool LcdRenderText { - get => GetFont ().Edging == SKFontEdging.SubpixelAntialias; - set => GetFont ().Edging = value ? SKFontEdging.SubpixelAntialias : SKFontEdging.Antialias; + get => lcdRenderText; + set { + lcdRenderText = value; + UpdateFontEdging (IsAntialias); + } } public bool IsEmbeddedBitmapText { @@ -701,6 +710,17 @@ public SKFont ToFont () => internal SKFont GetFont () => font ??= OwnedBy (SKFont.GetObject (SkiaApi.sk_compatpaint_get_font (Handle), false), this); + private void UpdateFontEdging (bool antialias) + { + var edging = SKFontEdging.Alias; + if (antialias) { + edging = lcdRenderText + ? SKFontEdging.SubpixelAntialias + : SKFontEdging.Antialias; + } + GetFont ().Edging = edging; + } + // internal static SKPaint GetObject (IntPtr handle) => diff --git a/externals/skia b/externals/skia index 173debd238b..bdfa2ee20ac 160000 --- a/externals/skia +++ b/externals/skia @@ -1 +1 @@ -Subproject commit 173debd238b1a55ab12f5994c5dc074fd141ccd6 +Subproject commit bdfa2ee20ac9f8aefb4bc7a1aa9d04de510539ad diff --git a/tests/Tests/SKPaintTest.cs b/tests/Tests/SKPaintTest.cs index f3e6349bb02..ed4dd7f8d44 100644 --- a/tests/Tests/SKPaintTest.cs +++ b/tests/Tests/SKPaintTest.cs @@ -554,5 +554,92 @@ public void GetTextPathSucceedsForEmtptyString() Assert.NotNull(paint.GetTextPath("", 0, 0)); } + + [SkippableTheory] + [InlineData(true, true, SKFontEdging.SubpixelAntialias)] + [InlineData(false, true, SKFontEdging.Alias)] + [InlineData(true, false, SKFontEdging.Antialias)] + [InlineData(false, false, SKFontEdging.Alias)] + public void UpdatingPropertiesIsAntialiasLcdRenderText(bool isAntialias, bool lcd, SKFontEdging newEdging) + { + var paint = new SKPaint(); + + paint.IsAntialias = isAntialias; + paint.LcdRenderText = lcd; + + Assert.Equal(newEdging, paint.GetFont().Edging); + } + + [SkippableTheory] + [InlineData(true, true, SKFontEdging.SubpixelAntialias)] + [InlineData(false, true, SKFontEdging.Alias)] + [InlineData(true, false, SKFontEdging.Antialias)] + [InlineData(false, false, SKFontEdging.Alias)] + public void UpdatingPropertiesLcdRenderTextIsAntialias(bool isAntialias, bool lcd, SKFontEdging newEdging) + { + var paint = new SKPaint(); + + paint.LcdRenderText = lcd; + paint.IsAntialias = isAntialias; + + Assert.Equal(newEdging, paint.GetFont().Edging); + } + + [SkippableFact] + public void PaintWithSubpixelEdgingIsPreserved() + { + var font = new SKFont(); + font.Edging = SKFontEdging.SubpixelAntialias; + + var paint = new SKPaint(font); + + Assert.True(paint.LcdRenderText); + Assert.False(paint.IsAntialias); + Assert.Equal(SKFontEdging.Alias, paint.GetFont().Edging); + + paint.IsAntialias = true; + + Assert.True(paint.LcdRenderText); + Assert.True(paint.IsAntialias); + Assert.Equal(SKFontEdging.SubpixelAntialias, paint.GetFont().Edging); + } + + [SkippableFact] + public void PaintWithAntialiasEdgingIsPreserved() + { + var font = new SKFont(); + font.Edging = SKFontEdging.Antialias; + + var paint = new SKPaint(font); + + Assert.False(paint.LcdRenderText); + Assert.False(paint.IsAntialias); + Assert.Equal(SKFontEdging.Alias, paint.GetFont().Edging); + + paint.IsAntialias = true; + + Assert.False(paint.LcdRenderText); + Assert.True(paint.IsAntialias); + Assert.Equal(SKFontEdging.Antialias, paint.GetFont().Edging); + } + + [SkippableFact] + public void PaintWithAliasEdgingIsPreserved() + { + var font = new SKFont(); + font.Edging = SKFontEdging.Alias; + + var paint = new SKPaint(font); + + Assert.False(paint.LcdRenderText); + Assert.False(paint.IsAntialias); + Assert.Equal(SKFontEdging.Alias, paint.GetFont().Edging); + + paint.IsAntialias = true; + + Assert.False(paint.LcdRenderText); + Assert.True(paint.IsAntialias); + Assert.Equal(SKFontEdging.Antialias, paint.GetFont().Edging); + } } }