blob: 768b836b24388c0de02e94a434b26b3ff39bdbfa [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* libs/android_runtime/android/graphics/Paint.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
Elliott Hughes8451b252011-04-07 19:17:57 -07005** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008**
Elliott Hughes8451b252011-04-07 19:17:57 -07009** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010**
Elliott Hughes8451b252011-04-07 19:17:57 -070011** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015** limitations under the License.
16*/
17
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018#include "jni.h"
19#include "GraphicsJNI.h"
20#include <android_runtime/AndroidRuntime.h>
21
22#include "SkBlurDrawLooper.h"
23#include "SkColorFilter.h"
24#include "SkMaskFilter.h"
25#include "SkRasterizer.h"
26#include "SkShader.h"
27#include "SkTypeface.h"
28#include "SkXfermode.h"
Doug Felt0c702b82010-05-14 10:55:42 -070029#include "unicode/ushape.h"
Doug Feltf7cb1f72010-07-01 16:20:43 -070030#include "TextLayout.h"
Doug Felt0c702b82010-05-14 10:55:42 -070031
32// temporary for debugging
Chet Haase5c13d892010-10-08 08:37:55 -070033#include <Caches.h>
Doug Felt0c702b82010-05-14 10:55:42 -070034#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035
36namespace android {
37
38struct JMetricsID {
39 jfieldID top;
40 jfieldID ascent;
41 jfieldID descent;
42 jfieldID bottom;
43 jfieldID leading;
44};
45
46static jclass gFontMetrics_class;
47static JMetricsID gFontMetrics_fieldID;
48
49static jclass gFontMetricsInt_class;
50static JMetricsID gFontMetricsInt_fieldID;
51
Mike Reed3d63e012009-07-27 09:50:31 -040052static void defaultSettingsForAndroid(SkPaint* paint) {
53 // looks best we decided
54 paint->setHinting(SkPaint::kSlight_Hinting);
55 // utf16 is required for java
56 paint->setTextEncoding(SkPaint::kUTF16_TextEncoding);
57}
58
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059class SkPaintGlue {
60public:
Doug Felt0c702b82010-05-14 10:55:42 -070061 enum MoveOpt {
62 AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT
63 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064
65 static void finalizer(JNIEnv* env, jobject clazz, SkPaint* obj) {
66 delete obj;
67 }
68
69 static SkPaint* init(JNIEnv* env, jobject clazz) {
70 SkPaint* obj = new SkPaint();
Mike Reed3d63e012009-07-27 09:50:31 -040071 defaultSettingsForAndroid(obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 return obj;
73 }
74
75 static SkPaint* intiWithPaint(JNIEnv* env, jobject clazz, SkPaint* paint) {
76 SkPaint* obj = new SkPaint(*paint);
77 return obj;
78 }
Elliott Hughes8451b252011-04-07 19:17:57 -070079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 static void reset(JNIEnv* env, jobject clazz, SkPaint* obj) {
81 obj->reset();
Mike Reed3d63e012009-07-27 09:50:31 -040082 defaultSettingsForAndroid(obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 }
Elliott Hughes8451b252011-04-07 19:17:57 -070084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 static void assign(JNIEnv* env, jobject clazz, SkPaint* dst, const SkPaint* src) {
86 *dst = *src;
87 }
Elliott Hughes8451b252011-04-07 19:17:57 -070088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 static jint getFlags(JNIEnv* env, jobject paint) {
90 NPE_CHECK_RETURN_ZERO(env, paint);
91 return GraphicsJNI::getNativePaint(env, paint)->getFlags();
92 }
Elliott Hughes8451b252011-04-07 19:17:57 -070093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 static void setFlags(JNIEnv* env, jobject paint, jint flags) {
95 NPE_CHECK_RETURN_VOID(env, paint);
96 GraphicsJNI::getNativePaint(env, paint)->setFlags(flags);
97 }
Elliott Hughes8451b252011-04-07 19:17:57 -070098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 static void setAntiAlias(JNIEnv* env, jobject paint, jboolean aa) {
100 NPE_CHECK_RETURN_VOID(env, paint);
101 GraphicsJNI::getNativePaint(env, paint)->setAntiAlias(aa);
102 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 static void setLinearText(JNIEnv* env, jobject paint, jboolean linearText) {
105 NPE_CHECK_RETURN_VOID(env, paint);
106 GraphicsJNI::getNativePaint(env, paint)->setLinearText(linearText);
107 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 static void setSubpixelText(JNIEnv* env, jobject paint, jboolean subpixelText) {
110 NPE_CHECK_RETURN_VOID(env, paint);
111 GraphicsJNI::getNativePaint(env, paint)->setSubpixelText(subpixelText);
112 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 static void setUnderlineText(JNIEnv* env, jobject paint, jboolean underlineText) {
115 NPE_CHECK_RETURN_VOID(env, paint);
116 GraphicsJNI::getNativePaint(env, paint)->setUnderlineText(underlineText);
117 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 static void setStrikeThruText(JNIEnv* env, jobject paint, jboolean strikeThruText) {
120 NPE_CHECK_RETURN_VOID(env, paint);
121 GraphicsJNI::getNativePaint(env, paint)->setStrikeThruText(strikeThruText);
122 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 static void setFakeBoldText(JNIEnv* env, jobject paint, jboolean fakeBoldText) {
125 NPE_CHECK_RETURN_VOID(env, paint);
126 GraphicsJNI::getNativePaint(env, paint)->setFakeBoldText(fakeBoldText);
127 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
130 NPE_CHECK_RETURN_VOID(env, paint);
131 GraphicsJNI::getNativePaint(env, paint)->setFilterBitmap(filterBitmap);
132 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
135 NPE_CHECK_RETURN_VOID(env, paint);
136 GraphicsJNI::getNativePaint(env, paint)->setDither(dither);
137 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 static jint getStyle(JNIEnv* env, jobject clazz, SkPaint* obj) {
140 return obj->getStyle();
141 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 static void setStyle(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Style style) {
144 obj->setStyle(style);
145 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 static jint getColor(JNIEnv* env, jobject paint) {
148 NPE_CHECK_RETURN_ZERO(env, paint);
149 return GraphicsJNI::getNativePaint(env, paint)->getColor();
150 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static jint getAlpha(JNIEnv* env, jobject paint) {
153 NPE_CHECK_RETURN_ZERO(env, paint);
154 return GraphicsJNI::getNativePaint(env, paint)->getAlpha();
155 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 static void setColor(JNIEnv* env, jobject paint, jint color) {
158 NPE_CHECK_RETURN_VOID(env, paint);
159 GraphicsJNI::getNativePaint(env, paint)->setColor(color);
160 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static void setAlpha(JNIEnv* env, jobject paint, jint a) {
163 NPE_CHECK_RETURN_VOID(env, paint);
164 GraphicsJNI::getNativePaint(env, paint)->setAlpha(a);
165 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 static jfloat getStrokeWidth(JNIEnv* env, jobject paint) {
168 NPE_CHECK_RETURN_ZERO(env, paint);
169 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeWidth());
170 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static void setStrokeWidth(JNIEnv* env, jobject paint, jfloat width) {
173 NPE_CHECK_RETURN_VOID(env, paint);
174 GraphicsJNI::getNativePaint(env, paint)->setStrokeWidth(SkFloatToScalar(width));
175 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 static jfloat getStrokeMiter(JNIEnv* env, jobject paint) {
178 NPE_CHECK_RETURN_ZERO(env, paint);
179 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeMiter());
180 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 static void setStrokeMiter(JNIEnv* env, jobject paint, jfloat miter) {
183 NPE_CHECK_RETURN_VOID(env, paint);
184 GraphicsJNI::getNativePaint(env, paint)->setStrokeMiter(SkFloatToScalar(miter));
185 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 static jint getStrokeCap(JNIEnv* env, jobject clazz, SkPaint* obj) {
188 return obj->getStrokeCap();
189 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 static void setStrokeCap(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Cap cap) {
192 obj->setStrokeCap(cap);
193 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195 static jint getStrokeJoin(JNIEnv* env, jobject clazz, SkPaint* obj) {
196 return obj->getStrokeJoin();
197 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 static void setStrokeJoin(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Join join) {
200 obj->setStrokeJoin(join);
201 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 static jboolean getFillPath(JNIEnv* env, jobject clazz, SkPaint* obj, SkPath* src, SkPath* dst) {
204 return obj->getFillPath(*src, dst);
205 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 static SkShader* setShader(JNIEnv* env, jobject clazz, SkPaint* obj, SkShader* shader) {
208 return obj->setShader(shader);
209 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 static SkColorFilter* setColorFilter(JNIEnv* env, jobject clazz, SkPaint* obj, SkColorFilter* filter) {
212 return obj->setColorFilter(filter);
213 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 static SkXfermode* setXfermode(JNIEnv* env, jobject clazz, SkPaint* obj, SkXfermode* xfermode) {
216 return obj->setXfermode(xfermode);
217 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 static SkPathEffect* setPathEffect(JNIEnv* env, jobject clazz, SkPaint* obj, SkPathEffect* effect) {
220 return obj->setPathEffect(effect);
221 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 static SkMaskFilter* setMaskFilter(JNIEnv* env, jobject clazz, SkPaint* obj, SkMaskFilter* maskfilter) {
224 return obj->setMaskFilter(maskfilter);
225 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 static SkTypeface* setTypeface(JNIEnv* env, jobject clazz, SkPaint* obj, SkTypeface* typeface) {
228 return obj->setTypeface(typeface);
229 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 static SkRasterizer* setRasterizer(JNIEnv* env, jobject clazz, SkPaint* obj, SkRasterizer* rasterizer) {
232 return obj->setRasterizer(rasterizer);
233 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 static jint getTextAlign(JNIEnv* env, jobject clazz, SkPaint* obj) {
236 return obj->getTextAlign();
237 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 static void setTextAlign(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Align align) {
240 obj->setTextAlign(align);
241 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 static jfloat getTextSize(JNIEnv* env, jobject paint) {
244 NPE_CHECK_RETURN_ZERO(env, paint);
245 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSize());
246 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 static void setTextSize(JNIEnv* env, jobject paint, jfloat textSize) {
249 NPE_CHECK_RETURN_VOID(env, paint);
250 GraphicsJNI::getNativePaint(env, paint)->setTextSize(SkFloatToScalar(textSize));
251 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 static jfloat getTextScaleX(JNIEnv* env, jobject paint) {
254 NPE_CHECK_RETURN_ZERO(env, paint);
255 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextScaleX());
256 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 static void setTextScaleX(JNIEnv* env, jobject paint, jfloat scaleX) {
259 NPE_CHECK_RETURN_VOID(env, paint);
260 GraphicsJNI::getNativePaint(env, paint)->setTextScaleX(SkFloatToScalar(scaleX));
261 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 static jfloat getTextSkewX(JNIEnv* env, jobject paint) {
264 NPE_CHECK_RETURN_ZERO(env, paint);
265 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSkewX());
266 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 static void setTextSkewX(JNIEnv* env, jobject paint, jfloat skewX) {
269 NPE_CHECK_RETURN_VOID(env, paint);
270 GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(SkFloatToScalar(skewX));
271 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 static jfloat ascent(JNIEnv* env, jobject paint) {
274 NPE_CHECK_RETURN_ZERO(env, paint);
275 SkPaint::FontMetrics metrics;
276 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
277 return SkScalarToFloat(metrics.fAscent);
278 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 static jfloat descent(JNIEnv* env, jobject paint) {
281 NPE_CHECK_RETURN_ZERO(env, paint);
282 SkPaint::FontMetrics metrics;
283 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
284 return SkScalarToFloat(metrics.fDescent);
285 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
288 NPE_CHECK_RETURN_ZERO(env, paint);
289 SkPaint::FontMetrics metrics;
290 SkScalar spacing = GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
291
292 if (metricsObj) {
293 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
294 env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop));
295 env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent));
296 env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent));
297 env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom));
298 env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading));
299 }
300 return SkScalarToFloat(spacing);
301 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 static jint getFontMetricsInt(JNIEnv* env, jobject paint, jobject metricsObj) {
304 NPE_CHECK_RETURN_ZERO(env, paint);
305 SkPaint::FontMetrics metrics;
Elliott Hughes8451b252011-04-07 19:17:57 -0700306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
308 int ascent = SkScalarRound(metrics.fAscent);
309 int descent = SkScalarRound(metrics.fDescent);
310 int leading = SkScalarRound(metrics.fLeading);
311
312 if (metricsObj) {
313 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class));
314 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloor(metrics.fTop));
315 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent);
316 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent);
317 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeil(metrics.fBottom));
318 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading);
319 }
320 return descent - ascent + leading;
321 }
322
323 static jfloat measureText_CII(JNIEnv* env, jobject jpaint, jcharArray text, int index, int count) {
324 NPE_CHECK_RETURN_ZERO(env, jpaint);
325 NPE_CHECK_RETURN_ZERO(env, text);
326
327 size_t textLength = env->GetArrayLength(text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 if ((index | count) < 0 || (size_t)(index + count) > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700330 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 return 0;
332 }
333
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700334 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700336 jfloat result = 0;
337#if RTL_USE_HARFBUZZ
338 TextLayout::getTextRunAdvances(paint, textArray, index, count, count, paint->getFlags(),
339 NULL /* dont need all advances */, result);
340#else
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 // we double count, since measureText wants a byteLength
342 SkScalar width = paint->measureText(textArray + index, count << 1);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700343 result = SkScalarToFloat(width);
344#endif
345 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
346 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 static jfloat measureText_StringII(JNIEnv* env, jobject jpaint, jstring text, int start, int end) {
350 NPE_CHECK_RETURN_ZERO(env, jpaint);
351 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700352
353 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 const jchar* textArray = env->GetStringChars(text, NULL);
Elliott Hughes8451b252011-04-07 19:17:57 -0700355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 int count = end - start;
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700357 size_t textLength = env->GetStringLength(text);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 if ((start | count) < 0 || (size_t)count > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700359 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 return 0;
361 }
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700362 jfloat width = 0;
Elliott Hughes8451b252011-04-07 19:17:57 -0700363
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700364#if RTL_USE_HARFBUZZ
365 TextLayout::getTextRunAdvances(paint, textArray, 0, count, count, paint->getFlags(),
366 NULL /* dont need all advances */, width);
367#else
368
369 width = SkScalarToFloat(paint->measureText(textArray + start, count << 1));
370#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 env->ReleaseStringChars(text, textArray);
372 return width;
373 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 static jfloat measureText_String(JNIEnv* env, jobject jpaint, jstring text) {
376 NPE_CHECK_RETURN_ZERO(env, jpaint);
377 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700378
379 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 const jchar* textArray = env->GetStringChars(text, NULL);
381 size_t textLength = env->GetStringLength(text);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700382 jfloat width = 0;
383#if RTL_USE_HARFBUZZ
384 TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength, paint->getFlags(),
385 NULL /* dont need all advances */, width);
386#else
387 width = SkScalarToFloat(paint->measureText(textArray, textLength << 1));
388#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 env->ReleaseStringChars(text, textArray);
390 return width;
391 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 static int dotextwidths(JNIEnv* env, SkPaint* paint, const jchar text[], int count, jfloatArray widths) {
394 AutoJavaFloatArray autoWidths(env, widths, count);
395 jfloat* widthsArray = autoWidths.ptr();
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700396#if RTL_USE_HARFBUZZ
397 jfloat totalAdvance;
398
399 TextLayout::getTextRunAdvances(paint, text, 0, count, count, paint->getFlags(),
400 widthsArray, totalAdvance);
401#else
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 SkScalar* scalarArray = (SkScalar*)widthsArray;
403
Elliott Hughes8451b252011-04-07 19:17:57 -0700404 count = paint->getTextWidths(text, count << 1, scalarArray);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 for (int i = 0; i < count; i++) {
406 widthsArray[i] = SkScalarToFloat(scalarArray[i]);
407 }
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700408#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 return count;
410 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 static int getTextWidths___CII_F(JNIEnv* env, jobject clazz, SkPaint* paint, jcharArray text, int index, int count, jfloatArray widths) {
413 const jchar* textArray = env->GetCharArrayElements(text, NULL);
414 count = dotextwidths(env, paint, textArray + index, count, widths);
415 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
Elliott Hughes8451b252011-04-07 19:17:57 -0700416 JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 return count;
418 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700419
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800420 static int getTextWidths__StringII_F(JNIEnv* env, jobject clazz, SkPaint* paint, jstring text,
421 int start, int end, jfloatArray widths) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 const jchar* textArray = env->GetStringChars(text, NULL);
423 int count = dotextwidths(env, paint, textArray + start, end - start, widths);
424 env->ReleaseStringChars(text, textArray);
425 return count;
426 }
Doug Felt0c702b82010-05-14 10:55:42 -0700427
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800428 static int doTextGlyphs(JNIEnv* env, SkPaint* paint, const jchar* text, jint start, jint count,
429 jint contextCount, jint flags, jcharArray glyphs) {
430 jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL);
431 HB_ShaperItem shaperItem;
432 HB_FontRec font;
433 FontData fontData;
Fabrice Di Meglio1de9e7a2011-04-05 13:43:18 -0700434 TextLayoutCacheValue::shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, text,
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800435 start, count, contextCount, flags);
436
437 int glyphCount = shaperItem.num_glyphs;
438 for (int i = 0; i < glyphCount; i++) {
439 glyphsArray[i] = (jchar) shaperItem.glyphs[i];
440 }
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700441 env->ReleaseCharArrayElements(glyphs, glyphsArray, JNI_ABORT);
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800442 return glyphCount;
443 }
444
445 static int getTextGlyphs__StringIIIII_C(JNIEnv* env, jobject clazz, SkPaint* paint,
446 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
447 jcharArray glyphs) {
448 const jchar* textArray = env->GetStringChars(text, NULL);
449 int count = doTextGlyphs(env, paint, textArray + contextStart, start - contextStart,
450 end - start, contextEnd - contextStart, flags, glyphs);
451 env->ReleaseStringChars(text, textArray);
452 return count;
453 }
454
Doug Feltf7cb1f72010-07-01 16:20:43 -0700455 static jfloat doTextRunAdvances(JNIEnv *env, SkPaint *paint, const jchar *text,
456 jint start, jint count, jint contextCount, jint flags,
Doug Felt0c702b82010-05-14 10:55:42 -0700457 jfloatArray advances, jint advancesIndex) {
458 jfloat advancesArray[count];
Doug Feltf7cb1f72010-07-01 16:20:43 -0700459 jfloat totalAdvance;
Doug Felt0c702b82010-05-14 10:55:42 -0700460
Doug Feltf7cb1f72010-07-01 16:20:43 -0700461 TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
462 advancesArray, totalAdvance);
Doug Felt0c702b82010-05-14 10:55:42 -0700463
464 if (advances != NULL) {
465 env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
466 }
467 return totalAdvance;
468 }
469
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700470 static jfloat doTextRunAdvancesICU(JNIEnv *env, SkPaint *paint, const jchar *text,
471 jint start, jint count, jint contextCount, jint flags,
472 jfloatArray advances, jint advancesIndex) {
473 jfloat advancesArray[count];
474 jfloat totalAdvance;
475
476 TextLayout::getTextRunAdvancesICU(paint, text, start, count, contextCount, flags,
477 advancesArray, totalAdvance);
478
479 if (advances != NULL) {
480 env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
481 }
482 return totalAdvance;
483 }
484
Fabrice Di Meglio0a1413e2011-04-21 17:36:26 -0700485 static float getTextRunAdvances___CIIIII_FII(JNIEnv* env, jobject clazz, SkPaint* paint,
Doug Felt0c702b82010-05-14 10:55:42 -0700486 jcharArray text, jint index, jint count, jint contextIndex, jint contextCount,
Fabrice Di Meglio0a1413e2011-04-21 17:36:26 -0700487 jint flags, jfloatArray advances, jint advancesIndex, jint reserved) {
Doug Felt0c702b82010-05-14 10:55:42 -0700488 jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglio0a1413e2011-04-21 17:36:26 -0700489 jfloat result = (reserved == 0) ?
490 doTextRunAdvances(env, paint, textArray + contextIndex, index - contextIndex,
491 count, contextCount, flags, advances, advancesIndex) :
492 doTextRunAdvancesICU(env, paint, textArray + contextIndex, index - contextIndex,
493 count, contextCount, flags, advances, advancesIndex);
Doug Felt0c702b82010-05-14 10:55:42 -0700494 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
495 return result;
496 }
497
Fabrice Di Meglio0a1413e2011-04-21 17:36:26 -0700498 static float getTextRunAdvances__StringIIIII_FII(JNIEnv* env, jobject clazz, SkPaint* paint,
Doug Felt0c702b82010-05-14 10:55:42 -0700499 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
Fabrice Di Meglio0a1413e2011-04-21 17:36:26 -0700500 jfloatArray advances, jint advancesIndex, jint reserved) {
Doug Felt0c702b82010-05-14 10:55:42 -0700501 const jchar* textArray = env->GetStringChars(text, NULL);
Fabrice Di Meglio0a1413e2011-04-21 17:36:26 -0700502 jfloat result = (reserved == 0) ?
503 doTextRunAdvances(env, paint, textArray + contextStart, start - contextStart,
504 end - start, contextEnd - contextStart, flags, advances, advancesIndex) :
505 doTextRunAdvancesICU(env, paint, textArray + contextStart, start - contextStart,
506 end - start, contextEnd - contextStart, flags, advances, advancesIndex);
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700507 env->ReleaseStringChars(text, textArray);
508 return result;
509 }
510
Doug Felt0c702b82010-05-14 10:55:42 -0700511 static jint doTextRunCursor(JNIEnv *env, SkPaint* paint, const jchar *text, jint start,
512 jint count, jint flags, jint offset, jint opt) {
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700513#if RTL_USE_HARFBUZZ
514 jfloat scalarArray[count];
515 jfloat totalAdvance;
516
517 TextLayout::getTextRunAdvances(paint, text, start, count, count, flags,
518 scalarArray, totalAdvance);
519#else
Doug Felt0c702b82010-05-14 10:55:42 -0700520 SkScalar scalarArray[count];
521 jchar buffer[count];
522
523 // this is where we'd call harfbuzz
524 // for now we just use ushape.c and widths returned from skia
525
526 int widths;
527 if (flags & 0x1) { // rtl, call arabic shaping in case
528 UErrorCode status = U_ZERO_ERROR;
529 // Use fixed length since we need to keep start and count valid
530 u_shapeArabic(text + start, count, buffer, count,
531 U_SHAPE_LENGTH_FIXED_SPACES_NEAR | U_SHAPE_TEXT_DIRECTION_LOGICAL |
532 U_SHAPE_LETTERS_SHAPE | U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status);
533 // we shouldn't fail unless there's an out of memory condition,
534 // in which case we're hosed anyway
535 for (int i = 0; i < count; ++i) {
536 if (buffer[i] == 0xffff) {
537 buffer[i] = 0x200b; // zero-width-space for skia
538 }
539 }
540 widths = paint->getTextWidths(buffer, count << 1, scalarArray);
541 } else {
542 widths = paint->getTextWidths(text + start, count << 1, scalarArray);
543 }
544
545 if (widths < count) {
546 // Skia operates on code points, not code units, so surrogate pairs return only one
547 // value. Expand the result so we have one value per UTF-16 code unit.
548
549 // Note, skia's getTextWidth gets confused if it encounters a surrogate pair,
550 // leaving the remaining widths zero. Not nice.
551 const jchar *chars = text + start;
552 for (int i = count, p = widths - 1; --i > p;) {
553 if (chars[i] >= 0xdc00 && chars[i] < 0xe000 &&
554 chars[i-1] >= 0xd800 && chars[i-1] < 0xdc00) {
555 scalarArray[i] = 0;
556 } else {
557 scalarArray[i] = scalarArray[--p];
558 }
559 }
560 }
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700561#endif
Doug Felt0c702b82010-05-14 10:55:42 -0700562 jint pos = offset - start;
563 switch (opt) {
564 case AFTER:
565 if (pos < count) {
566 pos += 1;
567 }
568 // fall through
569 case AT_OR_AFTER:
570 while (pos < count && scalarArray[pos] == 0) {
571 ++pos;
572 }
573 break;
574 case BEFORE:
575 if (pos > 0) {
576 --pos;
577 }
578 // fall through
579 case AT_OR_BEFORE:
580 while (pos > 0 && scalarArray[pos] == 0) {
581 --pos;
582 }
583 break;
584 case AT:
585 default:
586 if (scalarArray[pos] == 0) {
587 pos = -1;
588 }
589 break;
590 }
591
592 if (pos != -1) {
593 pos += start;
594 }
595
596 return pos;
597 }
598
599 static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, SkPaint* paint, jcharArray text,
600 jint contextStart, jint contextCount, jint flags, jint offset, jint cursorOpt) {
601 jchar* textArray = env->GetCharArrayElements(text, NULL);
602 jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, flags,
603 offset, cursorOpt);
604 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
605 return result;
606 }
607
608 static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, SkPaint* paint, jstring text,
609 jint contextStart, jint contextEnd, jint flags, jint offset, jint cursorOpt) {
610 const jchar* textArray = env->GetStringChars(text, NULL);
611 jint result = doTextRunCursor(env, paint, textArray, contextStart,
612 contextEnd - contextStart, flags, offset, cursorOpt);
613 env->ReleaseStringChars(text, textArray);
614 return result;
615 }
616
Doug Feltf7cb1f72010-07-01 16:20:43 -0700617 static void getTextPath(JNIEnv* env, SkPaint* paint, const jchar* text, jint count,
618 jint bidiFlags, jfloat x, jfloat y, SkPath *path) {
619 TextLayout::getTextPath(paint, text, count, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800620 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700621
622 static void getTextPath___C(JNIEnv* env, jobject clazz, SkPaint* paint, jint bidiFlags,
623 jcharArray text, int index, int count, jfloat x, jfloat y, SkPath* path) {
624 const jchar* textArray = env->GetCharArrayElements(text, NULL);
625 getTextPath(env, paint, textArray + index, count, bidiFlags, x, y, path);
626 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
627 }
628
629 static void getTextPath__String(JNIEnv* env, jobject clazz, SkPaint* paint, jint bidiFlags,
630 jstring text, int start, int end, jfloat x, jfloat y, SkPath* path) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 const jchar* textArray = env->GetStringChars(text, NULL);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700632 getTextPath(env, paint, textArray + start, end - start, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 env->ReleaseStringChars(text, textArray);
634 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636 static void setShadowLayer(JNIEnv* env, jobject jpaint, jfloat radius,
637 jfloat dx, jfloat dy, int color) {
638 NPE_CHECK_RETURN_VOID(env, jpaint);
Elliott Hughes8451b252011-04-07 19:17:57 -0700639
640 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 if (radius <= 0) {
642 paint->setLooper(NULL);
643 }
644 else {
645 paint->setLooper(new SkBlurDrawLooper(SkFloatToScalar(radius),
646 SkFloatToScalar(dx),
647 SkFloatToScalar(dy),
648 (SkColor)color))->unref();
649 }
650 }
651
652 static int breakText(JNIEnv* env, const SkPaint& paint, const jchar text[],
653 int count, float maxWidth, jfloatArray jmeasured,
654 SkPaint::TextBufferDirection tbd) {
655 SkASSERT(paint.getTextEncoding() == SkPaint::kUTF16_TextEncoding);
656
657 SkScalar measured;
658 size_t bytes = paint.breakText(text, count << 1,
659 SkFloatToScalar(maxWidth), &measured, tbd);
660 SkASSERT((bytes & 1) == 0);
661
662 if (jmeasured && env->GetArrayLength(jmeasured) > 0) {
663 AutoJavaFloatArray autoMeasured(env, jmeasured, 1);
664 jfloat* array = autoMeasured.ptr();
665 array[0] = SkScalarToFloat(measured);
666 }
667 return bytes >> 1;
668 }
669
670 static int breakTextC(JNIEnv* env, jobject jpaint, jcharArray jtext,
671 int index, int count, float maxWidth, jfloatArray jmeasuredWidth) {
672 NPE_CHECK_RETURN_ZERO(env, jpaint);
673 NPE_CHECK_RETURN_ZERO(env, jtext);
674
675 SkPaint::TextBufferDirection tbd;
676 if (count < 0) {
677 tbd = SkPaint::kBackward_TextBufferDirection;
678 count = -count;
679 }
680 else {
681 tbd = SkPaint::kForward_TextBufferDirection;
682 }
683
684 if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700685 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 return 0;
687 }
688
689 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
690 const jchar* text = env->GetCharArrayElements(jtext, NULL);
691 count = breakText(env, *paint, text + index, count, maxWidth,
692 jmeasuredWidth, tbd);
693 env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text),
694 JNI_ABORT);
695 return count;
696 }
697
698 static int breakTextS(JNIEnv* env, jobject jpaint, jstring jtext,
699 bool forwards, float maxWidth, jfloatArray jmeasuredWidth) {
700 NPE_CHECK_RETURN_ZERO(env, jpaint);
701 NPE_CHECK_RETURN_ZERO(env, jtext);
702
703 SkPaint::TextBufferDirection tbd = forwards ?
704 SkPaint::kForward_TextBufferDirection :
705 SkPaint::kBackward_TextBufferDirection;
706
707 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
708 int count = env->GetStringLength(jtext);
709 const jchar* text = env->GetStringChars(jtext, NULL);
710 count = breakText(env, *paint, text, count, maxWidth,
711 jmeasuredWidth, tbd);
712 env->ReleaseStringChars(jtext, text);
713 return count;
714 }
715
716 static void doTextBounds(JNIEnv* env, const jchar* text, int count,
717 jobject bounds, const SkPaint& paint)
718 {
719 SkRect r;
720 SkIRect ir;
Elliott Hughes8451b252011-04-07 19:17:57 -0700721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 paint.measureText(text, count << 1, &r);
723 r.roundOut(&ir);
724 GraphicsJNI::irect_to_jrect(ir, env, bounds);
725 }
726
727 static void getStringBounds(JNIEnv* env, jobject, const SkPaint* paint,
728 jstring text, int start, int end, jobject bounds)
729 {
730 const jchar* textArray = env->GetStringChars(text, NULL);
731 doTextBounds(env, textArray + start, end - start, bounds, *paint);
732 env->ReleaseStringChars(text, textArray);
733 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 static void getCharArrayBounds(JNIEnv* env, jobject, const SkPaint* paint,
736 jcharArray text, int index, int count, jobject bounds)
737 {
738 const jchar* textArray = env->GetCharArrayElements(text, NULL);
739 doTextBounds(env, textArray + index, count, bounds, *paint);
740 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
741 JNI_ABORT);
742 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744};
745
746static JNINativeMethod methods[] = {
747 {"finalizer", "(I)V", (void*) SkPaintGlue::finalizer},
748 {"native_init","()I", (void*) SkPaintGlue::init},
749 {"native_initWithPaint","(I)I", (void*) SkPaintGlue::intiWithPaint},
750 {"native_reset","(I)V", (void*) SkPaintGlue::reset},
751 {"native_set","(II)V", (void*) SkPaintGlue::assign},
752 {"getFlags","()I", (void*) SkPaintGlue::getFlags},
753 {"setFlags","(I)V", (void*) SkPaintGlue::setFlags},
754 {"setAntiAlias","(Z)V", (void*) SkPaintGlue::setAntiAlias},
755 {"setSubpixelText","(Z)V", (void*) SkPaintGlue::setSubpixelText},
756 {"setLinearText","(Z)V", (void*) SkPaintGlue::setLinearText},
757 {"setUnderlineText","(Z)V", (void*) SkPaintGlue::setUnderlineText},
758 {"setStrikeThruText","(Z)V", (void*) SkPaintGlue::setStrikeThruText},
759 {"setFakeBoldText","(Z)V", (void*) SkPaintGlue::setFakeBoldText},
760 {"setFilterBitmap","(Z)V", (void*) SkPaintGlue::setFilterBitmap},
761 {"setDither","(Z)V", (void*) SkPaintGlue::setDither},
762 {"native_getStyle","(I)I", (void*) SkPaintGlue::getStyle},
763 {"native_setStyle","(II)V", (void*) SkPaintGlue::setStyle},
764 {"getColor","()I", (void*) SkPaintGlue::getColor},
765 {"setColor","(I)V", (void*) SkPaintGlue::setColor},
766 {"getAlpha","()I", (void*) SkPaintGlue::getAlpha},
767 {"setAlpha","(I)V", (void*) SkPaintGlue::setAlpha},
768 {"getStrokeWidth","()F", (void*) SkPaintGlue::getStrokeWidth},
769 {"setStrokeWidth","(F)V", (void*) SkPaintGlue::setStrokeWidth},
770 {"getStrokeMiter","()F", (void*) SkPaintGlue::getStrokeMiter},
771 {"setStrokeMiter","(F)V", (void*) SkPaintGlue::setStrokeMiter},
772 {"native_getStrokeCap","(I)I", (void*) SkPaintGlue::getStrokeCap},
773 {"native_setStrokeCap","(II)V", (void*) SkPaintGlue::setStrokeCap},
774 {"native_getStrokeJoin","(I)I", (void*) SkPaintGlue::getStrokeJoin},
775 {"native_setStrokeJoin","(II)V", (void*) SkPaintGlue::setStrokeJoin},
776 {"native_getFillPath","(III)Z", (void*) SkPaintGlue::getFillPath},
777 {"native_setShader","(II)I", (void*) SkPaintGlue::setShader},
778 {"native_setColorFilter","(II)I", (void*) SkPaintGlue::setColorFilter},
779 {"native_setXfermode","(II)I", (void*) SkPaintGlue::setXfermode},
780 {"native_setPathEffect","(II)I", (void*) SkPaintGlue::setPathEffect},
781 {"native_setMaskFilter","(II)I", (void*) SkPaintGlue::setMaskFilter},
782 {"native_setTypeface","(II)I", (void*) SkPaintGlue::setTypeface},
783 {"native_setRasterizer","(II)I", (void*) SkPaintGlue::setRasterizer},
784 {"native_getTextAlign","(I)I", (void*) SkPaintGlue::getTextAlign},
785 {"native_setTextAlign","(II)V", (void*) SkPaintGlue::setTextAlign},
786 {"getTextSize","()F", (void*) SkPaintGlue::getTextSize},
787 {"setTextSize","(F)V", (void*) SkPaintGlue::setTextSize},
788 {"getTextScaleX","()F", (void*) SkPaintGlue::getTextScaleX},
789 {"setTextScaleX","(F)V", (void*) SkPaintGlue::setTextScaleX},
790 {"getTextSkewX","()F", (void*) SkPaintGlue::getTextSkewX},
791 {"setTextSkewX","(F)V", (void*) SkPaintGlue::setTextSkewX},
792 {"ascent","()F", (void*) SkPaintGlue::ascent},
793 {"descent","()F", (void*) SkPaintGlue::descent},
794 {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)SkPaintGlue::getFontMetrics},
795 {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)SkPaintGlue::getFontMetricsInt},
Dianne Hackbornafa78962009-09-28 17:33:54 -0700796 {"native_measureText","([CII)F", (void*) SkPaintGlue::measureText_CII},
797 {"native_measureText","(Ljava/lang/String;)F", (void*) SkPaintGlue::measureText_String},
798 {"native_measureText","(Ljava/lang/String;II)F", (void*) SkPaintGlue::measureText_StringII},
799 {"native_breakText","([CIIF[F)I", (void*) SkPaintGlue::breakTextC},
800 {"native_breakText","(Ljava/lang/String;ZF[F)I", (void*) SkPaintGlue::breakTextS},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 {"native_getTextWidths","(I[CII[F)I", (void*) SkPaintGlue::getTextWidths___CII_F},
802 {"native_getTextWidths","(ILjava/lang/String;II[F)I", (void*) SkPaintGlue::getTextWidths__StringII_F},
Fabrice Di Meglio0a1413e2011-04-21 17:36:26 -0700803 {"native_getTextRunAdvances","(I[CIIIII[FII)F",
804 (void*) SkPaintGlue::getTextRunAdvances___CIIIII_FII},
805 {"native_getTextRunAdvances","(ILjava/lang/String;IIIII[FII)F",
806 (void*) SkPaintGlue::getTextRunAdvances__StringIIIII_FII},
807
808
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800809 {"native_getTextGlyphs","(ILjava/lang/String;IIIII[C)I",
810 (void*) SkPaintGlue::getTextGlyphs__StringIIIII_C},
Doug Felt0c702b82010-05-14 10:55:42 -0700811 {"native_getTextRunCursor", "(I[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C},
812 {"native_getTextRunCursor", "(ILjava/lang/String;IIIII)I",
813 (void*) SkPaintGlue::getTextRunCursor__String},
Doug Feltf7cb1f72010-07-01 16:20:43 -0700814 {"native_getTextPath","(II[CIIFFI)V", (void*) SkPaintGlue::getTextPath___C},
815 {"native_getTextPath","(IILjava/lang/String;IIFFI)V", (void*) SkPaintGlue::getTextPath__String},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 {"nativeGetStringBounds", "(ILjava/lang/String;IILandroid/graphics/Rect;)V",
817 (void*) SkPaintGlue::getStringBounds },
818 {"nativeGetCharArrayBounds", "(I[CIILandroid/graphics/Rect;)V",
819 (void*) SkPaintGlue::getCharArrayBounds },
Romain Guy1e45aae2010-08-13 19:39:53 -0700820 {"nSetShadowLayer", "(FFFI)V", (void*)SkPaintGlue::setShadowLayer}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821};
822
823static jfieldID req_fieldID(jfieldID id) {
824 SkASSERT(id);
825 return id;
826}
827
828int register_android_graphics_Paint(JNIEnv* env) {
829 gFontMetrics_class = env->FindClass("android/graphics/Paint$FontMetrics");
830 SkASSERT(gFontMetrics_class);
831 gFontMetrics_class = (jclass)env->NewGlobalRef(gFontMetrics_class);
832
833 gFontMetrics_fieldID.top = req_fieldID(env->GetFieldID(gFontMetrics_class, "top", "F"));
834 gFontMetrics_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetrics_class, "ascent", "F"));
835 gFontMetrics_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetrics_class, "descent", "F"));
836 gFontMetrics_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetrics_class, "bottom", "F"));
837 gFontMetrics_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetrics_class, "leading", "F"));
838
839 gFontMetricsInt_class = env->FindClass("android/graphics/Paint$FontMetricsInt");
840 SkASSERT(gFontMetricsInt_class);
841 gFontMetricsInt_class = (jclass)env->NewGlobalRef(gFontMetricsInt_class);
842
843 gFontMetricsInt_fieldID.top = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "top", "I"));
844 gFontMetricsInt_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "ascent", "I"));
845 gFontMetricsInt_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "descent", "I"));
846 gFontMetricsInt_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "bottom", "I"));
847 gFontMetricsInt_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "leading", "I"));
848
849 int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Paint", methods,
850 sizeof(methods) / sizeof(methods[0]));
851 return result;
852}
853
854}