Merge "Make sure the Typeface is loaded before calling measureText."
This commit is contained in:
@@ -672,6 +672,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
public static void preloadFontCache() {
|
||||
Paint p = new Paint();
|
||||
p.setAntiAlias(true);
|
||||
// Ensure that the Typeface is loaded here.
|
||||
// Typically, Typeface is preloaded by zygote but not on all devices, e.g. Android Auto.
|
||||
// So, sets Typeface.DEFAULT explicitly here for ensuring that the Typeface is loaded here
|
||||
// since Paint.measureText can not be called without Typeface static initializer.
|
||||
p.setTypeface(Typeface.DEFAULT);
|
||||
// We don't care about the result, just the side-effect of measuring.
|
||||
p.measureText("H");
|
||||
}
|
||||
|
||||
@@ -49,62 +49,10 @@ 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.
|
||||
// TODO: investigate why layouts are being created before Typeface.java
|
||||
// class initialization.
|
||||
static minikin::FontCollection *makeFontCollection() {
|
||||
std::vector<minikin::FontFamily *>typefaces;
|
||||
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<SkTypeface> 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) {
|
||||
if (src == NULL) {
|
||||
pthread_once(&gDefaultTypefaceOnce, getDefaultTypefaceOnce);
|
||||
return gDefaultTypeface;
|
||||
} else {
|
||||
return src;
|
||||
}
|
||||
LOG_ALWAYS_FATAL_IF(gDefaultTypeface == nullptr);
|
||||
return src == nullptr ? gDefaultTypeface : src;
|
||||
}
|
||||
|
||||
Typeface* Typeface::createFromTypeface(Typeface* src, SkTypeface::Style style) {
|
||||
|
||||
Reference in New Issue
Block a user