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

Commit 9a5b61cc authored by Raph Levien's avatar Raph Levien
Browse files

Parsing of XML font configuration files for Minikin

This patch improves Minikin-based font handling, to deal with error
conditions (missing fonts and so on), and also moves the parsing of
fallback_fonts.xml and system_fonts.xml into Java code.

Change-Id: Ib0debdbd56ad3b0196be6d2a35668d711c98f1e5
parent 1a73f732
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -49,6 +49,10 @@ static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr,
    ScopedUtfChars str(env, path);
    ALOGD("addFont %s", str.c_str());
    SkTypeface* face = SkTypeface::CreateFromFile(str.c_str());
    if (face == NULL) {
        ALOGE("addFont failed to create font %s", str.c_str());
        return false;
    }
    MinikinFont* minikinFont = new MinikinFontSkia(face);
    FontFamily* fontFamily = (FontFamily*)familyPtr;
    return fontFamily->addFont(minikinFont);
+6 −0
Original line number Diff line number Diff line
@@ -120,6 +120,11 @@ static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArr
    return reinterpret_cast<jlong>(TypefaceImpl_createFromFamilies(families.get(), families.size()));
}

static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) {
    TypefaceImpl* face = reinterpret_cast<TypefaceImpl*>(faceHandle);
    return TypefaceImpl_setDefault(face);
}

///////////////////////////////////////////////////////////////////////////////

static JNINativeMethod gTypefaceMethods[] = {
@@ -133,6 +138,7 @@ static JNINativeMethod gTypefaceMethods[] = {
                                           (void*)Typeface_createFromFile },
    { "nativeCreateFromArray",    "([J)J",
                                           (void*)Typeface_createFromArray },
    { "nativeSetDefault",         "(J)V",   (void*)Typeface_setDefault },
};

int register_android_graphics_Typeface(JNIEnv* env)
+30 −22
Original line number Diff line number Diff line
@@ -52,38 +52,32 @@ static FontStyle styleFromSkiaStyle(SkTypeface::Style skiaStyle) {
    return FontStyle(weight, italic);
}

TypefaceImpl* gDefaultTypeface;
TypefaceImpl* gDefaultTypeface = NULL;
pthread_once_t gDefaultTypefaceOnce = PTHREAD_ONCE_INIT;

// TODO: this currently builds a font collection from hardcoded paths.
// It will get replaced by an implementation that parses the XML files.
// 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 FontCollection *makeFontCollection() {
    std::vector<FontFamily *>typefaces;
    const char *fns[] = {
        "/system/fonts/Roboto-Regular.ttf",
        "/system/fonts/Roboto-Italic.ttf",
        "/system/fonts/Roboto-BoldItalic.ttf",
        "/system/fonts/Roboto-Light.ttf",
        "/system/fonts/Roboto-Thin.ttf",
        "/system/fonts/Roboto-Bold.ttf",
        "/system/fonts/Roboto-ThinItalic.ttf",
        "/system/fonts/Roboto-LightItalic.ttf"
    };

    FontFamily *family = new FontFamily();
    for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) {
        const char *fn = fns[i];
        ALOGD("makeFontCollection adding %s", fn);
        SkTypeface *skFace = SkTypeface::CreateFromFile(fn);
        if (skFace != NULL) {
            MinikinFont *font = new MinikinFontSkia(skFace);
            family->addFont(font);
        } else {
            ALOGE("failed to create font %s", fn);
        }
    }
    typefaces.push_back(family);

    family = new FontFamily();
    const char *fn = "/system/fonts/NotoSansDevanagari-Regular.ttf";
    SkTypeface *skFace = SkTypeface::CreateFromFile(fn);
    MinikinFont *font = new MinikinFontSkia(skFace);
    family->addFont(font);
    typefaces.push_back(family);

    return new FontCollection(typefaces);
@@ -91,10 +85,14 @@ static FontCollection *makeFontCollection() {

static void getDefaultTypefaceOnce() {
    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 TypefaceImpl;
        gDefaultTypeface->fFontCollection = makeFontCollection();
        gDefaultTypeface->fStyle = FontStyle();
    }
}

TypefaceImpl* TypefaceImpl_resolveDefault(TypefaceImpl* src) {
    if (src == NULL) {
@@ -116,6 +114,9 @@ TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Sty
}

static TypefaceImpl* createFromSkTypeface(SkTypeface* typeface) {
    if (typeface == NULL) {
        return NULL;
    }
    MinikinFont* minikinFont = new MinikinFontSkia(typeface);
    std::vector<FontFamily *> typefaces;
    FontFamily* family = new FontFamily();
@@ -176,6 +177,10 @@ int TypefaceImpl_getStyle(TypefaceImpl* face) {
    return result;
}

void TypefaceImpl_setDefault(TypefaceImpl* face) {
    gDefaultTypeface = face;
}

#else  // USE_MINIKIN

/* Just use SkTypeface instead. */
@@ -219,6 +224,9 @@ int TypefaceImpl_getStyle(TypefaceImpl* face) {
    return face->style();
}

void TypefaceImpl_setDefault(TypefaceImpl* face) {
}

#endif  // USE_MINIKIN

}
+2 −0
Original line number Diff line number Diff line
@@ -61,6 +61,8 @@ void TypefaceImpl_unref(TypefaceImpl* face);

int TypefaceImpl_getStyle(TypefaceImpl* face);

void TypefaceImpl_setDefault(TypefaceImpl* face);

}

#endif  // ANDROID_TYPEFACE_IMPL_H
 No newline at end of file
+8 −0
Original line number Diff line number Diff line
@@ -24,9 +24,17 @@ import java.io.File;
 * @hide
 */
public class FontFamily {
    /**
     * @hide
     */
    public long mNativePtr;

    public FontFamily() {
        mNativePtr = nCreateFamily();
        mNativePtr = nCreateFamily();
        if (mNativePtr == 0) {
            throw new RuntimeException();
        }
    }
    // TODO: finalization

Loading