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 36 namespace android { 37 38 static jlong FontFamily_create(JNIEnv* env, jobject clazz, jstring lang, jint variant) { 39 FontLanguage fontLanguage; 40 if (lang != NULL) { 41 ScopedUtfChars str(env, lang); 42 fontLanguage = FontLanguage(str.c_str(), str.size()); 43 } 44 return (jlong)new FontFamily(fontLanguage, variant); 45 } 46 47 static void FontFamily_unref(JNIEnv* env, jobject clazz, jlong familyPtr) { 48 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 49 fontFamily->Unref(); 50 } 51 52 static 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 59 static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jstring path) { 60 NPE_CHECK_RETURN_ZERO(env, path); 61 ScopedUtfChars str(env, path); 62 SkTypeface* face = SkTypeface::CreateFromFile(str.c_str()); 63 if (face == NULL) { 64 ALOGE("addFont failed to create font %s", str.c_str()); 65 return false; 66 } 67 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 68 return addSkTypeface(fontFamily, face); 69 } 70 71 static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr, 72 jstring path, jint weight, jboolean isItalic) { 73 NPE_CHECK_RETURN_ZERO(env, path); 74 ScopedUtfChars str(env, path); 75 SkTypeface* face = SkTypeface::CreateFromFile(str.c_str()); 76 if (face == NULL) { 77 ALOGE("addFont failed to create font %s", str.c_str()); 78 return false; 79 } 80 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 81 MinikinFont* minikinFont = new MinikinFontSkia(face); 82 fontFamily->addFont(minikinFont, FontStyle(weight / 100, isItalic)); 83 minikinFont->Unref(); 84 return true; 85 } 86 87 static void releaseAsset(const void* ptr, size_t length, void* context) { 88 delete static_cast<Asset*>(context); 89 } 90 91 static jboolean FontFamily_addFontFromAsset(JNIEnv* env, jobject, jlong familyPtr, 92 jobject jassetMgr, jstring jpath) { 93 NPE_CHECK_RETURN_ZERO(env, jassetMgr); 94 NPE_CHECK_RETURN_ZERO(env, jpath); 95 96 AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr); 97 if (NULL == mgr) { 98 return false; 99 } 100 101 ScopedUtfChars str(env, jpath); 102 Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER); 103 if (NULL == asset) { 104 return false; 105 } 106 107 const void* buf = asset->getBuffer(false); 108 if (NULL == buf) { 109 delete asset; 110 return false; 111 } 112 113 SkAutoTUnref<SkData> data(SkData::NewWithProc(buf, asset->getLength(), releaseAsset, asset)); 114 SkMemoryStream* stream = new SkMemoryStream(data); 115 // CreateFromStream takes ownership of stream. 116 SkTypeface* face = SkTypeface::CreateFromStream(stream); 117 if (face == NULL) { 118 ALOGE("addFontFromAsset failed to create font %s", str.c_str()); 119 return false; 120 } 121 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 122 return addSkTypeface(fontFamily, face); 123 } 124 125 /////////////////////////////////////////////////////////////////////////////// 126 127 static JNINativeMethod gFontFamilyMethods[] = { 128 { "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create }, 129 { "nUnrefFamily", "(J)V", (void*)FontFamily_unref }, 130 { "nAddFont", "(JLjava/lang/String;)Z", (void*)FontFamily_addFont }, 131 { "nAddFontWeightStyle", "(JLjava/lang/String;IZ)Z", (void*)FontFamily_addFontWeightStyle }, 132 { "nAddFontFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z", 133 (void*)FontFamily_addFontFromAsset }, 134 }; 135 136 int register_android_graphics_FontFamily(JNIEnv* env) 137 { 138 return RegisterMethodsOrDie(env, "android/graphics/FontFamily", gFontFamilyMethods, 139 NELEM(gFontFamilyMethods)); 140 } 141 142 } 143