Skiasharp: Migrate to SKFont

Created on 29 Nov 2018  路  10Comments  路  Source: mono/SkiaSharp

Description

Google is deprecating the old ways of drawing text as they are not useful for non-English, non-linear text.

According to them, SKFont is the new text paint, and SKTextBlob is the new string:
https://groups.google.com/forum/#!topic/skia-discuss/qRARbUW2qhw

VS bug #737626

area-libSkiaSharp.native status-skia-update-required type-enhancement type-feature-request

Most helpful comment

@mattleibow it's important to not break existing code that uses DrawText method. We also use SKShaper to deal with non English text. Maybe the wrappers that Mike Reed talked about at that post could help here.

All 10 comments

@mattleibow it's important to not break existing code that uses DrawText method. We also use SKShaper to deal with non English text. Maybe the wrappers that Mike Reed talked about at that post could help here.

@neodynamic I will try to ensure maximum backwards-compatibility. One additional benefit of having this C# wrapper is that we can hide other breaking changes. One specific to not is the rewritten GPU interaction that has no breaking changes at all for the C# consumer.

any updates?

What is the benefit of the current SKFont implementation? I don't think you get anything new from it. That will probably change in the future.

So things have changed, we have to use the new SKFont. But, I think we can keep the old API by doing what Google did here:

class SkXamarinPaint : SkPaint {
    SkFont fFont;
}

https://github.com/aosp-mirror/platform_frameworks_base/blob/master/libs/hwui/hwui/Paint.h#L148

Do we have to live with that overhead or do you still add overloads that accept SKFont? The clean way would be getting rid of those font related members on SKPaint.

I haven't decided just yet. If I keep SkFont hidden, then we are all happy. But, doing that may make future updates harder as we will have a bigger jump.

I was also thinking of converting SKPaint into a compat wrapper thing and exposing the current SkPaint as an SKBrush and the SkFont as an SKFont. So, at the end of the day, new code uses a SKBrush and SKFont, and existing code can use SKPaint - and all the old members just go paint.Font or paint.Brush.

But, this will be annoying for everyone since they will have to change their usage of SKPaint. We do actually control what we expose to the C API, so adding a font field to paint is no biggie. Or, we could keep that as a "feature". Either use Font for a lightweight thing, but the Paint for all the properties. This will also help with the fact that the TextAlign property has been moved out. So...

Most - in fact all - of the SKFont uses is when using DrawText (which is pretty much useless) and SKTextBlob. So, as you mention having the font overhead for ALL operations is a bit overkill. This is why the wrapper thing may be nice.

Do you have any thoughts on this? I am heading towards the "SKPaint is now a big wrapper for all drawing, there are specific types as well" brain process. Comments?

So, keep the C/C++ code as is, then I do this in C#:

class SKPaint {
    SKFont Font { get; set; }
    SKBrush Brush { get; set; }
    SKTextAlignment TextAlignment { get; set; }

    SKTypeface Typeface {
        get => Font.Typeface;
        set => Font.Typeface = value;
    }

    SKColor Color {
        get => Brush.Color;
        set => Brush.Color = value;
    }
}

class SKCanvas {
    void DrawText(string text, SKPaint paint) =>
        DrawText(text, paint.Brush, paint.Font, paint.TextAlignment);
    void DrawText(string text, SKBrush brush, SKFont font, SKTextAlignment textAlign);
}

class SKTextBlobBuilder {
    void AddUtf16(string text, SKPaint paint) =>
        AddUtf16(text, paint.Font);
    void AddUtf16(string text, SKFont font);
}

That approach would allow me to choose what ever fits my needs best. If I want a lightweight representation for font processing I can just use SKFont and if I just want things on the screen I can use SKPaint. Currently I only use SKPaint when it comes to drawing something with a brush. Everything else is meaningless in terms of text processing.

Included in #986 .

The work was to publicly expose SKFont and then on the native side, add an instance of SkFont to a new SkCompatPaint : SkPaint. Everything should be backwards compatible.

Was this page helpful?
0 / 5 - 0 ratings