Home | History | Annotate | Download | only in graphics
      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 
     11 using namespace android;
     12 
     13 class AutoJavaStringToUTF8 {
     14 public:
     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 
     25 private:
     26     JNIEnv*     fEnv;
     27     jstring     fJStr;
     28     const char* fCStr;
     29 };
     30 
     31 static 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 
     54 static 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 
     69 static void Typeface_unref(JNIEnv* env, jobject obj, SkTypeface* face) {
     70     SkSafeUnref(face);
     71 }
     72 
     73 static int Typeface_getStyle(JNIEnv* env, jobject obj, SkTypeface* face) {
     74     return face->style();
     75 }
     76 
     77 static 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 
    106 static 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 
    116 static 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 
    127 int 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