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 <android_runtime/AndroidRuntime.h> 21 22 #include "SkTypeface.h" 23 #include "GraphicsJNI.h" 24 #include <ScopedPrimitiveArray.h> 25 #include <ScopedUtfChars.h> 26 #include <android_runtime/android_util_AssetManager.h> 27 #include <androidfw/AssetManager.h> 28 #include "Utils.h" 29 30 #include "TypefaceImpl.h" 31 #include <minikin/FontFamily.h> 32 #include "MinikinSkia.h" 33 34 namespace android { 35 36 static jlong FontFamily_create(JNIEnv* env, jobject clazz, jstring lang, jint variant) { 37 FontLanguage fontLanguage; 38 if (lang != NULL) { 39 ScopedUtfChars str(env, lang); 40 fontLanguage = FontLanguage(str.c_str(), str.size()); 41 } 42 return (jlong)new FontFamily(fontLanguage, variant); 43 } 44 45 static void FontFamily_unref(JNIEnv* env, jobject clazz, jlong familyPtr) { 46 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 47 fontFamily->Unref(); 48 } 49 50 static jboolean addSkTypeface(FontFamily* family, SkTypeface* face) { 51 MinikinFont* minikinFont = new MinikinFontSkia(face); 52 bool result = family->addFont(minikinFont); 53 minikinFont->Unref(); 54 return result; 55 } 56 57 static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jstring path) { 58 NPE_CHECK_RETURN_ZERO(env, path); 59 ScopedUtfChars str(env, path); 60 SkTypeface* face = SkTypeface::CreateFromFile(str.c_str()); 61 if (face == NULL) { 62 ALOGE("addFont failed to create font %s", str.c_str()); 63 return false; 64 } 65 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 66 return addSkTypeface(fontFamily, face); 67 } 68 69 static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr, 70 jstring path, jint weight, jboolean isItalic) { 71 NPE_CHECK_RETURN_ZERO(env, path); 72 ScopedUtfChars str(env, path); 73 SkTypeface* face = SkTypeface::CreateFromFile(str.c_str()); 74 if (face == NULL) { 75 ALOGE("addFont failed to create font %s", str.c_str()); 76 return false; 77 } 78 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 79 MinikinFont* minikinFont = new MinikinFontSkia(face); 80 fontFamily->addFont(minikinFont, FontStyle(weight / 100, isItalic)); 81 minikinFont->Unref(); 82 return true; 83 } 84 85 static jboolean FontFamily_addFontFromAsset(JNIEnv* env, jobject, jlong familyPtr, 86 jobject jassetMgr, jstring jpath) { 87 NPE_CHECK_RETURN_ZERO(env, jassetMgr); 88 NPE_CHECK_RETURN_ZERO(env, jpath); 89 90 AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr); 91 if (NULL == mgr) { 92 return false; 93 } 94 95 ScopedUtfChars str(env, jpath); 96 Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER); 97 if (NULL == asset) { 98 return false; 99 } 100 101 SkStream* stream = new AssetStreamAdaptor(asset, 102 AssetStreamAdaptor::kYes_OwnAsset, 103 AssetStreamAdaptor::kYes_HasMemoryBase); 104 SkTypeface* face = SkTypeface::CreateFromStream(stream); 105 // Note: SkTypeface::CreateFromStream holds its own reference to the stream 106 stream->unref(); 107 if (face == NULL) { 108 ALOGE("addFontFromAsset failed to create font %s", str.c_str()); 109 return false; 110 } 111 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 112 return addSkTypeface(fontFamily, face); 113 } 114 115 /////////////////////////////////////////////////////////////////////////////// 116 117 static JNINativeMethod gFontFamilyMethods[] = { 118 { "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create }, 119 { "nUnrefFamily", "(J)V", (void*)FontFamily_unref }, 120 { "nAddFont", "(JLjava/lang/String;)Z", (void*)FontFamily_addFont }, 121 { "nAddFontWeightStyle", "(JLjava/lang/String;IZ)Z", (void*)FontFamily_addFontWeightStyle }, 122 { "nAddFontFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z", 123 (void*)FontFamily_addFontFromAsset }, 124 }; 125 126 int register_android_graphics_FontFamily(JNIEnv* env) 127 { 128 return android::AndroidRuntime::registerNativeMethods(env, 129 "android/graphics/FontFamily", 130 gFontFamilyMethods, NELEM(gFontFamilyMethods)); 131 } 132 133 } 134