Typeface.cpp revision f8d8777dddf91c741981b4f795f2fb2b1d81c1b6
1#include "jni.h" 2#include <android_runtime/AndroidRuntime.h> 3 4#include "GraphicsJNI.h" 5#include "SkStream.h" 6#include "SkTypeface.h" 7#include "Utils.h" 8#include <android_runtime/android_util_AssetManager.h> 9#include <androidfw/AssetManager.h> 10 11using namespace android; 12 13class AutoJavaStringToUTF8 { 14public: 15 AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) 16 { 17 fCStr = env->GetStringUTFChars(str, NULL); 18 } 19 ~AutoJavaStringToUTF8() 20 { 21 fEnv->ReleaseStringUTFChars(fJStr, fCStr); 22 } 23 const char* c_str() const { return fCStr; } 24 25private: 26 JNIEnv* fEnv; 27 jstring fJStr; 28 const char* fCStr; 29}; 30 31static jlong Typeface_create(JNIEnv* env, jobject, jstring name, 32 jint styleHandle) { 33 SkTypeface::Style style = static_cast<SkTypeface::Style>(styleHandle); 34 SkTypeface* face = NULL; 35 36 if (NULL != name) { 37 AutoJavaStringToUTF8 str(env, name); 38 face = SkTypeface::CreateFromName(str.c_str(), style); 39 // Try to find the closest matching font, using the standard heuristic 40 if (NULL == face) { 41 face = SkTypeface::CreateFromName(str.c_str(), (SkTypeface::Style)(style ^ SkTypeface::kItalic)); 42 } 43 for (int i = 0; NULL == face && i < 4; i++) { 44 face = SkTypeface::CreateFromName(str.c_str(), (SkTypeface::Style)i); 45 } 46 } 47 48 // return the default font at the best style if no exact match exists 49 if (NULL == face) { 50 face = SkTypeface::CreateFromName(NULL, style); 51 } 52 return reinterpret_cast<jlong>(face); 53} 54 55static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandle, jint style) { 56 SkTypeface* family = reinterpret_cast<SkTypeface*>(familyHandle); 57 SkTypeface* face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)style); 58 // Try to find the closest matching font, using the standard heuristic 59 if (NULL == face) { 60 face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic)); 61 } 62 for (int i = 0; NULL == face && i < 4; i++) { 63 face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)i); 64 } 65 if (NULL == face) { 66 face = SkTypeface::CreateFromName(NULL, (SkTypeface::Style)style); 67 } 68 return reinterpret_cast<jlong>(face); 69} 70 71static void Typeface_unref(JNIEnv* env, jobject obj, jlong faceHandle) { 72 SkTypeface* face = reinterpret_cast<SkTypeface*>(faceHandle); 73 SkSafeUnref(face); 74} 75 76static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) { 77 SkTypeface* face = reinterpret_cast<SkTypeface*>(faceHandle); 78 return static_cast<jint>(face->style()); 79} 80 81static jlong Typeface_createFromAsset(JNIEnv* env, jobject, 82 jobject jassetMgr, 83 jstring jpath) { 84 85 NPE_CHECK_RETURN_ZERO(env, jassetMgr); 86 NPE_CHECK_RETURN_ZERO(env, jpath); 87 88 AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr); 89 if (NULL == mgr) { 90 return NULL; 91 } 92 93 AutoJavaStringToUTF8 str(env, jpath); 94 Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER); 95 if (NULL == asset) { 96 return NULL; 97 } 98 99 SkStream* stream = new AssetStreamAdaptor(asset, 100 AssetStreamAdaptor::kYes_OwnAsset, 101 AssetStreamAdaptor::kYes_HasMemoryBase); 102 SkTypeface* face = SkTypeface::CreateFromStream(stream); 103 // SkTypeFace::CreateFromStream calls ref() on the stream, so we 104 // need to unref it here or it won't be freed later on 105 stream->unref(); 106 107 return reinterpret_cast<jlong>(face); 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 115 return reinterpret_cast<jlong>(SkTypeface::CreateFromFile(str.c_str())); 116} 117 118/////////////////////////////////////////////////////////////////////////////// 119 120static JNINativeMethod gTypefaceMethods[] = { 121 { "nativeCreate", "(Ljava/lang/String;I)J", (void*)Typeface_create }, 122 { "nativeCreateFromTypeface", "(JI)J", (void*)Typeface_createFromTypeface }, 123 { "nativeUnref", "(J)V", (void*)Typeface_unref }, 124 { "nativeGetStyle", "(J)I", (void*)Typeface_getStyle }, 125 { "nativeCreateFromAsset", "(Landroid/content/res/AssetManager;Ljava/lang/String;)J", 126 (void*)Typeface_createFromAsset }, 127 { "nativeCreateFromFile", "(Ljava/lang/String;)J", 128 (void*)Typeface_createFromFile }, 129}; 130 131int register_android_graphics_Typeface(JNIEnv* env) 132{ 133 return android::AndroidRuntime::registerNativeMethods(env, 134 "android/graphics/Typeface", 135 gTypefaceMethods, 136 SK_ARRAY_COUNT(gTypefaceMethods)); 137} 138