Typeface.cpp revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
1#include "jni.h" 2#include <android_runtime/AndroidRuntime.h> 3 4#include "GraphicsJNI.h" 5#include <android_runtime/android_util_AssetManager.h> 6#include "SkStream.h" 7#include "SkTypeface.h" 8#include <utils/AssetManager.h> 9 10using namespace android; 11 12class AutoJavaStringToUTF8 { 13public: 14 AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) 15 { 16 fCStr = env->GetStringUTFChars(str, NULL); 17 } 18 ~AutoJavaStringToUTF8() 19 { 20 fEnv->ReleaseStringUTFChars(fJStr, fCStr); 21 } 22 const char* c_str() const { return fCStr; } 23 24private: 25 JNIEnv* fEnv; 26 jstring fJStr; 27 const char* fCStr; 28}; 29 30static SkTypeface* Typeface_create(JNIEnv* env, jobject, jstring name, 31 SkTypeface::Style style) { 32 SkTypeface* face; 33 34 if (NULL == name) { 35 face = SkTypeface::Create(NULL, (SkTypeface::Style)style); 36 } 37 else { 38 AutoJavaStringToUTF8 str(env, name); 39 face = SkTypeface::Create(str.c_str(), style); 40 } 41 return face; 42} 43 44static SkTypeface* Typeface_createFromTypeface(JNIEnv* env, jobject, SkTypeface* family, int style) { 45 return SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)style); 46} 47 48static void Typeface_unref(JNIEnv* env, jobject obj, SkTypeface* face) { 49 face->unref(); 50} 51 52static int Typeface_getStyle(JNIEnv* env, jobject obj, SkTypeface* face) { 53 return face->getStyle(); 54} 55 56class AssetStream : public SkStream { 57public: 58 AssetStream(Asset* asset, bool hasMemoryBase) : fAsset(asset) 59 { 60 fMemoryBase = hasMemoryBase ? fAsset->getBuffer(false) : NULL; 61 } 62 63 virtual ~AssetStream() 64 { 65 delete fAsset; 66 } 67 68 virtual const void* getMemoryBase() 69 { 70 return fMemoryBase; 71 } 72 73 virtual bool rewind() 74 { 75 off_t pos = fAsset->seek(0, SEEK_SET); 76 return pos != (off_t)-1; 77 } 78 79 virtual size_t read(void* buffer, size_t size) 80 { 81 ssize_t amount; 82 83 if (NULL == buffer) 84 { 85 if (0 == size) // caller is asking us for our total length 86 return fAsset->getLength(); 87 88 // asset->seek returns new total offset 89 // we want to return amount that was skipped 90 91 off_t oldOffset = fAsset->seek(0, SEEK_CUR); 92 if (-1 == oldOffset) 93 return 0; 94 off_t newOffset = fAsset->seek(size, SEEK_CUR); 95 if (-1 == newOffset) 96 return 0; 97 98 amount = newOffset - oldOffset; 99 } 100 else 101 { 102 amount = fAsset->read(buffer, size); 103 } 104 105 if (amount < 0) 106 amount = 0; 107 return amount; 108 } 109 110private: 111 Asset* fAsset; 112 const void* fMemoryBase; 113}; 114 115static SkTypeface* Typeface_createFromAsset(JNIEnv* env, jobject, 116 jobject jassetMgr, 117 jstring jpath) { 118 119 NPE_CHECK_RETURN_ZERO(env, jassetMgr); 120 NPE_CHECK_RETURN_ZERO(env, jpath); 121 122 AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr); 123 if (NULL == mgr) { 124 return NULL; 125 } 126 127 AutoJavaStringToUTF8 str(env, jpath); 128 Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER); 129 if (NULL == asset) { 130 return NULL; 131 } 132 133 return SkTypeface::CreateFromStream(new AssetStream(asset, true)); 134} 135 136/////////////////////////////////////////////////////////////////////////////// 137 138static JNINativeMethod gTypefaceMethods[] = { 139 { "nativeCreate", "(Ljava/lang/String;I)I", (void*)Typeface_create }, 140 { "nativeCreateFromTypeface", "(II)I", (void*)Typeface_createFromTypeface }, 141 { "nativeUnref", "(I)V", (void*)Typeface_unref }, 142 { "nativeGetStyle", "(I)I", (void*)Typeface_getStyle }, 143 { "nativeCreateFromAsset", 144 "(Landroid/content/res/AssetManager;Ljava/lang/String;)I", 145 (void*)Typeface_createFromAsset } 146}; 147 148int register_android_graphics_Typeface(JNIEnv* env); 149int register_android_graphics_Typeface(JNIEnv* env) 150{ 151 return android::AndroidRuntime::registerNativeMethods(env, 152 "android/graphics/Typeface", 153 gTypefaceMethods, 154 SK_ARRAY_COUNT(gTypefaceMethods)); 155} 156 157