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