diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp index 50bc6c383a0fe..59b1185d90057 100644 --- a/libs/hwui/hwui/Typeface.cpp +++ b/libs/hwui/hwui/Typeface.cpp @@ -49,10 +49,60 @@ static void resolveStyle(Typeface* typeface) { } Typeface* gDefaultTypeface = NULL; +pthread_once_t gDefaultTypefaceOnce = PTHREAD_ONCE_INIT; + +// This installs a default typeface (from a hardcoded path) that allows +// layouts to work (not crash on null pointer) before the default +// typeface is set. This happens if HWUI is used outside of zygote/app_process. +static minikin::FontCollection *makeFontCollection() { + std::vectortypefaces; + const char *fns[] = { + "/system/fonts/Roboto-Regular.ttf", + }; + + minikin::FontFamily *family = new minikin::FontFamily(); + for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) { + const char *fn = fns[i]; + ALOGD("makeFontCollection adding %s", fn); + sk_sp skFace = SkTypeface::MakeFromFile(fn); + if (skFace != NULL) { + // TODO: might be a nice optimization to get access to the underlying font + // data, but would require us opening the file ourselves and passing that + // to the appropriate Create method of SkTypeface. + minikin::MinikinFont *font = new MinikinFontSkia(std::move(skFace), NULL, 0, 0); + family->addFont(font); + font->Unref(); + } else { + ALOGE("failed to create font %s", fn); + } + } + typefaces.push_back(family); + + minikin::FontCollection *result = new minikin::FontCollection(typefaces); + family->Unref(); + return result; +} + +static void getDefaultTypefaceOnce() { + minikin::Layout::init(); + if (gDefaultTypeface == NULL) { + // We expect the client to set a default typeface, but provide a + // default so we can make progress before that happens. + gDefaultTypeface = new Typeface; + gDefaultTypeface->fFontCollection = makeFontCollection(); + gDefaultTypeface->fSkiaStyle = SkTypeface::kNormal; + gDefaultTypeface->fBaseWeight = 400; + resolveStyle(gDefaultTypeface); + } +} Typeface* Typeface::resolveDefault(Typeface* src) { - LOG_ALWAYS_FATAL_IF(gDefaultTypeface == nullptr); - return src == nullptr ? gDefaultTypeface : src; + if (src == NULL) { + pthread_once(&gDefaultTypefaceOnce, getDefaultTypefaceOnce); + return gDefaultTypeface; + } else { + return src; + } } Typeface* Typeface::createFromTypeface(Typeface* src, SkTypeface::Style style) {