Loading core/jni/android/graphics/FontFamily.cpp +43 −9 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "GraphicsJNI.h" #include "GraphicsJNI.h" #include <ScopedPrimitiveArray.h> #include <ScopedPrimitiveArray.h> #include <ScopedUtfChars.h> #include <ScopedUtfChars.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_util_AssetManager.h> #include <android_runtime/android_util_AssetManager.h> #include <androidfw/AssetManager.h> #include <androidfw/AssetManager.h> #include "Utils.h" #include "Utils.h" Loading Loading @@ -82,9 +83,32 @@ static struct { jfieldID mStyleValue; jfieldID mStyleValue; } gAxisClassInfo; } gAxisClassInfo; static void release_global_ref(const void* /*data*/, void* context) { JNIEnv* env = AndroidRuntime::getJNIEnv(); bool needToAttach = (env == NULL); if (needToAttach) { JavaVMAttachArgs args; args.version = JNI_VERSION_1_4; args.name = "release_font_data"; args.group = NULL; jint result = AndroidRuntime::getJavaVM()->AttachCurrentThread(&env, &args); if (result != JNI_OK) { ALOGE("failed to attach to thread to release global ref."); return; } } jobject obj = reinterpret_cast<jobject>(context); env->DeleteGlobalRef(obj); if (needToAttach) { AndroidRuntime::getJavaVM()->DetachCurrentThread(); } } static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr, static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr, jstring path, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) { jobject font, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) { NPE_CHECK_RETURN_ZERO(env, path); NPE_CHECK_RETURN_ZERO(env, font); // Declare axis native type. // Declare axis native type. std::unique_ptr<SkFontMgr::FontParameters::Axis[]> skiaAxes; std::unique_ptr<SkFontMgr::FontParameters::Axis[]> skiaAxes; Loading @@ -109,19 +133,29 @@ static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong } } } } ScopedUtfChars str(env, path); void* fontPtr = env->GetDirectBufferAddress(font); SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault()); if (fontPtr == NULL) { std::unique_ptr<SkStreamAsset> fontData(SkStream::NewFromFile(str.c_str())); ALOGE("addFont failed to create font, buffer invalid"); if (!fontData) { return false; ALOGE("addFont failed to open %s", str.c_str()); } jlong fontSize = env->GetDirectBufferCapacity(font); if (fontSize < 0) { ALOGE("addFont failed to create font, buffer size invalid"); return false; return false; } } jobject fontRef = MakeGlobalRefOrDie(env, font); SkAutoTUnref<SkData> data(SkData::NewWithProc(fontPtr, fontSize, release_global_ref, reinterpret_cast<void*>(fontRef))); std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(data)); SkFontMgr::FontParameters params; SkFontMgr::FontParameters params; params.setCollectionIndex(ttcIndex); params.setCollectionIndex(ttcIndex); params.setAxes(skiaAxes.get(), skiaAxesLength); params.setAxes(skiaAxes.get(), skiaAxesLength); SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault()); SkTypeface* face = fm->createFromStream(fontData.release(), params); SkTypeface* face = fm->createFromStream(fontData.release(), params); if (face == NULL) { if (face == NULL) { ALOGE("addFont failed to create font %s#%d", str.c_str(), ttcIndex); ALOGE("addFont failed to create font, invalid request"); return false; return false; } } FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); Loading Loading @@ -175,7 +209,7 @@ static const JNINativeMethod gFontFamilyMethods[] = { { "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create }, { "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create }, { "nUnrefFamily", "(J)V", (void*)FontFamily_unref }, { "nUnrefFamily", "(J)V", (void*)FontFamily_unref }, { "nAddFont", "(JLjava/lang/String;I)Z", (void*)FontFamily_addFont }, { "nAddFont", "(JLjava/lang/String;I)Z", (void*)FontFamily_addFont }, { "nAddFontWeightStyle", "(JLjava/lang/String;ILjava/util/List;IZ)Z", { "nAddFontWeightStyle", "(JLjava/nio/ByteBuffer;ILjava/util/List;IZ)Z", (void*)FontFamily_addFontWeightStyle }, (void*)FontFamily_addFontWeightStyle }, { "nAddFontFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z", { "nAddFontFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z", (void*)FontFamily_addFontFromAsset }, (void*)FontFamily_addFontFromAsset }, Loading graphics/java/android/graphics/FontFamily.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.graphics; import android.content.res.AssetManager; import android.content.res.AssetManager; import java.nio.ByteBuffer; import java.util.List; import java.util.List; /** /** Loading Loading @@ -64,9 +65,9 @@ public class FontFamily { return nAddFont(mNativePtr, path, ttcIndex); return nAddFont(mNativePtr, path, ttcIndex); } } public boolean addFontWeightStyle(String path, int ttcIndex, List<FontListParser.Axis> axes, public boolean addFontWeightStyle(ByteBuffer font, int ttcIndex, List<FontListParser.Axis> axes, int weight, boolean style) { int weight, boolean style) { return nAddFontWeightStyle(mNativePtr, path, ttcIndex, axes, weight, style); return nAddFontWeightStyle(mNativePtr, font, ttcIndex, axes, weight, style); } } public boolean addFontFromAsset(AssetManager mgr, String path) { public boolean addFontFromAsset(AssetManager mgr, String path) { Loading @@ -76,7 +77,7 @@ public class FontFamily { private static native long nCreateFamily(String lang, int variant); private static native long nCreateFamily(String lang, int variant); private static native void nUnrefFamily(long nativePtr); private static native void nUnrefFamily(long nativePtr); private static native boolean nAddFont(long nativeFamily, String path, int ttcIndex); private static native boolean nAddFont(long nativeFamily, String path, int ttcIndex); private static native boolean nAddFontWeightStyle(long nativeFamily, String path, private static native boolean nAddFontWeightStyle(long nativeFamily, ByteBuffer font, int ttcIndex, List<FontListParser.Axis> listOfAxis, int ttcIndex, List<FontListParser.Axis> listOfAxis, int weight, boolean isItalic); int weight, boolean isItalic); private static native boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, private static native boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, Loading graphics/java/android/graphics/Typeface.java +24 −5 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,8 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileNotFoundException; import java.io.IOException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; import java.util.List; import java.util.List; Loading Loading @@ -258,11 +260,26 @@ public class Typeface { mStyle = nativeGetStyle(ni); mStyle = nativeGetStyle(ni); } } private static FontFamily makeFamilyFromParsed(FontListParser.Family family) { private static FontFamily makeFamilyFromParsed(FontListParser.Family family, Map<String, ByteBuffer> bufferForPath) { FontFamily fontFamily = new FontFamily(family.lang, family.variant); FontFamily fontFamily = new FontFamily(family.lang, family.variant); for (FontListParser.Font font : family.fonts) { for (FontListParser.Font font : family.fonts) { fontFamily.addFontWeightStyle(font.fontName, font.ttcIndex, font.axes, ByteBuffer fontBuffer = bufferForPath.get(font.fontName); font.weight, font.isItalic); if (fontBuffer == null) { try (FileInputStream file = new FileInputStream(font.fontName)) { FileChannel fileChannel = file.getChannel(); long fontSize = fileChannel.size(); fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize); bufferForPath.put(font.fontName, fontBuffer); } catch (IOException e) { Log.e(TAG, "Error mapping font file " + font.fontName); continue; } } if (!fontFamily.addFontWeightStyle(fontBuffer, font.ttcIndex, font.axes, font.weight, font.isItalic)) { Log.e(TAG, "Error creating font " + font.fontName + "#" + font.ttcIndex); } } } return fontFamily; return fontFamily; } } Loading @@ -280,13 +297,15 @@ public class Typeface { FileInputStream fontsIn = new FileInputStream(configFilename); FileInputStream fontsIn = new FileInputStream(configFilename); FontListParser.Config fontConfig = FontListParser.parse(fontsIn); FontListParser.Config fontConfig = FontListParser.parse(fontsIn); Map<String, ByteBuffer> bufferForPath = new HashMap<String, ByteBuffer>(); List<FontFamily> familyList = new ArrayList<FontFamily>(); List<FontFamily> familyList = new ArrayList<FontFamily>(); // Note that the default typeface is always present in the fallback list; // Note that the default typeface is always present in the fallback list; // this is an enhancement from pre-Minikin behavior. // this is an enhancement from pre-Minikin behavior. for (int i = 0; i < fontConfig.families.size(); i++) { for (int i = 0; i < fontConfig.families.size(); i++) { FontListParser.Family f = fontConfig.families.get(i); FontListParser.Family f = fontConfig.families.get(i); if (i == 0 || f.name == null) { if (i == 0 || f.name == null) { familyList.add(makeFamilyFromParsed(f)); familyList.add(makeFamilyFromParsed(f, bufferForPath)); } } } } sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]); sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]); Loading @@ -302,7 +321,7 @@ public class Typeface { // duplicating the corresponding FontFamily. // duplicating the corresponding FontFamily. typeface = sDefaultTypeface; typeface = sDefaultTypeface; } else { } else { FontFamily fontFamily = makeFamilyFromParsed(f); FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath); FontFamily[] families = { fontFamily }; FontFamily[] families = { fontFamily }; typeface = Typeface.createFromFamiliesWithDefault(families); typeface = Typeface.createFromFamiliesWithDefault(families); } } Loading Loading
core/jni/android/graphics/FontFamily.cpp +43 −9 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "GraphicsJNI.h" #include "GraphicsJNI.h" #include <ScopedPrimitiveArray.h> #include <ScopedPrimitiveArray.h> #include <ScopedUtfChars.h> #include <ScopedUtfChars.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_util_AssetManager.h> #include <android_runtime/android_util_AssetManager.h> #include <androidfw/AssetManager.h> #include <androidfw/AssetManager.h> #include "Utils.h" #include "Utils.h" Loading Loading @@ -82,9 +83,32 @@ static struct { jfieldID mStyleValue; jfieldID mStyleValue; } gAxisClassInfo; } gAxisClassInfo; static void release_global_ref(const void* /*data*/, void* context) { JNIEnv* env = AndroidRuntime::getJNIEnv(); bool needToAttach = (env == NULL); if (needToAttach) { JavaVMAttachArgs args; args.version = JNI_VERSION_1_4; args.name = "release_font_data"; args.group = NULL; jint result = AndroidRuntime::getJavaVM()->AttachCurrentThread(&env, &args); if (result != JNI_OK) { ALOGE("failed to attach to thread to release global ref."); return; } } jobject obj = reinterpret_cast<jobject>(context); env->DeleteGlobalRef(obj); if (needToAttach) { AndroidRuntime::getJavaVM()->DetachCurrentThread(); } } static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr, static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr, jstring path, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) { jobject font, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) { NPE_CHECK_RETURN_ZERO(env, path); NPE_CHECK_RETURN_ZERO(env, font); // Declare axis native type. // Declare axis native type. std::unique_ptr<SkFontMgr::FontParameters::Axis[]> skiaAxes; std::unique_ptr<SkFontMgr::FontParameters::Axis[]> skiaAxes; Loading @@ -109,19 +133,29 @@ static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong } } } } ScopedUtfChars str(env, path); void* fontPtr = env->GetDirectBufferAddress(font); SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault()); if (fontPtr == NULL) { std::unique_ptr<SkStreamAsset> fontData(SkStream::NewFromFile(str.c_str())); ALOGE("addFont failed to create font, buffer invalid"); if (!fontData) { return false; ALOGE("addFont failed to open %s", str.c_str()); } jlong fontSize = env->GetDirectBufferCapacity(font); if (fontSize < 0) { ALOGE("addFont failed to create font, buffer size invalid"); return false; return false; } } jobject fontRef = MakeGlobalRefOrDie(env, font); SkAutoTUnref<SkData> data(SkData::NewWithProc(fontPtr, fontSize, release_global_ref, reinterpret_cast<void*>(fontRef))); std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(data)); SkFontMgr::FontParameters params; SkFontMgr::FontParameters params; params.setCollectionIndex(ttcIndex); params.setCollectionIndex(ttcIndex); params.setAxes(skiaAxes.get(), skiaAxesLength); params.setAxes(skiaAxes.get(), skiaAxesLength); SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault()); SkTypeface* face = fm->createFromStream(fontData.release(), params); SkTypeface* face = fm->createFromStream(fontData.release(), params); if (face == NULL) { if (face == NULL) { ALOGE("addFont failed to create font %s#%d", str.c_str(), ttcIndex); ALOGE("addFont failed to create font, invalid request"); return false; return false; } } FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); Loading Loading @@ -175,7 +209,7 @@ static const JNINativeMethod gFontFamilyMethods[] = { { "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create }, { "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create }, { "nUnrefFamily", "(J)V", (void*)FontFamily_unref }, { "nUnrefFamily", "(J)V", (void*)FontFamily_unref }, { "nAddFont", "(JLjava/lang/String;I)Z", (void*)FontFamily_addFont }, { "nAddFont", "(JLjava/lang/String;I)Z", (void*)FontFamily_addFont }, { "nAddFontWeightStyle", "(JLjava/lang/String;ILjava/util/List;IZ)Z", { "nAddFontWeightStyle", "(JLjava/nio/ByteBuffer;ILjava/util/List;IZ)Z", (void*)FontFamily_addFontWeightStyle }, (void*)FontFamily_addFontWeightStyle }, { "nAddFontFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z", { "nAddFontFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z", (void*)FontFamily_addFontFromAsset }, (void*)FontFamily_addFontFromAsset }, Loading
graphics/java/android/graphics/FontFamily.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.graphics; import android.content.res.AssetManager; import android.content.res.AssetManager; import java.nio.ByteBuffer; import java.util.List; import java.util.List; /** /** Loading Loading @@ -64,9 +65,9 @@ public class FontFamily { return nAddFont(mNativePtr, path, ttcIndex); return nAddFont(mNativePtr, path, ttcIndex); } } public boolean addFontWeightStyle(String path, int ttcIndex, List<FontListParser.Axis> axes, public boolean addFontWeightStyle(ByteBuffer font, int ttcIndex, List<FontListParser.Axis> axes, int weight, boolean style) { int weight, boolean style) { return nAddFontWeightStyle(mNativePtr, path, ttcIndex, axes, weight, style); return nAddFontWeightStyle(mNativePtr, font, ttcIndex, axes, weight, style); } } public boolean addFontFromAsset(AssetManager mgr, String path) { public boolean addFontFromAsset(AssetManager mgr, String path) { Loading @@ -76,7 +77,7 @@ public class FontFamily { private static native long nCreateFamily(String lang, int variant); private static native long nCreateFamily(String lang, int variant); private static native void nUnrefFamily(long nativePtr); private static native void nUnrefFamily(long nativePtr); private static native boolean nAddFont(long nativeFamily, String path, int ttcIndex); private static native boolean nAddFont(long nativeFamily, String path, int ttcIndex); private static native boolean nAddFontWeightStyle(long nativeFamily, String path, private static native boolean nAddFontWeightStyle(long nativeFamily, ByteBuffer font, int ttcIndex, List<FontListParser.Axis> listOfAxis, int ttcIndex, List<FontListParser.Axis> listOfAxis, int weight, boolean isItalic); int weight, boolean isItalic); private static native boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, private static native boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, Loading
graphics/java/android/graphics/Typeface.java +24 −5 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,8 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileNotFoundException; import java.io.IOException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; import java.util.List; import java.util.List; Loading Loading @@ -258,11 +260,26 @@ public class Typeface { mStyle = nativeGetStyle(ni); mStyle = nativeGetStyle(ni); } } private static FontFamily makeFamilyFromParsed(FontListParser.Family family) { private static FontFamily makeFamilyFromParsed(FontListParser.Family family, Map<String, ByteBuffer> bufferForPath) { FontFamily fontFamily = new FontFamily(family.lang, family.variant); FontFamily fontFamily = new FontFamily(family.lang, family.variant); for (FontListParser.Font font : family.fonts) { for (FontListParser.Font font : family.fonts) { fontFamily.addFontWeightStyle(font.fontName, font.ttcIndex, font.axes, ByteBuffer fontBuffer = bufferForPath.get(font.fontName); font.weight, font.isItalic); if (fontBuffer == null) { try (FileInputStream file = new FileInputStream(font.fontName)) { FileChannel fileChannel = file.getChannel(); long fontSize = fileChannel.size(); fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize); bufferForPath.put(font.fontName, fontBuffer); } catch (IOException e) { Log.e(TAG, "Error mapping font file " + font.fontName); continue; } } if (!fontFamily.addFontWeightStyle(fontBuffer, font.ttcIndex, font.axes, font.weight, font.isItalic)) { Log.e(TAG, "Error creating font " + font.fontName + "#" + font.ttcIndex); } } } return fontFamily; return fontFamily; } } Loading @@ -280,13 +297,15 @@ public class Typeface { FileInputStream fontsIn = new FileInputStream(configFilename); FileInputStream fontsIn = new FileInputStream(configFilename); FontListParser.Config fontConfig = FontListParser.parse(fontsIn); FontListParser.Config fontConfig = FontListParser.parse(fontsIn); Map<String, ByteBuffer> bufferForPath = new HashMap<String, ByteBuffer>(); List<FontFamily> familyList = new ArrayList<FontFamily>(); List<FontFamily> familyList = new ArrayList<FontFamily>(); // Note that the default typeface is always present in the fallback list; // Note that the default typeface is always present in the fallback list; // this is an enhancement from pre-Minikin behavior. // this is an enhancement from pre-Minikin behavior. for (int i = 0; i < fontConfig.families.size(); i++) { for (int i = 0; i < fontConfig.families.size(); i++) { FontListParser.Family f = fontConfig.families.get(i); FontListParser.Family f = fontConfig.families.get(i); if (i == 0 || f.name == null) { if (i == 0 || f.name == null) { familyList.add(makeFamilyFromParsed(f)); familyList.add(makeFamilyFromParsed(f, bufferForPath)); } } } } sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]); sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]); Loading @@ -302,7 +321,7 @@ public class Typeface { // duplicating the corresponding FontFamily. // duplicating the corresponding FontFamily. typeface = sDefaultTypeface; typeface = sDefaultTypeface; } else { } else { FontFamily fontFamily = makeFamilyFromParsed(f); FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath); FontFamily[] families = { fontFamily }; FontFamily[] families = { fontFamily }; typeface = Typeface.createFromFamiliesWithDefault(families); typeface = Typeface.createFromFamiliesWithDefault(families); } } Loading