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" 201a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include <android_runtime/AndroidRuntime.h> 211a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 221a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "SkTypeface.h" 231a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "GraphicsJNI.h" 241a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include <ScopedPrimitiveArray.h> 251a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include <ScopedUtfChars.h> 26d573794d83a049fe59e289944f0cd77406dd776aRaph Levien#include <android_runtime/android_util_AssetManager.h> 27d573794d83a049fe59e289944f0cd77406dd776aRaph Levien#include <androidfw/AssetManager.h> 28d573794d83a049fe59e289944f0cd77406dd776aRaph Levien#include "Utils.h" 291a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 303d528c403c8945cc326bb656ff0c2e11373401daRaph Levien#include "TypefaceImpl.h" 311a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include <minikin/FontFamily.h> 321a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "MinikinSkia.h" 331a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 341a73f732f91e97c9c66b808c245ddda36a10e987Raph Leviennamespace android { 351a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 36f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levienstatic jlong FontFamily_create(JNIEnv* env, jobject clazz, jstring lang, jint variant) { 37f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien FontLanguage fontLanguage; 38f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien if (lang != NULL) { 39f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien ScopedUtfChars str(env, lang); 40f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien fontLanguage = FontLanguage(str.c_str(), str.size()); 41f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien } 42f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien return (jlong)new FontFamily(fontLanguage, variant); 431a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien} 441a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 4515cf4757dc0099301662f8a26da561434cc07cfaRaph Levienstatic void FontFamily_unref(JNIEnv* env, jobject clazz, jlong familyPtr) { 4615cf4757dc0099301662f8a26da561434cc07cfaRaph Levien FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 4715cf4757dc0099301662f8a26da561434cc07cfaRaph Levien fontFamily->Unref(); 481a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien} 491a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 50d573794d83a049fe59e289944f0cd77406dd776aRaph Levienstatic jboolean addSkTypeface(FontFamily* family, SkTypeface* face) { 51d573794d83a049fe59e289944f0cd77406dd776aRaph Levien MinikinFont* minikinFont = new MinikinFontSkia(face); 52d573794d83a049fe59e289944f0cd77406dd776aRaph Levien bool result = family->addFont(minikinFont); 53d573794d83a049fe59e289944f0cd77406dd776aRaph Levien minikinFont->Unref(); 54d573794d83a049fe59e289944f0cd77406dd776aRaph Levien return result; 55d573794d83a049fe59e289944f0cd77406dd776aRaph Levien} 56d573794d83a049fe59e289944f0cd77406dd776aRaph Levien 571a73f732f91e97c9c66b808c245ddda36a10e987Raph Levienstatic jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jstring path) { 581a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien NPE_CHECK_RETURN_ZERO(env, path); 591a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien ScopedUtfChars str(env, path); 601a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien SkTypeface* face = SkTypeface::CreateFromFile(str.c_str()); 619a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien if (face == NULL) { 629a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien ALOGE("addFont failed to create font %s", str.c_str()); 639a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien return false; 649a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 65117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 66d573794d83a049fe59e289944f0cd77406dd776aRaph Levien return addSkTypeface(fontFamily, face); 67d573794d83a049fe59e289944f0cd77406dd776aRaph Levien} 68d573794d83a049fe59e289944f0cd77406dd776aRaph Levien 69117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levienstatic jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr, 70117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien jstring path, jint weight, jboolean isItalic) { 71117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien NPE_CHECK_RETURN_ZERO(env, path); 72117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien ScopedUtfChars str(env, path); 73117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien SkTypeface* face = SkTypeface::CreateFromFile(str.c_str()); 74117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien if (face == NULL) { 75117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien ALOGE("addFont failed to create font %s", str.c_str()); 76117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien return false; 77117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 78117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 79117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien MinikinFont* minikinFont = new MinikinFontSkia(face); 80117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien fontFamily->addFont(minikinFont, FontStyle(weight / 100, isItalic)); 81117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien minikinFont->Unref(); 82117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien return true; 83117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien} 84117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien 85d573794d83a049fe59e289944f0cd77406dd776aRaph Levienstatic jboolean FontFamily_addFontFromAsset(JNIEnv* env, jobject, jlong familyPtr, 86d573794d83a049fe59e289944f0cd77406dd776aRaph Levien jobject jassetMgr, jstring jpath) { 87d573794d83a049fe59e289944f0cd77406dd776aRaph Levien NPE_CHECK_RETURN_ZERO(env, jassetMgr); 88d573794d83a049fe59e289944f0cd77406dd776aRaph Levien NPE_CHECK_RETURN_ZERO(env, jpath); 89d573794d83a049fe59e289944f0cd77406dd776aRaph Levien 90d573794d83a049fe59e289944f0cd77406dd776aRaph Levien AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr); 91d573794d83a049fe59e289944f0cd77406dd776aRaph Levien if (NULL == mgr) { 92d573794d83a049fe59e289944f0cd77406dd776aRaph Levien return false; 93d573794d83a049fe59e289944f0cd77406dd776aRaph Levien } 94d573794d83a049fe59e289944f0cd77406dd776aRaph Levien 95d573794d83a049fe59e289944f0cd77406dd776aRaph Levien ScopedUtfChars str(env, jpath); 96d573794d83a049fe59e289944f0cd77406dd776aRaph Levien Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER); 97d573794d83a049fe59e289944f0cd77406dd776aRaph Levien if (NULL == asset) { 98d573794d83a049fe59e289944f0cd77406dd776aRaph Levien return false; 99d573794d83a049fe59e289944f0cd77406dd776aRaph Levien } 100d573794d83a049fe59e289944f0cd77406dd776aRaph Levien 101d573794d83a049fe59e289944f0cd77406dd776aRaph Levien SkStream* stream = new AssetStreamAdaptor(asset, 102d573794d83a049fe59e289944f0cd77406dd776aRaph Levien AssetStreamAdaptor::kYes_OwnAsset, 103d573794d83a049fe59e289944f0cd77406dd776aRaph Levien AssetStreamAdaptor::kYes_HasMemoryBase); 104d573794d83a049fe59e289944f0cd77406dd776aRaph Levien SkTypeface* face = SkTypeface::CreateFromStream(stream); 105d573794d83a049fe59e289944f0cd77406dd776aRaph Levien // Note: SkTypeface::CreateFromStream holds its own reference to the stream 106d573794d83a049fe59e289944f0cd77406dd776aRaph Levien stream->unref(); 107d573794d83a049fe59e289944f0cd77406dd776aRaph Levien if (face == NULL) { 108d573794d83a049fe59e289944f0cd77406dd776aRaph Levien ALOGE("addFontFromAsset failed to create font %s", str.c_str()); 109d573794d83a049fe59e289944f0cd77406dd776aRaph Levien return false; 110d573794d83a049fe59e289944f0cd77406dd776aRaph Levien } 111117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 112d573794d83a049fe59e289944f0cd77406dd776aRaph Levien return addSkTypeface(fontFamily, face); 1131a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien} 1141a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 1151a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien/////////////////////////////////////////////////////////////////////////////// 1161a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 1171a73f732f91e97c9c66b808c245ddda36a10e987Raph Levienstatic JNINativeMethod gFontFamilyMethods[] = { 118117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien { "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create }, 119117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien { "nUnrefFamily", "(J)V", (void*)FontFamily_unref }, 120117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien { "nAddFont", "(JLjava/lang/String;)Z", (void*)FontFamily_addFont }, 121117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien { "nAddFontWeightStyle", "(JLjava/lang/String;IZ)Z", (void*)FontFamily_addFontWeightStyle }, 122117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien { "nAddFontFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z", 123d573794d83a049fe59e289944f0cd77406dd776aRaph Levien (void*)FontFamily_addFontFromAsset }, 1241a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien}; 1251a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 1261a73f732f91e97c9c66b808c245ddda36a10e987Raph Levienint register_android_graphics_FontFamily(JNIEnv* env) 1271a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien{ 1281a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien return android::AndroidRuntime::registerNativeMethods(env, 1291a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien "android/graphics/FontFamily", 1301a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien gFontFamilyMethods, NELEM(gFontFamilyMethods)); 1311a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien} 1321a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 1331a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien} 134