Typeface.cpp revision 5e49b497ae2019586937aae0e8159292363728b5
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 SkTypeface* Typeface_create(JNIEnv* env, jobject, jstring name, 32 SkTypeface::Style style) { 33 SkTypeface* face = NULL; 34 35 if (NULL != name) { 36 AutoJavaStringToUTF8 str(env, name); 37 face = SkTypeface::CreateFromName(str.c_str(), style); 38 // Try to find the closest matching font, using the standard heuristic 39 if (NULL == face) { 40 face = SkTypeface::CreateFromName(str.c_str(), (SkTypeface::Style)(style ^ SkTypeface::kItalic)); 41 } 42 for (int i = 0; NULL == face && i < 4; i++) { 43 face = SkTypeface::CreateFromName(str.c_str(), (SkTypeface::Style)i); 44 } 45 } 46 47 // return the default font at the best style if no exact match exists 48 if (NULL == face) { 49 face = SkTypeface::CreateFromName(NULL, style); 50 } 51 return face; 52} 53 54static SkTypeface* Typeface_createFromTypeface(JNIEnv* env, jobject, SkTypeface* family, int style) { 55 SkTypeface* face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)style); 56 // Try to find the closest matching font, using the standard heuristic 57 if (NULL == face) { 58 face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic)); 59 } 60 for (int i = 0; NULL == face && i < 4; i++) { 61 face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)i); 62 } 63 if (NULL == face) { 64 face = SkTypeface::CreateFromName(NULL, (SkTypeface::Style)style); 65 } 66 return face; 67} 68 69static void Typeface_unref(JNIEnv* env, jobject obj, SkTypeface* face) { 70 SkSafeUnref(face); 71} 72 73static int Typeface_getStyle(JNIEnv* env, jobject obj, SkTypeface* face) { 74 return face->style(); 75} 76 77static SkTypeface* Typeface_createFromAsset(JNIEnv* env, jobject, 78 jobject jassetMgr, 79 jstring jpath) { 80 81 NPE_CHECK_RETURN_ZERO(env, jassetMgr); 82 NPE_CHECK_RETURN_ZERO(env, jpath); 83 84 AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr); 85 if (NULL == mgr) { 86 return NULL; 87 } 88 89 AutoJavaStringToUTF8 str(env, jpath); 90 Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER); 91 if (NULL == asset) { 92 return NULL; 93 } 94 95 SkStream* stream = new AssetStreamAdaptor(asset, 96 AssetStreamAdaptor::kYes_OwnAsset, 97 AssetStreamAdaptor::kYes_HasMemoryBase); 98 SkTypeface* face = SkTypeface::CreateFromStream(stream); 99 // SkTypeFace::CreateFromStream calls ref() on the stream, so we 100 // need to unref it here or it won't be freed later on 101 stream->unref(); 102 103 return face; 104} 105 106static SkTypeface* Typeface_createFromFile(JNIEnv* env, jobject, jstring jpath) { 107 NPE_CHECK_RETURN_ZERO(env, jpath); 108 109 AutoJavaStringToUTF8 str(env, jpath); 110 111 return SkTypeface::CreateFromFile(str.c_str()); 112} 113 114/////////////////////////////////////////////////////////////////////////////// 115 116static JNINativeMethod gTypefaceMethods[] = { 117 { "nativeCreate", "(Ljava/lang/String;I)I", (void*)Typeface_create }, 118 { "nativeCreateFromTypeface", "(II)I", (void*)Typeface_createFromTypeface }, 119 { "nativeUnref", "(I)V", (void*)Typeface_unref }, 120 { "nativeGetStyle", "(I)I", (void*)Typeface_getStyle }, 121 { "nativeCreateFromAsset", "(Landroid/content/res/AssetManager;Ljava/lang/String;)I", 122 (void*)Typeface_createFromAsset }, 123 { "nativeCreateFromFile", "(Ljava/lang/String;)I", 124 (void*)Typeface_createFromFile }, 125}; 126 127int register_android_graphics_Typeface(JNIEnv* env) 128{ 129 return android::AndroidRuntime::registerNativeMethods(env, 130 "android/graphics/Typeface", 131 gTypefaceMethods, 132 SK_ARRAY_COUNT(gTypefaceMethods)); 133} 134