11a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien/*
21a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Copyright (C) 2014 The Android Open Source Project
31a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien *
41a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Licensed under the Apache License, Version 2.0 (the "License");
51a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * you may not use this file except in compliance with the License.
61a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * You may obtain a copy of the License at
71a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien *
81a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien *      http://www.apache.org/licenses/LICENSE-2.0
91a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien *
101a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Unless required by applicable law or agreed to in writing, software
111a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * distributed under the License is distributed on an "AS IS" BASIS,
121a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * See the License for the specific language governing permissions and
141a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * limitations under the License.
151a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien */
161a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
171a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#define LOG_TAG "Minikin"
181a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
191a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "JNIHelp.h"
20ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include <core_jni_helpers.h>
211a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
22f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner#include "SkData.h"
23a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner#include "SkFontMgr.h"
24f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner#include "SkRefCnt.h"
251a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "SkTypeface.h"
261a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "GraphicsJNI.h"
271a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include <ScopedPrimitiveArray.h>
281a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include <ScopedUtfChars.h>
29fb95699364e555148b437cfa1e5c69384f843845Ben Wagner#include <android_runtime/AndroidRuntime.h>
30d573794d83a049fe59e289944f0cd77406dd776aRaph Levien#include <android_runtime/android_util_AssetManager.h>
31d573794d83a049fe59e289944f0cd77406dd776aRaph Levien#include <androidfw/AssetManager.h>
32d573794d83a049fe59e289944f0cd77406dd776aRaph Levien#include "Utils.h"
331a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
34dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/MinikinSkia.h>
35bad99183916ba2bac6659efc8a28273e344ba511sergeyv#include <hwui/Typeface.h>
361a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include <minikin/FontFamily.h>
371a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
38a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner#include <memory>
39a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner
401a73f732f91e97c9c66b808c245ddda36a10e987Raph Leviennamespace android {
411a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
42f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levienstatic jlong FontFamily_create(JNIEnv* env, jobject clazz, jstring lang, jint variant) {
434ea7d1d2ab51fd7f67087db669dbaf693560b838Seigo Nonaka    if (lang == NULL) {
444ea7d1d2ab51fd7f67087db669dbaf693560b838Seigo Nonaka        return (jlong)new FontFamily(variant);
45f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien    }
464ea7d1d2ab51fd7f67087db669dbaf693560b838Seigo Nonaka    ScopedUtfChars str(env, lang);
474ea7d1d2ab51fd7f67087db669dbaf693560b838Seigo Nonaka    uint32_t langId = FontStyle::registerLanguageList(str.c_str());
484ea7d1d2ab51fd7f67087db669dbaf693560b838Seigo Nonaka    return (jlong)new FontFamily(langId, variant);
491a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien}
501a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
5115cf4757dc0099301662f8a26da561434cc07cfaRaph Levienstatic void FontFamily_unref(JNIEnv* env, jobject clazz, jlong familyPtr) {
5215cf4757dc0099301662f8a26da561434cc07cfaRaph Levien    FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
5315cf4757dc0099301662f8a26da561434cc07cfaRaph Levien    fontFamily->Unref();
541a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien}
551a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
56296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levienstatic jboolean addSkTypeface(FontFamily* family, SkTypeface* face, const void* fontData,
57296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        size_t fontSize, int ttcIndex) {
58296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    MinikinFont* minikinFont = new MinikinFontSkia(face, fontData, fontSize, ttcIndex);
59d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    bool result = family->addFont(minikinFont);
60d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    minikinFont->Unref();
61d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    return result;
62d573794d83a049fe59e289944f0cd77406dd776aRaph Levien}
63d573794d83a049fe59e289944f0cd77406dd776aRaph Levien
64fb95699364e555148b437cfa1e5c69384f843845Ben Wagnerstatic void release_global_ref(const void* /*data*/, void* context) {
65fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    JNIEnv* env = AndroidRuntime::getJNIEnv();
66fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    bool needToAttach = (env == NULL);
67fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    if (needToAttach) {
68fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        JavaVMAttachArgs args;
69fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        args.version = JNI_VERSION_1_4;
70fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        args.name = "release_font_data";
71fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        args.group = NULL;
72fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        jint result = AndroidRuntime::getJavaVM()->AttachCurrentThread(&env, &args);
73fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        if (result != JNI_OK) {
74fb95699364e555148b437cfa1e5c69384f843845Ben Wagner            ALOGE("failed to attach to thread to release global ref.");
75fb95699364e555148b437cfa1e5c69384f843845Ben Wagner            return;
76fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        }
77fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    }
78fb95699364e555148b437cfa1e5c69384f843845Ben Wagner
79fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    jobject obj = reinterpret_cast<jobject>(context);
80fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    env->DeleteGlobalRef(obj);
81fb95699364e555148b437cfa1e5c69384f843845Ben Wagner
82fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    if (needToAttach) {
83fb95699364e555148b437cfa1e5c69384f843845Ben Wagner       AndroidRuntime::getJavaVM()->DetachCurrentThread();
84fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    }
85fb95699364e555148b437cfa1e5c69384f843845Ben Wagner}
86fb95699364e555148b437cfa1e5c69384f843845Ben Wagner
87296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levienstatic jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jobject bytebuf,
88296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        jint ttcIndex) {
89296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    NPE_CHECK_RETURN_ZERO(env, bytebuf);
90296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    const void* fontPtr = env->GetDirectBufferAddress(bytebuf);
91296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    if (fontPtr == NULL) {
92296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        ALOGE("addFont failed to create font, buffer invalid");
93296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        return false;
94296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    }
95296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    jlong fontSize = env->GetDirectBufferCapacity(bytebuf);
96296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    if (fontSize < 0) {
97296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        ALOGE("addFont failed to create font, buffer size invalid");
98296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        return false;
99296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    }
100296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    jobject fontRef = MakeGlobalRefOrDie(env, bytebuf);
101296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    SkAutoTUnref<SkData> data(SkData::NewWithProc(fontPtr, fontSize,
102296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien            release_global_ref, reinterpret_cast<void*>(fontRef)));
103296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(data));
104296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien
105296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    SkFontMgr::FontParameters params;
106296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    params.setCollectionIndex(ttcIndex);
107296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien
108296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
109296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    SkTypeface* face = fm->createFromStream(fontData.release(), params);
110296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    if (face == NULL) {
111296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        ALOGE("addFont failed to create font");
112296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        return false;
113296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    }
114296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
115296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    return addSkTypeface(fontFamily, face, fontPtr, (size_t)fontSize, ttcIndex);
116296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien}
117296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien
118296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levienstatic struct {
119296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    jmethodID mGet;
120296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    jmethodID mSize;
121296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien} gListClassInfo;
122296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien
123296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levienstatic struct {
124296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    jfieldID mTag;
125296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    jfieldID mStyleValue;
126296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien} gAxisClassInfo;
127296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien
128117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levienstatic jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr,
129fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        jobject font, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) {
130fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    NPE_CHECK_RETURN_ZERO(env, font);
131a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner
132a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    // Declare axis native type.
133a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    std::unique_ptr<SkFontMgr::FontParameters::Axis[]> skiaAxes;
134a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    int skiaAxesLength = 0;
135a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    if (listOfAxis) {
136a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner        jint listSize = env->CallIntMethod(listOfAxis, gListClassInfo.mSize);
137a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner
138a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner        skiaAxes.reset(new SkFontMgr::FontParameters::Axis[listSize]);
139a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner        skiaAxesLength = listSize;
140a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner        for (jint i = 0; i < listSize; ++i) {
141a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            jobject axisObject = env->CallObjectMethod(listOfAxis, gListClassInfo.mGet, i);
142a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            if (!axisObject) {
143a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner                skiaAxes[i].fTag = 0;
144a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner                skiaAxes[i].fStyleValue = 0;
145a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner                continue;
146a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            }
147a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner
148a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            jint tag = env->GetIntField(axisObject, gAxisClassInfo.mTag);
149a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            jfloat stylevalue = env->GetFloatField(axisObject, gAxisClassInfo.mStyleValue);
150a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            skiaAxes[i].fTag = tag;
151a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            skiaAxes[i].fStyleValue = SkFloatToScalar(stylevalue);
152a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner        }
153a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    }
154a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner
155296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    const void* fontPtr = env->GetDirectBufferAddress(font);
156fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    if (fontPtr == NULL) {
157fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        ALOGE("addFont failed to create font, buffer invalid");
158fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        return false;
159fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    }
160fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    jlong fontSize = env->GetDirectBufferCapacity(font);
161fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    if (fontSize < 0) {
162fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        ALOGE("addFont failed to create font, buffer size invalid");
163a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner        return false;
164a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    }
165fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    jobject fontRef = MakeGlobalRefOrDie(env, font);
166fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    SkAutoTUnref<SkData> data(SkData::NewWithProc(fontPtr, fontSize,
167fb95699364e555148b437cfa1e5c69384f843845Ben Wagner            release_global_ref, reinterpret_cast<void*>(fontRef)));
168fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(data));
169fb95699364e555148b437cfa1e5c69384f843845Ben Wagner
170a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    SkFontMgr::FontParameters params;
171a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    params.setCollectionIndex(ttcIndex);
172a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    params.setAxes(skiaAxes.get(), skiaAxesLength);
173fb95699364e555148b437cfa1e5c69384f843845Ben Wagner
174fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
175a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    SkTypeface* face = fm->createFromStream(fontData.release(), params);
176117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    if (face == NULL) {
177fb95699364e555148b437cfa1e5c69384f843845Ben Wagner        ALOGE("addFont failed to create font, invalid request");
178117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien        return false;
179117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    }
180117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
181296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    MinikinFont* minikinFont = new MinikinFontSkia(face, fontPtr, (size_t)fontSize, ttcIndex);
182117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    fontFamily->addFont(minikinFont, FontStyle(weight / 100, isItalic));
183117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    minikinFont->Unref();
184117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    return true;
185117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien}
186117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien
1872f02dc5a15013a5ccc6b07b90c9e59dbde92c4d0Mike Reedstatic void releaseAsset(const void* ptr, void* context) {
188f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner    delete static_cast<Asset*>(context);
189f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner}
190f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner
191d573794d83a049fe59e289944f0cd77406dd776aRaph Levienstatic jboolean FontFamily_addFontFromAsset(JNIEnv* env, jobject, jlong familyPtr,
192d573794d83a049fe59e289944f0cd77406dd776aRaph Levien        jobject jassetMgr, jstring jpath) {
193d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    NPE_CHECK_RETURN_ZERO(env, jassetMgr);
194d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    NPE_CHECK_RETURN_ZERO(env, jpath);
195d573794d83a049fe59e289944f0cd77406dd776aRaph Levien
196d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr);
197d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    if (NULL == mgr) {
198d573794d83a049fe59e289944f0cd77406dd776aRaph Levien        return false;
199d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    }
200d573794d83a049fe59e289944f0cd77406dd776aRaph Levien
201d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    ScopedUtfChars str(env, jpath);
202d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
203d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    if (NULL == asset) {
204d573794d83a049fe59e289944f0cd77406dd776aRaph Levien        return false;
205d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    }
206d573794d83a049fe59e289944f0cd77406dd776aRaph Levien
207f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner    const void* buf = asset->getBuffer(false);
208f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner    if (NULL == buf) {
209f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner        delete asset;
210f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner        return false;
211f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner    }
212f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner
213296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    size_t bufSize = asset->getLength();
214f462c2491bae67815ae9e4a2ff7ce77db97b49c6Ben Wagner    SkAutoTUnref<SkData> data(SkData::NewWithProc(buf, asset->getLength(), releaseAsset, asset));
2153449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III    SkMemoryStream* stream = new SkMemoryStream(data);
2163449789b9ca58fee7e5cd02ff89d544f4a6bc9b5Leon Scroggins III    // CreateFromStream takes ownership of stream.
217d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    SkTypeface* face = SkTypeface::CreateFromStream(stream);
218d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    if (face == NULL) {
219d573794d83a049fe59e289944f0cd77406dd776aRaph Levien        ALOGE("addFontFromAsset failed to create font %s", str.c_str());
220d573794d83a049fe59e289944f0cd77406dd776aRaph Levien        return false;
221d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    }
222117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
223296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    return addSkTypeface(fontFamily, face, buf, bufSize, /* ttcIndex */ 0);
2241a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien}
2251a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
2261a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien///////////////////////////////////////////////////////////////////////////////
2271a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
22876f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gFontFamilyMethods[] = {
229117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    { "nCreateFamily",         "(Ljava/lang/String;I)J", (void*)FontFamily_create },
230117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    { "nUnrefFamily",          "(J)V", (void*)FontFamily_unref },
231296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    { "nAddFont",              "(JLjava/nio/ByteBuffer;I)Z", (void*)FontFamily_addFont },
232fb95699364e555148b437cfa1e5c69384f843845Ben Wagner    { "nAddFontWeightStyle",   "(JLjava/nio/ByteBuffer;ILjava/util/List;IZ)Z",
233a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            (void*)FontFamily_addFontWeightStyle },
234117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    { "nAddFontFromAsset",     "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z",
235a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            (void*)FontFamily_addFontFromAsset },
2361a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien};
2371a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
2381a73f732f91e97c9c66b808c245ddda36a10e987Raph Levienint register_android_graphics_FontFamily(JNIEnv* env)
2391a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien{
240a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    int err = RegisterMethodsOrDie(env, "android/graphics/FontFamily", gFontFamilyMethods,
241a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            NELEM(gFontFamilyMethods));
242a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner
243a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    jclass listClass = FindClassOrDie(env, "java/util/List");
244a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    gListClassInfo.mGet = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;");
245a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    gListClassInfo.mSize = GetMethodIDOrDie(env, listClass, "size", "()I");
246a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner
247a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    jclass axisClass = FindClassOrDie(env, "android/graphics/FontListParser$Axis");
248a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    gAxisClassInfo.mTag = GetFieldIDOrDie(env, axisClass, "tag", "I");
249a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    gAxisClassInfo.mStyleValue = GetFieldIDOrDie(env, axisClass, "styleValue", "F");
250a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner
251a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner    return err;
2521a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien}
2531a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
2541a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien}
255