FontFamily.cpp revision 5640ae00e76f71a35b10b805bbee55efac6b16f2
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Minikin" 18 19#include "JNIHelp.h" 20#include <core_jni_helpers.h> 21 22#include "SkData.h" 23#include "SkRefCnt.h" 24#include "SkTypeface.h" 25#include "GraphicsJNI.h" 26#include <ScopedPrimitiveArray.h> 27#include <ScopedUtfChars.h> 28#include <android_runtime/android_util_AssetManager.h> 29#include <androidfw/AssetManager.h> 30#include "Utils.h" 31 32#include "TypefaceImpl.h" 33#include <minikin/FontFamily.h> 34#include "MinikinSkia.h" 35 36namespace android { 37 38static jlong FontFamily_create(JNIEnv* env, jobject clazz, jstring lang, jint variant) { 39 if (lang == NULL) { 40 return (jlong)new FontFamily(variant); 41 } 42 ScopedUtfChars str(env, lang); 43 uint32_t langId = FontStyle::registerLanguageList(str.c_str()); 44 return (jlong)new FontFamily(langId, variant); 45} 46 47static void FontFamily_unref(JNIEnv* env, jobject clazz, jlong familyPtr) { 48 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 49 fontFamily->Unref(); 50} 51 52static jboolean addSkTypeface(FontFamily* family, SkTypeface* face) { 53 MinikinFont* minikinFont = new MinikinFontSkia(face); 54 bool result = family->addFont(minikinFont); 55 minikinFont->Unref(); 56 return result; 57} 58 59static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jstring path, 60 jint ttcIndex) { 61 NPE_CHECK_RETURN_ZERO(env, path); 62 ScopedUtfChars str(env, path); 63 SkTypeface* face = SkTypeface::CreateFromFile(str.c_str(), ttcIndex); 64 if (face == NULL) { 65 ALOGE("addFont failed to create font %s", str.c_str()); 66 return false; 67 } 68 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 69 return addSkTypeface(fontFamily, face); 70} 71 72static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr, 73 jstring path, jint ttcIndex, jint weight, jboolean isItalic) { 74 NPE_CHECK_RETURN_ZERO(env, path); 75 ScopedUtfChars str(env, path); 76 SkTypeface* face = SkTypeface::CreateFromFile(str.c_str(), ttcIndex); 77 if (face == NULL) { 78 ALOGE("addFont failed to create font %s", str.c_str()); 79 return false; 80 } 81 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 82 MinikinFont* minikinFont = new MinikinFontSkia(face); 83 fontFamily->addFont(minikinFont, FontStyle(weight / 100, isItalic)); 84 minikinFont->Unref(); 85 return true; 86} 87 88static void releaseAsset(const void* ptr, void* context) { 89 delete static_cast<Asset*>(context); 90} 91 92static jboolean FontFamily_addFontFromAsset(JNIEnv* env, jobject, jlong familyPtr, 93 jobject jassetMgr, jstring jpath) { 94 NPE_CHECK_RETURN_ZERO(env, jassetMgr); 95 NPE_CHECK_RETURN_ZERO(env, jpath); 96 97 AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr); 98 if (NULL == mgr) { 99 return false; 100 } 101 102 ScopedUtfChars str(env, jpath); 103 Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER); 104 if (NULL == asset) { 105 return false; 106 } 107 108 const void* buf = asset->getBuffer(false); 109 if (NULL == buf) { 110 delete asset; 111 return false; 112 } 113 114 SkAutoTUnref<SkData> data(SkData::NewWithProc(buf, asset->getLength(), releaseAsset, asset)); 115 SkMemoryStream* stream = new SkMemoryStream(data); 116 // CreateFromStream takes ownership of stream. 117 SkTypeface* face = SkTypeface::CreateFromStream(stream); 118 if (face == NULL) { 119 ALOGE("addFontFromAsset failed to create font %s", str.c_str()); 120 return false; 121 } 122 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 123 return addSkTypeface(fontFamily, face); 124} 125 126/////////////////////////////////////////////////////////////////////////////// 127 128static const JNINativeMethod gFontFamilyMethods[] = { 129 { "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create }, 130 { "nUnrefFamily", "(J)V", (void*)FontFamily_unref }, 131 { "nAddFont", "(JLjava/lang/String;I)Z", (void*)FontFamily_addFont }, 132 { "nAddFontWeightStyle", "(JLjava/lang/String;IIZ)Z", (void*)FontFamily_addFontWeightStyle }, 133 { "nAddFontFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z", 134 (void*)FontFamily_addFontFromAsset }, 135}; 136 137int register_android_graphics_FontFamily(JNIEnv* env) 138{ 139 return RegisterMethodsOrDie(env, "android/graphics/FontFamily", gFontFamilyMethods, 140 NELEM(gFontFamilyMethods)); 141} 142 143} 144