blob: 04c7fb9b04d7080833a5d89c1f99517e9cd53458 [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
Elliott Hughes8451b252011-04-07 19:17:57 -0700334 const SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 const jchar* textArray = env->GetCharArrayElements(text, NULL);
336 // we double count, since measureText wants a byteLength
337 SkScalar width = paint->measureText(textArray + index, count << 1);
338 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
339 JNI_ABORT);
340
341 return SkScalarToFloat(width);
342 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 static jfloat measureText_StringII(JNIEnv* env, jobject jpaint, jstring text, int start, int end) {
345 NPE_CHECK_RETURN_ZERO(env, jpaint);
346 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700347
348 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 const jchar* textArray = env->GetStringChars(text, NULL);
350 size_t textLength = env->GetStringLength(text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 int count = end - start;
353 if ((start | count) < 0 || (size_t)count > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700354 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 return 0;
356 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 jfloat width = SkScalarToFloat(paint->measureText(textArray + start, count << 1));
359 env->ReleaseStringChars(text, textArray);
360 return width;
361 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 static jfloat measureText_String(JNIEnv* env, jobject jpaint, jstring text) {
364 NPE_CHECK_RETURN_ZERO(env, jpaint);
365 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700366
367 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 const jchar* textArray = env->GetStringChars(text, NULL);
369 size_t textLength = env->GetStringLength(text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 jfloat width = SkScalarToFloat(paint->measureText(textArray, textLength << 1));
372 env->ReleaseStringChars(text, textArray);
373 return width;
374 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 static int dotextwidths(JNIEnv* env, SkPaint* paint, const jchar text[], int count, jfloatArray widths) {
377 AutoJavaFloatArray autoWidths(env, widths, count);
378 jfloat* widthsArray = autoWidths.ptr();
379 SkScalar* scalarArray = (SkScalar*)widthsArray;
380
Elliott Hughes8451b252011-04-07 19:17:57 -0700381 count = paint->getTextWidths(text, count << 1, scalarArray);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 for (int i = 0; i < count; i++) {
383 widthsArray[i] = SkScalarToFloat(scalarArray[i]);
384 }
385 return count;
386 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 static int getTextWidths___CII_F(JNIEnv* env, jobject clazz, SkPaint* paint, jcharArray text, int index, int count, jfloatArray widths) {
389 const jchar* textArray = env->GetCharArrayElements(text, NULL);
390 count = dotextwidths(env, paint, textArray + index, count, widths);
391 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
Elliott Hughes8451b252011-04-07 19:17:57 -0700392 JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 return count;
394 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700395
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800396 static int getTextWidths__StringII_F(JNIEnv* env, jobject clazz, SkPaint* paint, jstring text,
397 int start, int end, jfloatArray widths) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 const jchar* textArray = env->GetStringChars(text, NULL);
399 int count = dotextwidths(env, paint, textArray + start, end - start, widths);
400 env->ReleaseStringChars(text, textArray);
401 return count;
402 }
Doug Felt0c702b82010-05-14 10:55:42 -0700403
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800404 static int doTextGlyphs(JNIEnv* env, SkPaint* paint, const jchar* text, jint start, jint count,
405 jint contextCount, jint flags, jcharArray glyphs) {
406 jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL);
407 HB_ShaperItem shaperItem;
408 HB_FontRec font;
409 FontData fontData;
Fabrice Di Meglio1de9e7a2011-04-05 13:43:18 -0700410 TextLayoutCacheValue::shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, text,
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800411 start, count, contextCount, flags);
412
413 int glyphCount = shaperItem.num_glyphs;
414 for (int i = 0; i < glyphCount; i++) {
415 glyphsArray[i] = (jchar) shaperItem.glyphs[i];
416 }
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700417 env->ReleaseCharArrayElements(glyphs, glyphsArray, JNI_ABORT);
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800418 return glyphCount;
419 }
420
421 static int getTextGlyphs__StringIIIII_C(JNIEnv* env, jobject clazz, SkPaint* paint,
422 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
423 jcharArray glyphs) {
424 const jchar* textArray = env->GetStringChars(text, NULL);
425 int count = doTextGlyphs(env, paint, textArray + contextStart, start - contextStart,
426 end - start, contextEnd - contextStart, flags, glyphs);
427 env->ReleaseStringChars(text, textArray);
428 return count;
429 }
430
Doug Feltf7cb1f72010-07-01 16:20:43 -0700431 static jfloat doTextRunAdvances(JNIEnv *env, SkPaint *paint, const jchar *text,
432 jint start, jint count, jint contextCount, jint flags,
Doug Felt0c702b82010-05-14 10:55:42 -0700433 jfloatArray advances, jint advancesIndex) {
434 jfloat advancesArray[count];
Doug Feltf7cb1f72010-07-01 16:20:43 -0700435 jfloat totalAdvance;
Doug Felt0c702b82010-05-14 10:55:42 -0700436
Doug Feltf7cb1f72010-07-01 16:20:43 -0700437 TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
438 advancesArray, totalAdvance);
Doug Felt0c702b82010-05-14 10:55:42 -0700439
440 if (advances != NULL) {
441 env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
442 }
443 return totalAdvance;
444 }
445
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700446 static jfloat doTextRunAdvancesICU(JNIEnv *env, SkPaint *paint, const jchar *text,
447 jint start, jint count, jint contextCount, jint flags,
448 jfloatArray advances, jint advancesIndex) {
449 jfloat advancesArray[count];
450 jfloat totalAdvance;
451
452 TextLayout::getTextRunAdvancesICU(paint, text, start, count, contextCount, flags,
453 advancesArray, totalAdvance);
454
455 if (advances != NULL) {
456 env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
457 }
458 return totalAdvance;
459 }
460
Doug Felt0c702b82010-05-14 10:55:42 -0700461 static float getTextRunAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, SkPaint* paint,
462 jcharArray text, jint index, jint count, jint contextIndex, jint contextCount,
463 jint flags, jfloatArray advances, jint advancesIndex) {
464 jchar* textArray = env->GetCharArrayElements(text, NULL);
465 jfloat result = doTextRunAdvances(env, paint, textArray + contextIndex,
466 index - contextIndex, count, contextCount, flags, advances, advancesIndex);
467 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
468 return result;
469 }
470
471 static float getTextRunAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, SkPaint* paint,
472 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
473 jfloatArray advances, jint advancesIndex) {
474 const jchar* textArray = env->GetStringChars(text, NULL);
475 jfloat result = doTextRunAdvances(env, paint, textArray + contextStart,
476 start - contextStart, end - start, contextEnd - contextStart, flags, advances,
477 advancesIndex);
478 env->ReleaseStringChars(text, textArray);
479 return result;
480 }
481
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700482 static float getTextRunAdvancesICU___CIIIII_FI(JNIEnv* env, jobject clazz, SkPaint* paint,
483 jcharArray text, jint index, jint count, jint contextIndex, jint contextCount,
484 jint flags, jfloatArray advances, jint advancesIndex) {
485 jchar* textArray = env->GetCharArrayElements(text, NULL);
486 jfloat result = doTextRunAdvancesICU(env, paint, textArray + contextIndex,
487 index - contextIndex, count, contextCount, flags, advances, advancesIndex);
488 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
489 return result;
490 }
491
492 static float getTextRunAdvancesICU__StringIIIII_FI(JNIEnv* env, jobject clazz, SkPaint* paint,
493 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
494 jfloatArray advances, jint advancesIndex) {
495 const jchar* textArray = env->GetStringChars(text, NULL);
496 jfloat result = doTextRunAdvancesICU(env, paint, textArray + contextStart,
497 start - contextStart, end - start, contextEnd - contextStart, flags, advances,
498 advancesIndex);
499 env->ReleaseStringChars(text, textArray);
500 return result;
501 }
502
Doug Felt0c702b82010-05-14 10:55:42 -0700503 static jint doTextRunCursor(JNIEnv *env, SkPaint* paint, const jchar *text, jint start,
504 jint count, jint flags, jint offset, jint opt) {
505 SkScalar scalarArray[count];
506 jchar buffer[count];
507
508 // this is where we'd call harfbuzz
509 // for now we just use ushape.c and widths returned from skia
510
511 int widths;
512 if (flags & 0x1) { // rtl, call arabic shaping in case
513 UErrorCode status = U_ZERO_ERROR;
514 // Use fixed length since we need to keep start and count valid
515 u_shapeArabic(text + start, count, buffer, count,
516 U_SHAPE_LENGTH_FIXED_SPACES_NEAR | U_SHAPE_TEXT_DIRECTION_LOGICAL |
517 U_SHAPE_LETTERS_SHAPE | U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status);
518 // we shouldn't fail unless there's an out of memory condition,
519 // in which case we're hosed anyway
520 for (int i = 0; i < count; ++i) {
521 if (buffer[i] == 0xffff) {
522 buffer[i] = 0x200b; // zero-width-space for skia
523 }
524 }
525 widths = paint->getTextWidths(buffer, count << 1, scalarArray);
526 } else {
527 widths = paint->getTextWidths(text + start, count << 1, scalarArray);
528 }
529
530 if (widths < count) {
531 // Skia operates on code points, not code units, so surrogate pairs return only one
532 // value. Expand the result so we have one value per UTF-16 code unit.
533
534 // Note, skia's getTextWidth gets confused if it encounters a surrogate pair,
535 // leaving the remaining widths zero. Not nice.
536 const jchar *chars = text + start;
537 for (int i = count, p = widths - 1; --i > p;) {
538 if (chars[i] >= 0xdc00 && chars[i] < 0xe000 &&
539 chars[i-1] >= 0xd800 && chars[i-1] < 0xdc00) {
540 scalarArray[i] = 0;
541 } else {
542 scalarArray[i] = scalarArray[--p];
543 }
544 }
545 }
546
547 jint pos = offset - start;
548 switch (opt) {
549 case AFTER:
550 if (pos < count) {
551 pos += 1;
552 }
553 // fall through
554 case AT_OR_AFTER:
555 while (pos < count && scalarArray[pos] == 0) {
556 ++pos;
557 }
558 break;
559 case BEFORE:
560 if (pos > 0) {
561 --pos;
562 }
563 // fall through
564 case AT_OR_BEFORE:
565 while (pos > 0 && scalarArray[pos] == 0) {
566 --pos;
567 }
568 break;
569 case AT:
570 default:
571 if (scalarArray[pos] == 0) {
572 pos = -1;
573 }
574 break;
575 }
576
577 if (pos != -1) {
578 pos += start;
579 }
580
581 return pos;
582 }
583
584 static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, SkPaint* paint, jcharArray text,
585 jint contextStart, jint contextCount, jint flags, jint offset, jint cursorOpt) {
586 jchar* textArray = env->GetCharArrayElements(text, NULL);
587 jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, flags,
588 offset, cursorOpt);
589 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
590 return result;
591 }
592
593 static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, SkPaint* paint, jstring text,
594 jint contextStart, jint contextEnd, jint flags, jint offset, jint cursorOpt) {
595 const jchar* textArray = env->GetStringChars(text, NULL);
596 jint result = doTextRunCursor(env, paint, textArray, contextStart,
597 contextEnd - contextStart, flags, offset, cursorOpt);
598 env->ReleaseStringChars(text, textArray);
599 return result;
600 }
601
Doug Feltf7cb1f72010-07-01 16:20:43 -0700602 static void getTextPath(JNIEnv* env, SkPaint* paint, const jchar* text, jint count,
603 jint bidiFlags, jfloat x, jfloat y, SkPath *path) {
604 TextLayout::getTextPath(paint, text, count, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700606
607 static void getTextPath___C(JNIEnv* env, jobject clazz, SkPaint* paint, jint bidiFlags,
608 jcharArray text, int index, int count, jfloat x, jfloat y, SkPath* path) {
609 const jchar* textArray = env->GetCharArrayElements(text, NULL);
610 getTextPath(env, paint, textArray + index, count, bidiFlags, x, y, path);
611 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
612 }
613
614 static void getTextPath__String(JNIEnv* env, jobject clazz, SkPaint* paint, jint bidiFlags,
615 jstring text, int start, int end, jfloat x, jfloat y, SkPath* path) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800616 const jchar* textArray = env->GetStringChars(text, NULL);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700617 getTextPath(env, paint, textArray + start, end - start, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 env->ReleaseStringChars(text, textArray);
619 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 static void setShadowLayer(JNIEnv* env, jobject jpaint, jfloat radius,
622 jfloat dx, jfloat dy, int color) {
623 NPE_CHECK_RETURN_VOID(env, jpaint);
Elliott Hughes8451b252011-04-07 19:17:57 -0700624
625 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 if (radius <= 0) {
627 paint->setLooper(NULL);
628 }
629 else {
630 paint->setLooper(new SkBlurDrawLooper(SkFloatToScalar(radius),
631 SkFloatToScalar(dx),
632 SkFloatToScalar(dy),
633 (SkColor)color))->unref();
634 }
635 }
636
637 static int breakText(JNIEnv* env, const SkPaint& paint, const jchar text[],
638 int count, float maxWidth, jfloatArray jmeasured,
639 SkPaint::TextBufferDirection tbd) {
640 SkASSERT(paint.getTextEncoding() == SkPaint::kUTF16_TextEncoding);
641
642 SkScalar measured;
643 size_t bytes = paint.breakText(text, count << 1,
644 SkFloatToScalar(maxWidth), &measured, tbd);
645 SkASSERT((bytes & 1) == 0);
646
647 if (jmeasured && env->GetArrayLength(jmeasured) > 0) {
648 AutoJavaFloatArray autoMeasured(env, jmeasured, 1);
649 jfloat* array = autoMeasured.ptr();
650 array[0] = SkScalarToFloat(measured);
651 }
652 return bytes >> 1;
653 }
654
655 static int breakTextC(JNIEnv* env, jobject jpaint, jcharArray jtext,
656 int index, int count, float maxWidth, jfloatArray jmeasuredWidth) {
657 NPE_CHECK_RETURN_ZERO(env, jpaint);
658 NPE_CHECK_RETURN_ZERO(env, jtext);
659
660 SkPaint::TextBufferDirection tbd;
661 if (count < 0) {
662 tbd = SkPaint::kBackward_TextBufferDirection;
663 count = -count;
664 }
665 else {
666 tbd = SkPaint::kForward_TextBufferDirection;
667 }
668
669 if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700670 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 return 0;
672 }
673
674 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
675 const jchar* text = env->GetCharArrayElements(jtext, NULL);
676 count = breakText(env, *paint, text + index, count, maxWidth,
677 jmeasuredWidth, tbd);
678 env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text),
679 JNI_ABORT);
680 return count;
681 }
682
683 static int breakTextS(JNIEnv* env, jobject jpaint, jstring jtext,
684 bool forwards, float maxWidth, jfloatArray jmeasuredWidth) {
685 NPE_CHECK_RETURN_ZERO(env, jpaint);
686 NPE_CHECK_RETURN_ZERO(env, jtext);
687
688 SkPaint::TextBufferDirection tbd = forwards ?
689 SkPaint::kForward_TextBufferDirection :
690 SkPaint::kBackward_TextBufferDirection;
691
692 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
693 int count = env->GetStringLength(jtext);
694 const jchar* text = env->GetStringChars(jtext, NULL);
695 count = breakText(env, *paint, text, count, maxWidth,
696 jmeasuredWidth, tbd);
697 env->ReleaseStringChars(jtext, text);
698 return count;
699 }
700
701 static void doTextBounds(JNIEnv* env, const jchar* text, int count,
702 jobject bounds, const SkPaint& paint)
703 {
704 SkRect r;
705 SkIRect ir;
Elliott Hughes8451b252011-04-07 19:17:57 -0700706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 paint.measureText(text, count << 1, &r);
708 r.roundOut(&ir);
709 GraphicsJNI::irect_to_jrect(ir, env, bounds);
710 }
711
712 static void getStringBounds(JNIEnv* env, jobject, const SkPaint* paint,
713 jstring text, int start, int end, jobject bounds)
714 {
715 const jchar* textArray = env->GetStringChars(text, NULL);
716 doTextBounds(env, textArray + start, end - start, bounds, *paint);
717 env->ReleaseStringChars(text, textArray);
718 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 static void getCharArrayBounds(JNIEnv* env, jobject, const SkPaint* paint,
721 jcharArray text, int index, int count, jobject bounds)
722 {
723 const jchar* textArray = env->GetCharArrayElements(text, NULL);
724 doTextBounds(env, textArray + index, count, bounds, *paint);
725 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
726 JNI_ABORT);
727 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729};
730
731static JNINativeMethod methods[] = {
732 {"finalizer", "(I)V", (void*) SkPaintGlue::finalizer},
733 {"native_init","()I", (void*) SkPaintGlue::init},
734 {"native_initWithPaint","(I)I", (void*) SkPaintGlue::intiWithPaint},
735 {"native_reset","(I)V", (void*) SkPaintGlue::reset},
736 {"native_set","(II)V", (void*) SkPaintGlue::assign},
737 {"getFlags","()I", (void*) SkPaintGlue::getFlags},
738 {"setFlags","(I)V", (void*) SkPaintGlue::setFlags},
739 {"setAntiAlias","(Z)V", (void*) SkPaintGlue::setAntiAlias},
740 {"setSubpixelText","(Z)V", (void*) SkPaintGlue::setSubpixelText},
741 {"setLinearText","(Z)V", (void*) SkPaintGlue::setLinearText},
742 {"setUnderlineText","(Z)V", (void*) SkPaintGlue::setUnderlineText},
743 {"setStrikeThruText","(Z)V", (void*) SkPaintGlue::setStrikeThruText},
744 {"setFakeBoldText","(Z)V", (void*) SkPaintGlue::setFakeBoldText},
745 {"setFilterBitmap","(Z)V", (void*) SkPaintGlue::setFilterBitmap},
746 {"setDither","(Z)V", (void*) SkPaintGlue::setDither},
747 {"native_getStyle","(I)I", (void*) SkPaintGlue::getStyle},
748 {"native_setStyle","(II)V", (void*) SkPaintGlue::setStyle},
749 {"getColor","()I", (void*) SkPaintGlue::getColor},
750 {"setColor","(I)V", (void*) SkPaintGlue::setColor},
751 {"getAlpha","()I", (void*) SkPaintGlue::getAlpha},
752 {"setAlpha","(I)V", (void*) SkPaintGlue::setAlpha},
753 {"getStrokeWidth","()F", (void*) SkPaintGlue::getStrokeWidth},
754 {"setStrokeWidth","(F)V", (void*) SkPaintGlue::setStrokeWidth},
755 {"getStrokeMiter","()F", (void*) SkPaintGlue::getStrokeMiter},
756 {"setStrokeMiter","(F)V", (void*) SkPaintGlue::setStrokeMiter},
757 {"native_getStrokeCap","(I)I", (void*) SkPaintGlue::getStrokeCap},
758 {"native_setStrokeCap","(II)V", (void*) SkPaintGlue::setStrokeCap},
759 {"native_getStrokeJoin","(I)I", (void*) SkPaintGlue::getStrokeJoin},
760 {"native_setStrokeJoin","(II)V", (void*) SkPaintGlue::setStrokeJoin},
761 {"native_getFillPath","(III)Z", (void*) SkPaintGlue::getFillPath},
762 {"native_setShader","(II)I", (void*) SkPaintGlue::setShader},
763 {"native_setColorFilter","(II)I", (void*) SkPaintGlue::setColorFilter},
764 {"native_setXfermode","(II)I", (void*) SkPaintGlue::setXfermode},
765 {"native_setPathEffect","(II)I", (void*) SkPaintGlue::setPathEffect},
766 {"native_setMaskFilter","(II)I", (void*) SkPaintGlue::setMaskFilter},
767 {"native_setTypeface","(II)I", (void*) SkPaintGlue::setTypeface},
768 {"native_setRasterizer","(II)I", (void*) SkPaintGlue::setRasterizer},
769 {"native_getTextAlign","(I)I", (void*) SkPaintGlue::getTextAlign},
770 {"native_setTextAlign","(II)V", (void*) SkPaintGlue::setTextAlign},
771 {"getTextSize","()F", (void*) SkPaintGlue::getTextSize},
772 {"setTextSize","(F)V", (void*) SkPaintGlue::setTextSize},
773 {"getTextScaleX","()F", (void*) SkPaintGlue::getTextScaleX},
774 {"setTextScaleX","(F)V", (void*) SkPaintGlue::setTextScaleX},
775 {"getTextSkewX","()F", (void*) SkPaintGlue::getTextSkewX},
776 {"setTextSkewX","(F)V", (void*) SkPaintGlue::setTextSkewX},
777 {"ascent","()F", (void*) SkPaintGlue::ascent},
778 {"descent","()F", (void*) SkPaintGlue::descent},
779 {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)SkPaintGlue::getFontMetrics},
780 {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)SkPaintGlue::getFontMetricsInt},
Dianne Hackbornafa78962009-09-28 17:33:54 -0700781 {"native_measureText","([CII)F", (void*) SkPaintGlue::measureText_CII},
782 {"native_measureText","(Ljava/lang/String;)F", (void*) SkPaintGlue::measureText_String},
783 {"native_measureText","(Ljava/lang/String;II)F", (void*) SkPaintGlue::measureText_StringII},
784 {"native_breakText","([CIIF[F)I", (void*) SkPaintGlue::breakTextC},
785 {"native_breakText","(Ljava/lang/String;ZF[F)I", (void*) SkPaintGlue::breakTextS},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 {"native_getTextWidths","(I[CII[F)I", (void*) SkPaintGlue::getTextWidths___CII_F},
787 {"native_getTextWidths","(ILjava/lang/String;II[F)I", (void*) SkPaintGlue::getTextWidths__StringII_F},
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700788 {"native_getTextRunAdvances","(I[CIIIII[FI)F",
789 (void*) SkPaintGlue::getTextRunAdvances___CIIIII_FI},
Doug Felt0c702b82010-05-14 10:55:42 -0700790 {"native_getTextRunAdvances","(ILjava/lang/String;IIIII[FI)F",
791 (void*) SkPaintGlue::getTextRunAdvances__StringIIIII_FI},
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700792 {"native_getTextRunAdvancesICU","(I[CIIIII[FI)F",
793 (void*) SkPaintGlue::getTextRunAdvancesICU___CIIIII_FI},
794 {"native_getTextRunAdvancesICU","(ILjava/lang/String;IIIII[FI)F",
795 (void*) SkPaintGlue::getTextRunAdvancesICU__StringIIIII_FI},
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800796 {"native_getTextGlyphs","(ILjava/lang/String;IIIII[C)I",
797 (void*) SkPaintGlue::getTextGlyphs__StringIIIII_C},
Doug Felt0c702b82010-05-14 10:55:42 -0700798 {"native_getTextRunCursor", "(I[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C},
799 {"native_getTextRunCursor", "(ILjava/lang/String;IIIII)I",
800 (void*) SkPaintGlue::getTextRunCursor__String},
Doug Feltf7cb1f72010-07-01 16:20:43 -0700801 {"native_getTextPath","(II[CIIFFI)V", (void*) SkPaintGlue::getTextPath___C},
802 {"native_getTextPath","(IILjava/lang/String;IIFFI)V", (void*) SkPaintGlue::getTextPath__String},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800803 {"nativeGetStringBounds", "(ILjava/lang/String;IILandroid/graphics/Rect;)V",
804 (void*) SkPaintGlue::getStringBounds },
805 {"nativeGetCharArrayBounds", "(I[CIILandroid/graphics/Rect;)V",
806 (void*) SkPaintGlue::getCharArrayBounds },
Romain Guy1e45aae2010-08-13 19:39:53 -0700807 {"nSetShadowLayer", "(FFFI)V", (void*)SkPaintGlue::setShadowLayer}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808};
809
810static jfieldID req_fieldID(jfieldID id) {
811 SkASSERT(id);
812 return id;
813}
814
815int register_android_graphics_Paint(JNIEnv* env) {
816 gFontMetrics_class = env->FindClass("android/graphics/Paint$FontMetrics");
817 SkASSERT(gFontMetrics_class);
818 gFontMetrics_class = (jclass)env->NewGlobalRef(gFontMetrics_class);
819
820 gFontMetrics_fieldID.top = req_fieldID(env->GetFieldID(gFontMetrics_class, "top", "F"));
821 gFontMetrics_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetrics_class, "ascent", "F"));
822 gFontMetrics_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetrics_class, "descent", "F"));
823 gFontMetrics_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetrics_class, "bottom", "F"));
824 gFontMetrics_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetrics_class, "leading", "F"));
825
826 gFontMetricsInt_class = env->FindClass("android/graphics/Paint$FontMetricsInt");
827 SkASSERT(gFontMetricsInt_class);
828 gFontMetricsInt_class = (jclass)env->NewGlobalRef(gFontMetricsInt_class);
829
830 gFontMetricsInt_fieldID.top = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "top", "I"));
831 gFontMetricsInt_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "ascent", "I"));
832 gFontMetricsInt_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "descent", "I"));
833 gFontMetricsInt_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "bottom", "I"));
834 gFontMetricsInt_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "leading", "I"));
835
836 int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Paint", methods,
837 sizeof(methods) / sizeof(methods[0]));
838 return result;
839}
840
841}