How can I render Chinese characters using skia under Android

1,538 views
Skip to first unread message

Liang Jian

unread,
Dec 12, 2017, 1:11:26 AM12/12/17
to skia-d...@googlegroups.com
    Hello,
    I build libskia android with the following instructions:

bin/gn gen out/android-armv7 --args='ndk="E:\software\sdk\android\windows\android-ndk-r16b" ndk_api=16 target_cpu="arm" extra_cflags=["-Oz","-fvisibility=hidden","-fvisibility-inlines-hidden"] is_official_build=true skia_use_system_expat=false skia_use_system_freetype2=false skia_use_system_icu=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false'
ninja -C out/android-armv7

    Every thing works fine, but when I draw Chinese characters using Canvas it draw two black box instead of the Chinese characters while drawing English character works well. I draw the text like the following:

    SkCanvas canvas(bitmap);
    canvas.clear(SK_ColorRED);

    SkPaint paint;
    const char str[] = {0xE4, 0xBD, 0xA0, 0xE5, 0xA5, 0xBD, 0x0};//"你好";
    paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
    paint.setFlags(paint.getFlags() | SkPaint::kAntiAlias_Flag | SkPaint::kDevKernText_Flag);
    paint.setTextSize(SkIntToScalar(256));
    canvas.drawString(str, SkIntToScalar(0), SkIntToScalar(256), paint);

   What is wrong with my code? Any suggestion is welcome, Thanks!

Hal Canary

unread,
Dec 12, 2017, 6:25:13 AM12/12/17
to skia-discuss
Skia provides interfaces to draw glyphs, but does not implement a text shaper. Skia’s client’s often use HarfBuzz to generate the glyphs and their positions, including kerning.

Here is an example of how to use Skia and HarfBuzz together. 
In the example, a SkTypeface and a hb_face_t are created using the same font. The HarfBuzz face is used to shape unicode text into a sequence of glyphs and positions, and the SkTypeface can then be used to draw those glyphs.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss+unsubscribe@googlegroups.com.
To post to this group, send email to skia-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/skia-discuss.
For more options, visit https://groups.google.com/d/optout.

Liang Jian

unread,
Dec 12, 2017, 7:35:29 AM12/12/17
to skia-d...@googlegroups.com
    Thank you for the reply.
    I am confused now, do you mean without HarfBuzz, libskia can't draw unicode text under Android with SKCanvas?
    But according to my test, I can successfully draw Chinese characters with an external font file like the following:

    sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
    sk_sp<SkTypeface> defaultTypeface = fm->makeFromFile("path/to/fontfiles/fangzhenghuali_GBK");
    paint.setTypeface(defaultTypeface);

    const char str[] = "\xe4\xbd\xa0\xe5\xa5\xbd"; //你好
    paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
    paint.setFlags(paint.getFlags() | SkPaint::kAntiAlias_Flag | SkPaint::kDevKernText_Flag);
    paint.setTextSize(SkIntToScalar(256));

    canvas.drawString(str, SkIntToScalar(0), SkIntToScalar(256), paint);

   I guess the problem is libskia Android can't find the proper simplified Chinese font files on startup.

Robert Phillips

unread,
Dec 12, 2017, 7:35:43 AM12/12/17
to skia-d...@googlegroups.com
You also probably need to select an appropriate Chinese font (e.g., NotoSansCJK-Regular.ttc on Android). The SampleChineseFling.cpp sample shows how to set this up for various platforms.

Liang Jian

unread,
Dec 12, 2017, 7:36:47 AM12/12/17
to skia-d...@googlegroups.com
    sorry:
    sk_sp<SkTypeface> defaultTypeface = fm->makeFromFile("path/to/fontfiles/fangzhenghuali_GBK");
    should be 
    sk_sp<SkTypeface> defaultTypeface = fm->makeFromFile("path/to/fontfiles/fangzhenghuali_GBK.TTF");

Liang Jian

unread,
Dec 12, 2017, 7:54:49 AM12/12/17
to skia-d...@googlegroups.com
    Hi Robert, thank you for the reply. I do have rendered Chinese characters with an external TTF font file. But the problem is I want to use the Chinese font file installed in the Android system, and I have no idea How to find the proper Chinese font files in the system. It seems that the default font manager in Android: SkFontMgr_Android has the capability to search all the font files (and even the fallback font files) in the system, but it just can't draw any Chinese character by default, this is strange. Under Windows, I can draw Chinese characters using SkCanvas without any extra effort.

Hal Canary

unread,
Dec 12, 2017, 7:54:50 AM12/12/17
to skia-discuss
Yes, in either case you have to provide the correct font to Skia. Skia never does this automatically. The default font and the utf8 mode exist only for our internal testing. 

Liang Jian

unread,
Dec 12, 2017, 8:09:33 AM12/12/17
to skia-d...@googlegroups.com
    Thanks, Is there any library to handle font files management under Android? will HarfBuzz handle this ?

ykt

unread,
Jun 26, 2018, 10:50:18 PM6/26/18
to skia-discuss
Did you solve it? I have the same problem,I can iterate through the fonts, but still can't show Chinese, here is my code:

sk_sp<SkFontMgr> pMgr = (SkFontMgr::RefDefault());
int FamilyCount = pMgr->countFamilies();
for (int j = 0; j < FamilyCount; j++) {
SkString FamilyName;
pMgr->getFamilyName(j, &FamilyName);
sk_sp<SkTypeface> typeface = SkTypeface::MakeFromName(FamilyName.c_str(), SkFontStyle::Normal());
if (typeface == nullptr) {
continue;
}
typeface->charsToGlyphs(text + Offset, SkTypeface::kUTF8_Encoding, pInfo.glyphs + i, 1);
if (*(pInfo.glyphs + i) != 0) {
break;
}
}

在 2017年12月12日星期二 UTC+8下午9:09:33,liang jian写道:
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.

To post to this group, send email to skia-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/skia-discuss.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.

To post to this group, send email to skia-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/skia-discuss.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.

To post to this group, send email to skia-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/skia-discuss.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.

Ben Wagner

unread,
Jun 27, 2018, 10:50:21 AM6/27/18
to skia-d...@googlegroups.com
If you're looking to create a SkTypeface which supports a particular unicode codepoint, use SkFontMgr::matchFamilyStyleCharacter . This can (and does) return SkTypefaces which cannot be accessed through the list of families.
Reply all
Reply to author
Forward
0 new messages