From a0a4828614edfd633ab86f04408e7f4e55b491dd Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Sat, 7 Jan 2017 15:33:38 +0900 Subject: [PATCH] Follow minikin::FontFamily constructor signature change. minikin::FontFamily no longer has addFont function, instead it accept vector of Fonts in its constructor. To follow this signature change, holding minikin::Font instance in native and build minikin::FontFamily instance in FontFamily.freeze() method. Test: hwui test passed Change-Id: Id10ca97f6f6f5bbe4999c1ad2736423a204d6e87 --- core/jni/android/graphics/FontFamily.cpp | 74 ++++++++++++++++++-------- graphics/java/android/graphics/FontFamily.java | 49 +++++++++++------ graphics/java/android/graphics/Typeface.java | 3 ++ libs/hwui/hwui/Typeface.cpp | 4 +- 4 files changed, 91 insertions(+), 39 deletions(-) diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp index 15e7165210ae..adee2fd717b7 100644 --- a/core/jni/android/graphics/FontFamily.cpp +++ b/core/jni/android/graphics/FontFamily.cpp @@ -39,27 +39,54 @@ namespace android { -static jlong FontFamily_create(JNIEnv* env, jobject clazz, jstring lang, jint variant) { - if (lang == NULL) { - return (jlong)new minikin::FontFamily(variant); +struct NativeFamilyBuilder { + uint32_t langId; + int variant; + std::vector fonts; +}; + +static jlong FontFamily_initBuilder(JNIEnv* env, jobject clazz, jstring lang, jint variant) { + NativeFamilyBuilder* builder = new NativeFamilyBuilder(); + if (lang != nullptr) { + ScopedUtfChars str(env, lang); + builder->langId = minikin::FontStyle::registerLanguageList(str.c_str()); + } else { + builder->langId = minikin::FontStyle::registerLanguageList(""); + } + builder->variant = variant; + return reinterpret_cast(builder); +} + +static jlong FontFamily_create(jlong builderPtr) { + if (builderPtr == 0) { + return 0; } - ScopedUtfChars str(env, lang); - uint32_t langId = minikin::FontStyle::registerLanguageList(str.c_str()); - return (jlong)new minikin::FontFamily(langId, variant); + NativeFamilyBuilder* builder = reinterpret_cast(builderPtr); + minikin::FontFamily* family = new minikin::FontFamily( + builder->langId, builder->variant, std::move(builder->fonts)); + delete builder; + return reinterpret_cast(family); } -static void FontFamily_unref(JNIEnv* env, jobject clazz, jlong familyPtr) { +static void FontFamily_unref(jlong familyPtr) { minikin::FontFamily* fontFamily = reinterpret_cast(familyPtr); fontFamily->Unref(); } -static jboolean addSkTypeface(minikin::FontFamily* family, sk_sp face, - const void* fontData, size_t fontSize, int ttcIndex) { +static void addSkTypeface(jlong builderPtr, sk_sp face, const void* fontData, + size_t fontSize, int ttcIndex) { minikin::MinikinFont* minikinFont = new MinikinFontSkia(std::move(face), fontData, fontSize, ttcIndex); - bool result = family->addFont(minikinFont); + NativeFamilyBuilder* builder = reinterpret_cast(builderPtr); + int weight; + bool italic; + if (!minikin::FontFamily::analyzeStyle(minikinFont, &weight, &italic)) { + ALOGE("analyzeStyle failed. Using default style"); + weight = 400; + italic = false; + } + builder->fonts.push_back(minikin::Font(minikinFont, minikin::FontStyle(weight / 100, italic))); minikinFont->Unref(); - return result; } static void release_global_ref(const void* /*data*/, void* context) { @@ -85,7 +112,7 @@ static void release_global_ref(const void* /*data*/, void* context) { } } -static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jobject bytebuf, +static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong builderPtr, jobject bytebuf, jint ttcIndex) { NPE_CHECK_RETURN_ZERO(env, bytebuf); const void* fontPtr = env->GetDirectBufferAddress(bytebuf); @@ -112,8 +139,8 @@ static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, ALOGE("addFont failed to create font"); return false; } - minikin::FontFamily* fontFamily = reinterpret_cast(familyPtr); - return addSkTypeface(fontFamily, std::move(face), fontPtr, (size_t)fontSize, ttcIndex); + addSkTypeface(builderPtr, std::move(face), fontPtr, (size_t)fontSize, ttcIndex); + return true; } static struct { @@ -126,7 +153,7 @@ static struct { jfieldID mStyleValue; } gAxisClassInfo; -static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr, +static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong builderPtr, jobject font, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) { NPE_CHECK_RETURN_ZERO(env, font); @@ -178,10 +205,11 @@ static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong ALOGE("addFont failed to create font, invalid request"); return false; } - minikin::FontFamily* fontFamily = reinterpret_cast(familyPtr); minikin::MinikinFont* minikinFont = - new MinikinFontSkia(std::move(face), fontPtr, (size_t)fontSize, ttcIndex); - fontFamily->addFont(minikinFont, minikin::FontStyle(weight / 100, isItalic)); + new MinikinFontSkia(std::move(face), fontPtr, fontSize, ttcIndex); + NativeFamilyBuilder* builder = reinterpret_cast(builderPtr); + builder->fonts.push_back(minikin::Font(minikinFont, + minikin::FontStyle(weight / 100, isItalic))); minikinFont->Unref(); return true; } @@ -190,7 +218,7 @@ static void releaseAsset(const void* ptr, void* context) { delete static_cast(context); } -static jboolean FontFamily_addFontFromAsset(JNIEnv* env, jobject, jlong familyPtr, +static jboolean FontFamily_addFontFromAsset(JNIEnv* env, jobject, jlong builderPtr, jobject jassetMgr, jstring jpath) { NPE_CHECK_RETURN_ZERO(env, jassetMgr); NPE_CHECK_RETURN_ZERO(env, jpath); @@ -222,14 +250,16 @@ static jboolean FontFamily_addFontFromAsset(JNIEnv* env, jobject, jlong familyPt ALOGE("addFontFromAsset failed to create font %s", str.c_str()); return false; } - minikin::FontFamily* fontFamily = reinterpret_cast(familyPtr); - return addSkTypeface(fontFamily, std::move(face), buf, bufSize, /* ttcIndex */ 0); + + addSkTypeface(builderPtr, std::move(face), buf, bufSize, 0 /* ttc index */); + return true; } /////////////////////////////////////////////////////////////////////////////// static const JNINativeMethod gFontFamilyMethods[] = { - { "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create }, + { "nInitBuilder", "(Ljava/lang/String;I)J", (void*)FontFamily_initBuilder }, + { "nCreateFamily", "(J)J", (void*)FontFamily_create }, { "nUnrefFamily", "(J)V", (void*)FontFamily_unref }, { "nAddFont", "(JLjava/nio/ByteBuffer;I)Z", (void*)FontFamily_addFont }, { "nAddFontWeightStyle", "(JLjava/nio/ByteBuffer;ILjava/util/List;IZ)Z", diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index e48bf7956df3..2733c43f8b98 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -18,6 +18,7 @@ package android.graphics; import android.content.res.AssetManager; import android.util.Log; +import dalvik.annotation.optimization.CriticalNative; import java.io.FileInputStream; import java.io.IOException; @@ -39,11 +40,11 @@ public class FontFamily { */ public long mNativePtr; + // Points native font family builder. Must be zero after freezing this family. + private long mBuilderPtr; + public FontFamily() { - mNativePtr = nCreateFamily(null, 0); - if (mNativePtr == 0) { - throw new IllegalStateException("error creating native FontFamily"); - } + mBuilderPtr = nInitBuilder(null, 0); } public FontFamily(String lang, String variant) { @@ -53,10 +54,15 @@ public class FontFamily { } else if ("elegant".equals(variant)) { varEnum = 2; } - mNativePtr = nCreateFamily(lang, varEnum); - if (mNativePtr == 0) { - throw new IllegalStateException("error creating native FontFamily"); + mBuilderPtr = nInitBuilder(lang, varEnum); + } + + public void freeze() { + if (mBuilderPtr == 0) { + throw new IllegalStateException("This FontFamily is already frozen"); } + mNativePtr = nCreateFamily(mBuilderPtr); + mBuilderPtr = 0; } @Override @@ -69,11 +75,14 @@ public class FontFamily { } public boolean addFont(String path, int ttcIndex) { + if (mBuilderPtr == 0) { + throw new IllegalStateException("Unable to call addFont after freezing."); + } try (FileInputStream file = new FileInputStream(path)) { FileChannel fileChannel = file.getChannel(); long fontSize = fileChannel.size(); ByteBuffer fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize); - return nAddFont(mNativePtr, fontBuffer, ttcIndex); + return nAddFont(mBuilderPtr, fontBuffer, ttcIndex); } catch (IOException e) { Log.e(TAG, "Error mapping font file " + path); return false; @@ -82,19 +91,29 @@ public class FontFamily { public boolean addFontWeightStyle(ByteBuffer font, int ttcIndex, List axes, int weight, boolean style) { - return nAddFontWeightStyle(mNativePtr, font, ttcIndex, axes, weight, style); + if (mBuilderPtr == 0) { + throw new IllegalStateException("Unable to call addFontWeightStyle after freezing."); + } + return nAddFontWeightStyle(mBuilderPtr, font, ttcIndex, axes, weight, style); } public boolean addFontFromAsset(AssetManager mgr, String path) { - return nAddFontFromAsset(mNativePtr, mgr, path); + if (mBuilderPtr == 0) { + throw new IllegalStateException("Unable to call addFontFromAsset after freezing."); + } + return nAddFontFromAsset(mBuilderPtr, mgr, path); } - private static native long nCreateFamily(String lang, int variant); + private static native long nInitBuilder(String lang, int variant); + + @CriticalNative + private static native long nCreateFamily(long mBuilderPtr); + + @CriticalNative private static native void nUnrefFamily(long nativePtr); - private static native boolean nAddFont(long nativeFamily, ByteBuffer font, int ttcIndex); - private static native boolean nAddFontWeightStyle(long nativeFamily, ByteBuffer font, + private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex); + private static native boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font, int ttcIndex, List listOfAxis, int weight, boolean isItalic); - private static native boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, - String path); + private static native boolean nAddFontFromAsset(long builderPtr, AssetManager mgr, String path); } diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 2886f0dd4a2e..a8c1690e191a 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -196,6 +196,7 @@ public class Typeface { FontFamily fontFamily = new FontFamily(); if (fontFamily.addFontFromAsset(mgr, path)) { + fontFamily.freeze(); FontFamily[] families = { fontFamily }; typeface = createFromFamiliesWithDefault(families); sDynamicTypefaceCache.put(key, typeface); @@ -245,6 +246,7 @@ public class Typeface { if (sFallbackFonts != null) { FontFamily fontFamily = new FontFamily(); if (fontFamily.addFont(path, 0 /* ttcIndex */)) { + fontFamily.freeze(); FontFamily[] families = { fontFamily }; return createFromFamiliesWithDefault(families); } @@ -315,6 +317,7 @@ public class Typeface { Log.e(TAG, "Error creating font " + font.fontName + "#" + font.ttcIndex); } } + fontFamily.freeze(); return fontFamily; } diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp index ca43156e88a1..9041b44db849 100644 --- a/libs/hwui/hwui/Typeface.cpp +++ b/libs/hwui/hwui/Typeface.cpp @@ -130,9 +130,9 @@ void Typeface::setRobotoTypefaceForTest() { sk_sp typeface = SkTypeface::MakeFromStream(fontData.release()); LOG_ALWAYS_FATAL_IF(typeface == nullptr, "Failed to make typeface from %s", kRobotoFont); - minikin::FontFamily* family = new minikin::FontFamily(); minikin::MinikinFont* font = new MinikinFontSkia(std::move(typeface), data, st.st_size, 0); - family->addFont(font); + minikin::FontFamily* family = new minikin::FontFamily( + std::vector({ minikin::Font(font, minikin::FontStyle()) })); font->Unref(); std::vector typefaces = { family }; -- 2.11.0