blob: 53a5c0ada828ee66e4009831f550130688b3348c [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001#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) {
The Android Open Source Project4df24232009-03-05 14:34:35 -080035 face = SkTypeface::CreateFromName(NULL, (SkTypeface::Style)style);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036 }
37 else {
38 AutoJavaStringToUTF8 str(env, name);
The Android Open Source Project4df24232009-03-05 14:34:35 -080039 face = SkTypeface::CreateFromName(str.c_str(), style);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 }
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) {
Mike Reed31a69fd2009-12-14 14:57:01 -050049 SkSafeUnref(face);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050}
51
52static int Typeface_getStyle(JNIEnv* env, jobject obj, SkTypeface* face) {
The Android Open Source Project4df24232009-03-05 14:34:35 -080053 return face->style();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054}
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 {
Kenny Rootddb76c42010-11-24 12:56:06 -080075 off64_t pos = fAsset->seek(0, SEEK_SET);
76 return pos != (off64_t)-1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 }
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
Kenny Rootddb76c42010-11-24 12:56:06 -080091 off64_t oldOffset = fAsset->seek(0, SEEK_CUR);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 if (-1 == oldOffset)
93 return 0;
Kenny Rootddb76c42010-11-24 12:56:06 -080094 off64_t newOffset = fAsset->seek(size, SEEK_CUR);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 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
Romain Guya1db5742010-07-20 13:09:13 -0700133 SkStream* stream = new AssetStream(asset, true);
134 SkTypeface* face = SkTypeface::CreateFromStream(stream);
135 // SkTypeFace::CreateFromStream calls ref() on the stream, so we
136 // need to unref it here or it won't be freed later on
137 stream->unref();
138
139 return face;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140}
141
Romain Guya87a1322009-05-12 13:22:18 -0700142static SkTypeface* Typeface_createFromFile(JNIEnv* env, jobject, jstring jpath) {
143 NPE_CHECK_RETURN_ZERO(env, jpath);
144
145 AutoJavaStringToUTF8 str(env, jpath);
146
147 return SkTypeface::CreateFromFile(str.c_str());
148}
149
Mike Reeddbade9d2009-08-25 13:20:19 -0400150#define MIN_GAMMA (0.1f)
151#define MAX_GAMMA (10.0f)
152static float pinGamma(float gamma) {
153 if (gamma < MIN_GAMMA) {
154 gamma = MIN_GAMMA;
155 } else if (gamma > MAX_GAMMA) {
156 gamma = MAX_GAMMA;
157 }
158 return gamma;
159}
160
161extern void skia_set_text_gamma(float, float);
162
163static void Typeface_setGammaForText(JNIEnv* env, jobject, jfloat blackGamma,
164 jfloat whiteGamma) {
165 // Comment this out for release builds. This is only used during development
166 skia_set_text_gamma(pinGamma(blackGamma), pinGamma(whiteGamma));
167}
168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169///////////////////////////////////////////////////////////////////////////////
170
171static JNINativeMethod gTypefaceMethods[] = {
172 { "nativeCreate", "(Ljava/lang/String;I)I", (void*)Typeface_create },
173 { "nativeCreateFromTypeface", "(II)I", (void*)Typeface_createFromTypeface },
174 { "nativeUnref", "(I)V", (void*)Typeface_unref },
175 { "nativeGetStyle", "(I)I", (void*)Typeface_getStyle },
Romain Guya87a1322009-05-12 13:22:18 -0700176 { "nativeCreateFromAsset", "(Landroid/content/res/AssetManager;Ljava/lang/String;)I",
177 (void*)Typeface_createFromAsset },
Romain Guy2bb3ea12009-05-12 15:43:26 -0700178 { "nativeCreateFromFile", "(Ljava/lang/String;)I",
Mike Reeddbade9d2009-08-25 13:20:19 -0400179 (void*)Typeface_createFromFile },
180 { "setGammaForText", "(FF)V", (void*)Typeface_setGammaForText },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181};
182
183int register_android_graphics_Typeface(JNIEnv* env);
184int register_android_graphics_Typeface(JNIEnv* env)
185{
186 return android::AndroidRuntime::registerNativeMethods(env,
187 "android/graphics/Typeface",
188 gTypefaceMethods,
189 SK_ARRAY_COUNT(gTypefaceMethods));
190}