Home | History | Annotate | Download | only in graphics
      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