Typeface.cpp revision 36bef0bf30d6bae48cf3837df351075ca4fce654
1/*
2 * Copyright (C) 2013 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#include "jni.h"
18#include <android_runtime/AndroidRuntime.h>
19
20#include "GraphicsJNI.h"
21#include "SkStream.h"
22#include "SkTypeface.h"
23#include "TypefaceImpl.h"
24#include <android_runtime/android_util_AssetManager.h>
25#include <androidfw/AssetManager.h>
26
27using namespace android;
28
29class AutoJavaStringToUTF8 {
30public:
31    AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str)
32    {
33        fCStr = env->GetStringUTFChars(str, NULL);
34    }
35    ~AutoJavaStringToUTF8()
36    {
37        fEnv->ReleaseStringUTFChars(fJStr, fCStr);
38    }
39    const char* c_str() const { return fCStr; }
40
41private:
42    JNIEnv*     fEnv;
43    jstring     fJStr;
44    const char* fCStr;
45};
46
47static jlong Typeface_create(JNIEnv* env, jobject, jstring name,
48                             jint styleHandle) {
49    SkTypeface::Style style = static_cast<SkTypeface::Style>(styleHandle);
50    TypefaceImpl* face = NULL;
51
52    if (NULL != name) {
53        AutoJavaStringToUTF8    str(env, name);
54        face = TypefaceImpl_createFromName(str.c_str(), style);
55    }
56
57    // return the default font at the best style if no exact match exists
58    if (NULL == face) {
59        face = TypefaceImpl_createFromName(NULL, style);
60    }
61    return reinterpret_cast<jlong>(face);
62}
63
64static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandle, jint style) {
65    SkTypeface* family = reinterpret_cast<SkTypeface*>(familyHandle);
66    TypefaceImpl* face = TypefaceImpl_createFromTypeface(family, (SkTypeface::Style)style);
67    // Try to find the closest matching font, using the standard heuristic
68    if (NULL == face) {
69        face = TypefaceImpl_createFromTypeface(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic));
70    }
71    for (int i = 0; NULL == face && i < 4; i++) {
72        face = TypefaceImpl_createFromTypeface(family, (SkTypeface::Style)i);
73    }
74    if (NULL == face) {
75        face = TypefaceImpl_createFromName(NULL, (SkTypeface::Style)style);
76    }
77    return reinterpret_cast<jlong>(face);
78}
79
80static void Typeface_unref(JNIEnv* env, jobject obj, jlong faceHandle) {
81    TypefaceImpl* face = reinterpret_cast<TypefaceImpl*>(faceHandle);
82    TypefaceImpl_unref(face);
83}
84
85static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) {
86    TypefaceImpl* face = reinterpret_cast<TypefaceImpl*>(faceHandle);
87    return TypefaceImpl_getStyle(face);
88}
89
90static jlong Typeface_createFromAsset(JNIEnv* env, jobject,
91                                      jobject jassetMgr,
92                                      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 NULL;
99    }
100
101    AutoJavaStringToUTF8 str(env, jpath);
102    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
103    if (NULL == asset) {
104        return NULL;
105    }
106
107    return reinterpret_cast<jlong>(TypefaceImpl_createFromAsset(asset));
108}
109
110static jlong Typeface_createFromFile(JNIEnv* env, jobject, jstring jpath) {
111    NPE_CHECK_RETURN_ZERO(env, jpath);
112
113    AutoJavaStringToUTF8 str(env, jpath);
114    return reinterpret_cast<jlong>(TypefaceImpl_createFromFile(str.c_str()));
115}
116
117///////////////////////////////////////////////////////////////////////////////
118
119static JNINativeMethod gTypefaceMethods[] = {
120    { "nativeCreate",        "(Ljava/lang/String;I)J", (void*)Typeface_create },
121    { "nativeCreateFromTypeface", "(JI)J", (void*)Typeface_createFromTypeface },
122    { "nativeUnref",              "(J)V",  (void*)Typeface_unref },
123    { "nativeGetStyle",           "(J)I",  (void*)Typeface_getStyle },
124    { "nativeCreateFromAsset",    "(Landroid/content/res/AssetManager;Ljava/lang/String;)J",
125                                           (void*)Typeface_createFromAsset },
126    { "nativeCreateFromFile",     "(Ljava/lang/String;)J",
127                                           (void*)Typeface_createFromFile },
128};
129
130int register_android_graphics_Typeface(JNIEnv* env)
131{
132    return android::AndroidRuntime::registerNativeMethods(env,
133                                                       "android/graphics/Typeface",
134                                                       gTypefaceMethods,
135                                                       SK_ARRAY_COUNT(gTypefaceMethods));
136}
137