Merge "Deduplicate font file mappings." into nyc-dev

am: 242afb7809

* commit '242afb7809aaca37a34e4fce4a895d8b5c5f67fd':
  Deduplicate font file mappings.
This commit is contained in:
Ben Wagner
2016-02-12 20:42:10 +00:00
committed by android-build-merger
3 changed files with 71 additions and 17 deletions

View File

@@ -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 },

View File

@@ -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,

View File

@@ -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);
}