special character crash - skshaper building textblob in windows

47 views
Skip to first unread message

Xinhua Chen

unread,
May 13, 2022, 3:22:08 AMMay 13
to skia-discuss
Dear every one, i try to use skshaper to build textblob for my multi-platform program, i input 6° ,it is ok on the macos.But It crash on the windows. and then i delete  °  special character ,it can be display on the windows. I want to know whether it is bug for skia. if i want to input some special characters and can display right on the windows, how to do it .Thanks for your help.Give my best regards!

Roni Keller

unread,
Jun 3, 2022, 3:22:40 AMJun 3
to skia-discuss
Sorry, I'm a little late to the party...

We are drawing all kind of special characters successfully under Windows. So, I do not think that it is a bug from Skia.

It's hard to say what goes wrong without an example. But just a wild guess.
Since you encountering the issue especially with Windows: perhaps you are trying to pass an ANSI (Codepage Windows-1251) character to SkShaper? It expects an UTF-8 string.
In your case the "Degree" character is represented as 0xB0 in Windows-1251, which is an invalid UTF-8 symbol. I don't know how SkShaper reacts on an invalid UTF-8 symbol, but I would assume that it should not crash (I have only experience with SkTextBlob). But perhaps your crash is a follow up error?

It's just a guess on my part.
Regards
Roni

Xinhua Chen

unread,
Jun 7, 2022, 10:24:39 AMJun 7
to skia-discuss
Thank you very much for your reply. Indeed, i use 0xB0 to represent the degree character. If i want to right render degree character in the windows, i need how to deal it? 

Xinhua Chen

unread,
Jun 7, 2022, 10:43:34 AMJun 7
to skia-discuss
test main code as below:  

 static const char gText[] =
        "6° test\n";

 void HelloWorld::drawTestDegree(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
    fShaper = SkShaper::Make();
     SkAutoCanvasRestore acr(canvas, true);
    SkScalar margin = 20;
    SkPaint paint;
    paint.setColor(fg);

    for (int i = 23; i < 24; i += 2) {
        SkShaper::PurgeCaches();
        SkTextBlobBuilderRunHandler builder(gText, {margin, margin});
        SkFont srcFont(nullptr, SkIntToScalar(i));
        srcFont.setEdging(SkFont::Edging::kSubpixelAntiAlias);
        srcFont.setSubpixel(true);
        const char* utf8 = gText;
        size_t utf8Bytes = sizeof(gText) - 1;

        std::unique_ptr<SkShaper::BiDiRunIterator> bidi(
                SkShaper::MakeBiDiRunIterator(utf8, utf8Bytes, 0xfe));
        if (!bidi) {
            return;
        }

        std::unique_ptr<SkShaper::LanguageRunIterator> language(
                SkShaper::MakeStdLanguageRunIterator(utf8, utf8Bytes));
        if (!language) {
            return;
        }

        SkFourByteTag undeterminedScript = SkSetFourByteTag('Z', 'y', 'y', 'y');
        std::unique_ptr<SkShaper::ScriptRunIterator> script(
                SkShaper::MakeScriptRunIterator(utf8, utf8Bytes, undeterminedScript));
        if (!script) {
            return;
        }

        std::unique_ptr<SkShaper::FontRunIterator> font(
                SkShaper::MakeFontMgrRunIterator(utf8,
                                                 utf8Bytes,
                                                 srcFont,
                                                 SkFontMgr::RefDefault(),
                                                 "STENCIL",
                                                 SkFontStyle::Bold(),
                                                 &*language));
        if (!font) {
            return;
        }

        fShaper->shape(utf8, utf8Bytes, *font, *bidi, *script, *language, w - margin, &builder);
        sk_sp<SkTextBlob> textblob = builder.makeBlob();
   
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawTextBlob(textblob, 0, 0, paint);

        canvas->translate(0, builder.endPoint().y());
    }
}

Roni Keller

unread,
Jun 8, 2022, 10:31:01 AMJun 8
to skia-discuss
If you are only using static strings, you can make use of the "u8" string literal (at least in Visual Studio) [https://docs.microsoft.com/en-us/cpp/cpp/string-and-character-literals-cpp?view=msvc-170#utf-8-encoded-strings]
If you need to convert an ANSI string to UTF-8 at runtime, you will find a lot of example code online. However, this should be discussed at another place (e.g., Stackoverflow), since this is not Skia related anymore.

Example for u8 string literals:

#include <string>

int main(int argc, char* argv[])
{
    const char text_ANSI[] =   "6° test\n";
    const char text_UTF8[] = u8"6° test\n";

    printf("ANSI: ");
    for(int i = 0; i < strlen(text_ANSI); i++) printf("0x%02X ", (unsigned char)text_ANSI[i]);

    printf("\nUTF8: ");
    for(int i = 0; i < strlen(text_UTF8); i++) printf("0x%02X ", (unsigned char)text_UTF8[i]);

    return(0);
}


Xinhua Chen

unread,
Jun 8, 2022, 9:29:31 PMJun 8
to skia-discuss
Thanks for your reply.  Your suggest is very good.It help me resolve this problem.Give my best regards to you.
Reply all
Reply to author
Forward
0 new messages