I've been struggling to get color emojis rendering on Ubuntu 20.04 (via WSL). I'm trying to use the Noto Color Emoji font, but they do not show up. I found an old conversation from 2017 that sounds like a similar issue
(
https://groups.google.com/g/skia-discuss/c/1uJoMAvUXXo/m/k_zta3OYAAAJ)
, but the Skia API has changed quite a bit since then, so I'm not sure what else I need to do. I made a similar test app that reproduces the problem that looks like this:
#include "include/core/SkBitmap.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkImage.h"
#include "include/core/SkCanvas.h"
#include "include/codec/SkEncodedImageFormat.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkStream.h"
#include "include/encode/SkJpegEncoder.h"
#include "include/ports/SkFontMgr_empty.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkFont.h"
int main() {
SkBitmap bitmap;
bitmap.allocPixels(SkImageInfo::MakeS32(640, 480, kPremul_SkAlphaType));
SkCanvas canvas(bitmap);
SkPaint paint;
paint.setColor(SK_ColorWHITE);
canvas.drawRect(SkRect::MakeXYWH(0, 0, 640, 480), paint);
sk_sp<SkFontMgr> mgr = SkFontMgr_New_Custom_Empty();
sk_sp<SkTypeface> emojiFace = mgr->makeFromFile("NotoColorEmoji-Regular.ttf");
SkString familyName;
emojiFace->getFamilyName(&familyName);
SkDebugf("Emoji Family name: %s\n", familyName.c_str());
//replace "GT-America-Standard-Regular.otf" with other local font file
sk_sp<SkTypeface> face = mgr->makeFromFile("GT-America-Standard-Regular.otf");
//OR just use a default empty font face
//const char* fontFamily = nullptr; // Default system family, if it exists.
//SkFontStyle fontStyle; // Default is normal weight, normal width, upright slant.
//sk_sp<SkTypeface> face = mgr->legacyMakeTypeface(fontFamily, fontStyle);
face->getFamilyName(&familyName);
SkDebugf("Non-Emoji Family name: %s\n", familyName.c_str());
const char text[] = "Skia";
const char emojiText[] = "A😌😀😬😁😂😃A";
paint.setColor(SK_ColorBLACK);
SkFont font;
font.setTypeface(face);
font.setSize(20);
canvas.drawSimpleText(text,
strlen(text),
SkTextEncoding::kUTF8,
20,
20,
font,
paint);
SkFont emojiFont;
font.setTypeface(emojiFace);
font.setSize(20);
SkPaint emojiPaint;
canvas.drawSimpleText(emojiText,
strlen(emojiText),
SkTextEncoding::kUTF8,
20,
40,
emojiFont,
emojiPaint);
SkFILEWStream output("test.jpg");
SkPixmap pixmap;
auto opts = SkJpegEncoder::Options{};
opts.fQuality = 90;
if (canvas.peekPixels(&pixmap)) {
if (!SkJpegEncoder::Encode(&output, pixmap, opts)) {
SkDebugf("Cannot write output\n");
}
SkDebugf("Wrote image\n");
} else {
SkDebugf("Cannot readback on surface\n");
}
return 0;
}
I'm pointed to the current latest commit in the github mirror of the Skia code (8ad03dfe4e2eea42ddded1df0d38613b329a2095) and am building skia with the following commands:
gn gen out/so --args="is_component_build=true is_debug=true"
ninja -C out/so skia
then compiling my test app (from one directory up from the skia directory) like this:
c++ emoji_test.cpp -g -o emoji_test -std=c++17 -Iskia -Lskia/out/so/ -lskia -Wl,-rpath skia/out/so -DSK_SAMPLES_FOR_X
It doesn't look like SK_SAMPLES_FOR_X is recognized anymore, but I left it in. Note that you'll need to put
NotoColorEmoji-Regular.ttf in the same directory as the executable and another font file (I was using GT-America) will also need to be added to the non-emoji test string.
It may also be worth noting that I first noticed this issue while using SKParagraph to lay out text including emojis, but this is the simplest reproduction case I could make. Thank you for any help/