Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b561774 authored by Seigo Nonaka's avatar Seigo Nonaka Committed by Android (Google) Code Review
Browse files

Merge "Make sure the Typeface is loaded before calling measureText."

parents 3bbe9ab6 e2179925
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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");
    }
+2 −54
Original line number Diff line number Diff line
@@ -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) {