Merge "Deduplicate font file mappings." into nyc-dev
am: 242afb7809
* commit '242afb7809aaca37a34e4fce4a895d8b5c5f67fd':
Deduplicate font file mappings.
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "GraphicsJNI.h"
|
||||
#include <ScopedPrimitiveArray.h>
|
||||
#include <ScopedUtfChars.h>
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <android_runtime/android_util_AssetManager.h>
|
||||
#include <androidfw/AssetManager.h>
|
||||
#include "Utils.h"
|
||||
@@ -82,9 +83,32 @@ static struct {
|
||||
jfieldID mStyleValue;
|
||||
} 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,
|
||||
jstring path, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) {
|
||||
NPE_CHECK_RETURN_ZERO(env, path);
|
||||
jobject font, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) {
|
||||
NPE_CHECK_RETURN_ZERO(env, font);
|
||||
|
||||
// Declare axis native type.
|
||||
std::unique_ptr<SkFontMgr::FontParameters::Axis[]> skiaAxes;
|
||||
@@ -109,19 +133,29 @@ static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong
|
||||
}
|
||||
}
|
||||
|
||||
ScopedUtfChars str(env, path);
|
||||
SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
|
||||
std::unique_ptr<SkStreamAsset> fontData(SkStream::NewFromFile(str.c_str()));
|
||||
if (!fontData) {
|
||||
ALOGE("addFont failed to open %s", str.c_str());
|
||||
void* fontPtr = env->GetDirectBufferAddress(font);
|
||||
if (fontPtr == NULL) {
|
||||
ALOGE("addFont failed to create font, buffer invalid");
|
||||
return false;
|
||||
}
|
||||
jlong fontSize = env->GetDirectBufferCapacity(font);
|
||||
if (fontSize < 0) {
|
||||
ALOGE("addFont failed to create font, buffer size invalid");
|
||||
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;
|
||||
params.setCollectionIndex(ttcIndex);
|
||||
params.setAxes(skiaAxes.get(), skiaAxesLength);
|
||||
|
||||
SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
|
||||
SkTypeface* face = fm->createFromStream(fontData.release(), params);
|
||||
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;
|
||||
}
|
||||
FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
|
||||
@@ -175,7 +209,7 @@ static const JNINativeMethod gFontFamilyMethods[] = {
|
||||
{ "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create },
|
||||
{ "nUnrefFamily", "(J)V", (void*)FontFamily_unref },
|
||||
{ "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 },
|
||||
{ "nAddFontFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z",
|
||||
(void*)FontFamily_addFontFromAsset },
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.graphics;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -64,9 +65,9 @@ public class FontFamily {
|
||||
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) {
|
||||
return nAddFontWeightStyle(mNativePtr, path, ttcIndex, axes, weight, style);
|
||||
return nAddFontWeightStyle(mNativePtr, font, ttcIndex, axes, weight, style);
|
||||
}
|
||||
|
||||
public boolean addFontFromAsset(AssetManager mgr, String path) {
|
||||
@@ -76,7 +77,7 @@ public class FontFamily {
|
||||
private static native long nCreateFamily(String lang, int variant);
|
||||
private static native void nUnrefFamily(long nativePtr);
|
||||
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 weight, boolean isItalic);
|
||||
private static native boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr,
|
||||
|
||||
@@ -27,6 +27,8 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -258,11 +260,26 @@ public class Typeface {
|
||||
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);
|
||||
for (FontListParser.Font font : family.fonts) {
|
||||
fontFamily.addFontWeightStyle(font.fontName, font.ttcIndex, font.axes,
|
||||
font.weight, font.isItalic);
|
||||
ByteBuffer fontBuffer = bufferForPath.get(font.fontName);
|
||||
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;
|
||||
}
|
||||
@@ -280,13 +297,15 @@ public class Typeface {
|
||||
FileInputStream fontsIn = new FileInputStream(configFilename);
|
||||
FontListParser.Config fontConfig = FontListParser.parse(fontsIn);
|
||||
|
||||
Map<String, ByteBuffer> bufferForPath = new HashMap<String, ByteBuffer>();
|
||||
|
||||
List<FontFamily> familyList = new ArrayList<FontFamily>();
|
||||
// Note that the default typeface is always present in the fallback list;
|
||||
// this is an enhancement from pre-Minikin behavior.
|
||||
for (int i = 0; i < fontConfig.families.size(); i++) {
|
||||
FontListParser.Family f = fontConfig.families.get(i);
|
||||
if (i == 0 || f.name == null) {
|
||||
familyList.add(makeFamilyFromParsed(f));
|
||||
familyList.add(makeFamilyFromParsed(f, bufferForPath));
|
||||
}
|
||||
}
|
||||
sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]);
|
||||
@@ -302,7 +321,7 @@ public class Typeface {
|
||||
// duplicating the corresponding FontFamily.
|
||||
typeface = sDefaultTypeface;
|
||||
} else {
|
||||
FontFamily fontFamily = makeFamilyFromParsed(f);
|
||||
FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath);
|
||||
FontFamily[] families = { fontFamily };
|
||||
typeface = Typeface.createFromFamiliesWithDefault(families);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user