blob: 6c81f060184df313e29641177904db9c4bc65ee2 [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
Dianne Hackbornf43fa572011-08-12 18:59:39 -070018#define LOG_TAG "Paint"
19
20#include <utils/Log.h>
21
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022#include "jni.h"
23#include "GraphicsJNI.h"
24#include <android_runtime/AndroidRuntime.h>
Billy Hewlettac1cbaf2012-07-18 09:51:45 -070025#include <ScopedUtfChars.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026
27#include "SkBlurDrawLooper.h"
28#include "SkColorFilter.h"
29#include "SkMaskFilter.h"
30#include "SkRasterizer.h"
31#include "SkShader.h"
32#include "SkTypeface.h"
33#include "SkXfermode.h"
Billy Hewlettac1cbaf2012-07-18 09:51:45 -070034#include "unicode/uloc.h"
Doug Felt0c702b82010-05-14 10:55:42 -070035#include "unicode/ushape.h"
Doug Feltf7cb1f72010-07-01 16:20:43 -070036#include "TextLayout.h"
Doug Felt0c702b82010-05-14 10:55:42 -070037
38// temporary for debugging
Chet Haase5c13d892010-10-08 08:37:55 -070039#include <Caches.h>
Doug Felt0c702b82010-05-14 10:55:42 -070040#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
42namespace android {
43
44struct JMetricsID {
45 jfieldID top;
46 jfieldID ascent;
47 jfieldID descent;
48 jfieldID bottom;
49 jfieldID leading;
50};
51
52static jclass gFontMetrics_class;
53static JMetricsID gFontMetrics_fieldID;
54
55static jclass gFontMetricsInt_class;
56static JMetricsID gFontMetricsInt_fieldID;
57
Mike Reed3d63e012009-07-27 09:50:31 -040058static void defaultSettingsForAndroid(SkPaint* paint) {
Fabrice Di Meglioc511bee82012-01-05 13:30:54 -080059 // GlyphID encoding is required because we are using Harfbuzz shaping
60 paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Derek Sollenbergerd7a80772013-05-28 10:44:26 -040061
62 SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
63 paintOpts.setUseFontFallbacks(true);
64 paint->setPaintOptionsAndroid(paintOpts);
Mike Reed3d63e012009-07-27 09:50:31 -040065}
66
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067class SkPaintGlue {
68public:
Doug Felt0c702b82010-05-14 10:55:42 -070069 enum MoveOpt {
70 AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT
71 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072
Ashok Bhat36bef0b2014-01-20 20:08:01 +000073 static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
74 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 delete obj;
76 }
77
Ashok Bhat36bef0b2014-01-20 20:08:01 +000078 static jlong init(JNIEnv* env, jobject clazz) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 SkPaint* obj = new SkPaint();
Mike Reed3d63e012009-07-27 09:50:31 -040080 defaultSettingsForAndroid(obj);
Ashok Bhat36bef0b2014-01-20 20:08:01 +000081 return reinterpret_cast<jlong>(obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 }
83
Ashok Bhat36bef0b2014-01-20 20:08:01 +000084 static jlong initWithPaint(JNIEnv* env, jobject clazz, jlong paintHandle) {
85 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 SkPaint* obj = new SkPaint(*paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +000087 return reinterpret_cast<jlong>(obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 }
Elliott Hughes8451b252011-04-07 19:17:57 -070089
Ashok Bhat36bef0b2014-01-20 20:08:01 +000090 static void reset(JNIEnv* env, jobject clazz, jlong objHandle) {
91 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 obj->reset();
Mike Reed3d63e012009-07-27 09:50:31 -040093 defaultSettingsForAndroid(obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 }
Elliott Hughes8451b252011-04-07 19:17:57 -070095
Ashok Bhat36bef0b2014-01-20 20:08:01 +000096 static void assign(JNIEnv* env, jobject clazz, jlong dstPaintHandle, jlong srcPaintHandle) {
97 SkPaint* dst = reinterpret_cast<SkPaint*>(dstPaintHandle);
98 const SkPaint* src = reinterpret_cast<SkPaint*>(srcPaintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 *dst = *src;
100 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 static jint getFlags(JNIEnv* env, jobject paint) {
103 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000104 int result;
105 result = GraphicsJNI::getNativePaint(env, paint)->getFlags();
106 return static_cast<jint>(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 static void setFlags(JNIEnv* env, jobject paint, jint flags) {
110 NPE_CHECK_RETURN_VOID(env, paint);
111 GraphicsJNI::getNativePaint(env, paint)->setFlags(flags);
112 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700113
Dianne Hackbornf43fa572011-08-12 18:59:39 -0700114 static jint getHinting(JNIEnv* env, jobject paint) {
115 NPE_CHECK_RETURN_ZERO(env, paint);
116 return GraphicsJNI::getNativePaint(env, paint)->getHinting()
117 == SkPaint::kNo_Hinting ? 0 : 1;
118 }
119
120 static void setHinting(JNIEnv* env, jobject paint, jint mode) {
121 NPE_CHECK_RETURN_VOID(env, paint);
122 GraphicsJNI::getNativePaint(env, paint)->setHinting(
Victoria Lease88705382013-06-14 16:15:41 -0700123 mode == 0 ? SkPaint::kNo_Hinting : SkPaint::kNormal_Hinting);
Dianne Hackbornf43fa572011-08-12 18:59:39 -0700124 }
125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 static void setAntiAlias(JNIEnv* env, jobject paint, jboolean aa) {
127 NPE_CHECK_RETURN_VOID(env, paint);
128 GraphicsJNI::getNativePaint(env, paint)->setAntiAlias(aa);
129 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 static void setLinearText(JNIEnv* env, jobject paint, jboolean linearText) {
132 NPE_CHECK_RETURN_VOID(env, paint);
133 GraphicsJNI::getNativePaint(env, paint)->setLinearText(linearText);
134 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 static void setSubpixelText(JNIEnv* env, jobject paint, jboolean subpixelText) {
137 NPE_CHECK_RETURN_VOID(env, paint);
138 GraphicsJNI::getNativePaint(env, paint)->setSubpixelText(subpixelText);
139 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 static void setUnderlineText(JNIEnv* env, jobject paint, jboolean underlineText) {
142 NPE_CHECK_RETURN_VOID(env, paint);
143 GraphicsJNI::getNativePaint(env, paint)->setUnderlineText(underlineText);
144 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 static void setStrikeThruText(JNIEnv* env, jobject paint, jboolean strikeThruText) {
147 NPE_CHECK_RETURN_VOID(env, paint);
148 GraphicsJNI::getNativePaint(env, paint)->setStrikeThruText(strikeThruText);
149 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 static void setFakeBoldText(JNIEnv* env, jobject paint, jboolean fakeBoldText) {
152 NPE_CHECK_RETURN_VOID(env, paint);
153 GraphicsJNI::getNativePaint(env, paint)->setFakeBoldText(fakeBoldText);
154 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
157 NPE_CHECK_RETURN_VOID(env, paint);
158 GraphicsJNI::getNativePaint(env, paint)->setFilterBitmap(filterBitmap);
159 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
162 NPE_CHECK_RETURN_VOID(env, paint);
163 GraphicsJNI::getNativePaint(env, paint)->setDither(dither);
164 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700165
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000166 static jint getStyle(JNIEnv* env, jobject clazz,jlong objHandle) {
167 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
168 return static_cast<jint>(obj->getStyle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700170
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000171 static void setStyle(JNIEnv* env, jobject clazz, jlong objHandle, jint styleHandle) {
172 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
173 SkPaint::Style style = static_cast<SkPaint::Style>(styleHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 obj->setStyle(style);
175 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 static jint getColor(JNIEnv* env, jobject paint) {
178 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000179 int color;
180 color = GraphicsJNI::getNativePaint(env, paint)->getColor();
181 return static_cast<jint>(color);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 static jint getAlpha(JNIEnv* env, jobject paint) {
185 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000186 int alpha;
187 alpha = GraphicsJNI::getNativePaint(env, paint)->getAlpha();
188 return static_cast<jint>(alpha);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 static void setColor(JNIEnv* env, jobject paint, jint color) {
192 NPE_CHECK_RETURN_VOID(env, paint);
193 GraphicsJNI::getNativePaint(env, paint)->setColor(color);
194 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 static void setAlpha(JNIEnv* env, jobject paint, jint a) {
197 NPE_CHECK_RETURN_VOID(env, paint);
198 GraphicsJNI::getNativePaint(env, paint)->setAlpha(a);
199 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 static jfloat getStrokeWidth(JNIEnv* env, jobject paint) {
202 NPE_CHECK_RETURN_ZERO(env, paint);
203 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeWidth());
204 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 static void setStrokeWidth(JNIEnv* env, jobject paint, jfloat width) {
207 NPE_CHECK_RETURN_VOID(env, paint);
208 GraphicsJNI::getNativePaint(env, paint)->setStrokeWidth(SkFloatToScalar(width));
209 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 static jfloat getStrokeMiter(JNIEnv* env, jobject paint) {
212 NPE_CHECK_RETURN_ZERO(env, paint);
213 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeMiter());
214 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 static void setStrokeMiter(JNIEnv* env, jobject paint, jfloat miter) {
217 NPE_CHECK_RETURN_VOID(env, paint);
218 GraphicsJNI::getNativePaint(env, paint)->setStrokeMiter(SkFloatToScalar(miter));
219 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700220
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000221 static jint getStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle) {
222 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
223 return static_cast<jint>(obj->getStrokeCap());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700225
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000226 static void setStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle, jint capHandle) {
227 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
228 SkPaint::Cap cap = static_cast<SkPaint::Cap>(capHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 obj->setStrokeCap(cap);
230 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700231
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000232 static jint getStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle) {
233 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
234 return static_cast<jint>(obj->getStrokeJoin());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700236
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000237 static void setStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle, jint joinHandle) {
238 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
239 SkPaint::Join join = (SkPaint::Join) joinHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 obj->setStrokeJoin(join);
241 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700242
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000243 static jboolean getFillPath(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jlong dstHandle) {
244 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
245 SkPath* src = reinterpret_cast<SkPath*>(srcHandle);
246 SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
247 return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700249
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000250 static jlong setShader(JNIEnv* env, jobject clazz, jlong objHandle, jlong shaderHandle) {
251 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
252 SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
253 return reinterpret_cast<jlong>(obj->setShader(shader));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700255
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000256 static jlong setColorFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong filterHandle) {
257 SkPaint* obj = reinterpret_cast<SkPaint *>(objHandle);
258 SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(filterHandle);
259 return reinterpret_cast<jlong>(obj->setColorFilter(filter));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700261
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000262 static jlong setXfermode(JNIEnv* env, jobject clazz, jlong objHandle, jlong xfermodeHandle) {
263 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
264 SkXfermode* xfermode = reinterpret_cast<SkXfermode*>(xfermodeHandle);
265 return reinterpret_cast<jlong>(obj->setXfermode(xfermode));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700267
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000268 static jlong setPathEffect(JNIEnv* env, jobject clazz, jlong objHandle, jlong effectHandle) {
269 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
270 SkPathEffect* effect = reinterpret_cast<SkPathEffect*>(effectHandle);
271 return reinterpret_cast<jlong>(obj->setPathEffect(effect));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700273
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000274 static jlong setMaskFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong maskfilterHandle) {
275 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
276 SkMaskFilter* maskfilter = reinterpret_cast<SkMaskFilter*>(maskfilterHandle);
277 return reinterpret_cast<jlong>(obj->setMaskFilter(maskfilter));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700279
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000280 static jlong setTypeface(JNIEnv* env, jobject clazz, jlong objHandle, jlong typefaceHandle) {
Raph Leviena0336302013-05-22 16:16:59 -0700281#ifndef USE_MINIKIN
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000282 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
283 SkTypeface* typeface = reinterpret_cast<SkTypeface*>(typefaceHandle);
284 return reinterpret_cast<jlong>(obj->setTypeface(typeface));
Raph Leviena0336302013-05-22 16:16:59 -0700285#else
286 // TODO(raph): not yet implemented
287 return NULL;
288#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700290
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000291 static jlong setRasterizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong rasterizerHandle) {
292 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
293 SkRasterizer* rasterizer = reinterpret_cast<SkRasterizer*>(rasterizerHandle);
294 return reinterpret_cast<jlong>(obj->setRasterizer(rasterizer));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700296
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000297 static jint getTextAlign(JNIEnv* env, jobject clazz, jlong objHandle) {
298 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
299 return static_cast<jint>(obj->getTextAlign());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700301
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000302 static void setTextAlign(JNIEnv* env, jobject clazz, jlong objHandle, jint alignHandle) {
303 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
304 SkPaint::Align align = static_cast<SkPaint::Align>(alignHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 obj->setTextAlign(align);
306 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700307
Billy Hewlettac1cbaf2012-07-18 09:51:45 -0700308 // generate bcp47 identifier for the supplied locale
309 static void toLanguageTag(char* output, size_t outSize,
310 const char* locale) {
311 if (output == NULL || outSize <= 0) {
312 return;
313 }
314 if (locale == NULL) {
315 output[0] = '\0';
316 return;
317 }
318 char canonicalChars[ULOC_FULLNAME_CAPACITY];
319 UErrorCode uErr = U_ZERO_ERROR;
320 uloc_canonicalize(locale, canonicalChars, ULOC_FULLNAME_CAPACITY,
321 &uErr);
322 if (U_SUCCESS(uErr)) {
323 char likelyChars[ULOC_FULLNAME_CAPACITY];
324 uErr = U_ZERO_ERROR;
325 uloc_addLikelySubtags(canonicalChars, likelyChars,
326 ULOC_FULLNAME_CAPACITY, &uErr);
327 if (U_SUCCESS(uErr)) {
328 uErr = U_ZERO_ERROR;
329 uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr);
330 if (U_SUCCESS(uErr)) {
331 return;
332 } else {
333 ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars,
334 u_errorName(uErr));
335 }
336 } else {
337 ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s",
338 canonicalChars, u_errorName(uErr));
339 }
340 } else {
341 ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale,
342 u_errorName(uErr));
343 }
344 // unable to build a proper language identifier
345 output[0] = '\0';
346 }
347
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000348 static void setTextLocale(JNIEnv* env, jobject clazz, jlong objHandle, jstring locale) {
349 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
Billy Hewlettac1cbaf2012-07-18 09:51:45 -0700350 ScopedUtfChars localeChars(env, locale);
351 char langTag[ULOC_FULLNAME_CAPACITY];
352 toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str());
Derek Sollenbergerd7a80772013-05-28 10:44:26 -0400353
354 SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
355 paintOpts.setLanguage(langTag);
356 obj->setPaintOptionsAndroid(paintOpts);
Fabrice Di Meglio517825f2012-04-06 16:53:48 -0700357 }
358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 static jfloat getTextSize(JNIEnv* env, jobject paint) {
360 NPE_CHECK_RETURN_ZERO(env, paint);
361 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSize());
362 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 static void setTextSize(JNIEnv* env, jobject paint, jfloat textSize) {
365 NPE_CHECK_RETURN_VOID(env, paint);
366 GraphicsJNI::getNativePaint(env, paint)->setTextSize(SkFloatToScalar(textSize));
367 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 static jfloat getTextScaleX(JNIEnv* env, jobject paint) {
370 NPE_CHECK_RETURN_ZERO(env, paint);
371 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextScaleX());
372 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 static void setTextScaleX(JNIEnv* env, jobject paint, jfloat scaleX) {
375 NPE_CHECK_RETURN_VOID(env, paint);
376 GraphicsJNI::getNativePaint(env, paint)->setTextScaleX(SkFloatToScalar(scaleX));
377 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 static jfloat getTextSkewX(JNIEnv* env, jobject paint) {
380 NPE_CHECK_RETURN_ZERO(env, paint);
381 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSkewX());
382 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 static void setTextSkewX(JNIEnv* env, jobject paint, jfloat skewX) {
385 NPE_CHECK_RETURN_VOID(env, paint);
386 GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(SkFloatToScalar(skewX));
387 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 static jfloat ascent(JNIEnv* env, jobject paint) {
390 NPE_CHECK_RETURN_ZERO(env, paint);
391 SkPaint::FontMetrics metrics;
392 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
393 return SkScalarToFloat(metrics.fAscent);
394 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 static jfloat descent(JNIEnv* env, jobject paint) {
397 NPE_CHECK_RETURN_ZERO(env, paint);
398 SkPaint::FontMetrics metrics;
399 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
400 return SkScalarToFloat(metrics.fDescent);
401 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
404 NPE_CHECK_RETURN_ZERO(env, paint);
405 SkPaint::FontMetrics metrics;
406 SkScalar spacing = GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
407
408 if (metricsObj) {
409 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
410 env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop));
411 env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent));
412 env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent));
413 env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom));
414 env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading));
415 }
416 return SkScalarToFloat(spacing);
417 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 static jint getFontMetricsInt(JNIEnv* env, jobject paint, jobject metricsObj) {
420 NPE_CHECK_RETURN_ZERO(env, paint);
421 SkPaint::FontMetrics metrics;
Elliott Hughes8451b252011-04-07 19:17:57 -0700422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
424 int ascent = SkScalarRound(metrics.fAscent);
425 int descent = SkScalarRound(metrics.fDescent);
426 int leading = SkScalarRound(metrics.fLeading);
427
428 if (metricsObj) {
429 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class));
430 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloor(metrics.fTop));
431 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent);
432 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent);
433 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeil(metrics.fBottom));
434 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading);
435 }
436 return descent - ascent + leading;
437 }
438
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000439 static jfloat measureText_CIII(JNIEnv* env, jobject jpaint, jcharArray text, jint index, jint count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700440 jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 NPE_CHECK_RETURN_ZERO(env, jpaint);
442 NPE_CHECK_RETURN_ZERO(env, text);
443
444 size_t textLength = env->GetArrayLength(text);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 if ((index | count) < 0 || (size_t)(index + count) > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700446 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 return 0;
448 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700449 if (count == 0) {
450 return 0;
451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700453 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700455 jfloat result = 0;
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800456
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700457 TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700458 bidiFlags, NULL /* dont need all advances */, &result);
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800459
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700460 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
461 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700463
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000464 static jfloat measureText_StringIII(JNIEnv* env, jobject jpaint, jstring text, jint start, jint end,
Victoria Lease626d3c22013-03-27 15:35:53 -0700465 jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 NPE_CHECK_RETURN_ZERO(env, jpaint);
467 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700468
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700469 size_t textLength = env->GetStringLength(text);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 int count = end - start;
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700471 if ((start | count) < 0 || (size_t)end > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700472 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 return 0;
474 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700475 if (count == 0) {
476 return 0;
477 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700478
479 const jchar* textArray = env->GetStringChars(text, NULL);
480 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700481 jfloat width = 0;
Elliott Hughes8451b252011-04-07 19:17:57 -0700482
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700483 TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700484 bidiFlags, NULL /* dont need all advances */, &width);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 env->ReleaseStringChars(text, textArray);
487 return width;
488 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700489
Victoria Lease626d3c22013-03-27 15:35:53 -0700490 static jfloat measureText_StringI(JNIEnv* env, jobject jpaint, jstring text, jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 NPE_CHECK_RETURN_ZERO(env, jpaint);
492 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 size_t textLength = env->GetStringLength(text);
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700495 if (textLength == 0) {
496 return 0;
497 }
498
499 const jchar* textArray = env->GetStringChars(text, NULL);
500 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700501 jfloat width = 0;
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700502
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700503 TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700504 bidiFlags, NULL /* dont need all advances */, &width);
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 env->ReleaseStringChars(text, textArray);
507 return width;
508 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700509
Victoria Lease626d3c22013-03-27 15:35:53 -0700510 static int dotextwidths(JNIEnv* env, SkPaint* paint, const jchar text[], int count, jfloatArray widths,
511 jint bidiFlags) {
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700512 NPE_CHECK_RETURN_ZERO(env, paint);
513 NPE_CHECK_RETURN_ZERO(env, text);
514
515 if (count < 0 || !widths) {
516 doThrowAIOOBE(env);
517 return 0;
518 }
519 if (count == 0) {
520 return 0;
521 }
522 size_t widthsLength = env->GetArrayLength(widths);
523 if ((size_t)count > widthsLength) {
524 doThrowAIOOBE(env);
525 return 0;
526 }
527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 AutoJavaFloatArray autoWidths(env, widths, count);
529 jfloat* widthsArray = autoWidths.ptr();
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700530
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700531 TextLayout::getTextRunAdvances(paint, text, 0, count, count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700532 bidiFlags, widthsArray, NULL /* dont need totalAdvance */);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 return count;
535 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700536
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000537 static jint getTextWidths___CIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text,
538 jint index, jint count, jint bidiFlags, jfloatArray widths) {
539 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700541 count = dotextwidths(env, paint, textArray + index, count, widths, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
Elliott Hughes8451b252011-04-07 19:17:57 -0700543 JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 return count;
545 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700546
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000547 static jint getTextWidths__StringIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text,
548 jint start, jint end, jint bidiFlags, jfloatArray widths) {
549 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 const jchar* textArray = env->GetStringChars(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700551 int count = dotextwidths(env, paint, textArray + start, end - start, widths, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 env->ReleaseStringChars(text, textArray);
553 return count;
554 }
Doug Felt0c702b82010-05-14 10:55:42 -0700555
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700556 static int doTextGlyphs(JNIEnv* env, SkPaint* paint, const jchar* text, jint start, jint count,
557 jint contextCount, jint flags, jcharArray glyphs) {
558 NPE_CHECK_RETURN_ZERO(env, paint);
559 NPE_CHECK_RETURN_ZERO(env, text);
560
561 if ((start | count | contextCount) < 0 || contextCount < count || !glyphs) {
562 doThrowAIOOBE(env);
563 return 0;
564 }
565 if (count == 0) {
566 return 0;
567 }
568 size_t glypthsLength = env->GetArrayLength(glyphs);
569 if ((size_t)count > glypthsLength) {
570 doThrowAIOOBE(env);
571 return 0;
572 }
573
574 jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL);
575
576 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
577 text, start, count, contextCount, flags);
578 const jchar* shapedGlyphs = value->getGlyphs();
579 size_t glyphsCount = value->getGlyphsCount();
580 memcpy(glyphsArray, shapedGlyphs, sizeof(jchar) * glyphsCount);
581
582 env->ReleaseCharArrayElements(glyphs, glyphsArray, JNI_ABORT);
583 return glyphsCount;
584 }
585
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000586 static jint getTextGlyphs__StringIIIII_C(JNIEnv* env, jobject clazz, jlong paintHandle,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700587 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
588 jcharArray glyphs) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000589 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700590 const jchar* textArray = env->GetStringChars(text, NULL);
591 int count = doTextGlyphs(env, paint, textArray + contextStart, start - contextStart,
592 end - start, contextEnd - contextStart, flags, glyphs);
593 env->ReleaseStringChars(text, textArray);
594 return count;
595 }
596
Doug Feltf7cb1f72010-07-01 16:20:43 -0700597 static jfloat doTextRunAdvances(JNIEnv *env, SkPaint *paint, const jchar *text,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700598 jint start, jint count, jint contextCount, jint flags,
Doug Felt0c702b82010-05-14 10:55:42 -0700599 jfloatArray advances, jint advancesIndex) {
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700600 NPE_CHECK_RETURN_ZERO(env, paint);
601 NPE_CHECK_RETURN_ZERO(env, text);
602
603 if ((start | count | contextCount | advancesIndex) < 0 || contextCount < count) {
604 doThrowAIOOBE(env);
605 return 0;
606 }
607 if (count == 0) {
608 return 0;
609 }
610 if (advances) {
611 size_t advancesLength = env->GetArrayLength(advances);
612 if ((size_t)count > advancesLength) {
613 doThrowAIOOBE(env);
614 return 0;
615 }
616 }
Doug Felt0c702b82010-05-14 10:55:42 -0700617 jfloat advancesArray[count];
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700618 jfloat totalAdvance = 0;
Doug Felt0c702b82010-05-14 10:55:42 -0700619
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700620 TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700621 advancesArray, &totalAdvance);
Doug Felt0c702b82010-05-14 10:55:42 -0700622
623 if (advances != NULL) {
624 env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
625 }
626 return totalAdvance;
627 }
628
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000629 static jfloat getTextRunAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
Doug Felt0c702b82010-05-14 10:55:42 -0700630 jcharArray text, jint index, jint count, jint contextIndex, jint contextCount,
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700631 jint flags, jfloatArray advances, jint advancesIndex) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000632 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700633 jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700634 jfloat result = doTextRunAdvances(env, paint, textArray + contextIndex,
635 index - contextIndex, count, contextCount, flags, advances, advancesIndex);
Doug Felt0c702b82010-05-14 10:55:42 -0700636 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
637 return result;
638 }
639
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000640 static jfloat getTextRunAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700641 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700642 jfloatArray advances, jint advancesIndex) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000643 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700644 const jchar* textArray = env->GetStringChars(text, NULL);
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700645 jfloat result = doTextRunAdvances(env, paint, textArray + contextStart,
646 start - contextStart, end - start, contextEnd - contextStart, flags,
647 advances, advancesIndex);
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700648 env->ReleaseStringChars(text, textArray);
649 return result;
650 }
651
Doug Felt0c702b82010-05-14 10:55:42 -0700652 static jint doTextRunCursor(JNIEnv *env, SkPaint* paint, const jchar *text, jint start,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700653 jint count, jint flags, jint offset, jint opt) {
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700654 jfloat scalarArray[count];
Fabrice Di Meglio9c418db2011-09-18 12:54:38 -0700655
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700656 TextLayout::getTextRunAdvances(paint, text, start, count, start + count, flags,
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700657 scalarArray, NULL /* dont need totalAdvance */);
Doug Felt0c702b82010-05-14 10:55:42 -0700658
Doug Felt0c702b82010-05-14 10:55:42 -0700659 jint pos = offset - start;
660 switch (opt) {
661 case AFTER:
662 if (pos < count) {
663 pos += 1;
664 }
665 // fall through
666 case AT_OR_AFTER:
667 while (pos < count && scalarArray[pos] == 0) {
668 ++pos;
669 }
670 break;
671 case BEFORE:
672 if (pos > 0) {
673 --pos;
674 }
675 // fall through
676 case AT_OR_BEFORE:
677 while (pos > 0 && scalarArray[pos] == 0) {
678 --pos;
679 }
680 break;
681 case AT:
682 default:
683 if (scalarArray[pos] == 0) {
684 pos = -1;
685 }
686 break;
687 }
688
689 if (pos != -1) {
690 pos += start;
691 }
692
693 return pos;
694 }
695
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000696 static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700697 jint contextStart, jint contextCount, jint flags, jint offset, jint cursorOpt) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000698 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700699 jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700700 jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, flags,
Doug Felt0c702b82010-05-14 10:55:42 -0700701 offset, cursorOpt);
702 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
703 return result;
704 }
705
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000706 static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700707 jint contextStart, jint contextEnd, jint flags, jint offset, jint cursorOpt) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000708 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700709 const jchar* textArray = env->GetStringChars(text, NULL);
710 jint result = doTextRunCursor(env, paint, textArray, contextStart,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700711 contextEnd - contextStart, flags, offset, cursorOpt);
Doug Felt0c702b82010-05-14 10:55:42 -0700712 env->ReleaseStringChars(text, textArray);
713 return result;
714 }
715
Doug Feltf7cb1f72010-07-01 16:20:43 -0700716 static void getTextPath(JNIEnv* env, SkPaint* paint, const jchar* text, jint count,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700717 jint bidiFlags, jfloat x, jfloat y, SkPath *path) {
718 TextLayout::getTextPath(paint, text, count, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800719 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700720
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000721 static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags,
722 jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) {
723 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
724 SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700725 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700726 getTextPath(env, paint, textArray + index, count, bidiFlags, x, y, path);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700727 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
728 }
729
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000730 static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags,
731 jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) {
732 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
733 SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 const jchar* textArray = env->GetStringChars(text, NULL);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700735 getTextPath(env, paint, textArray + start, end - start, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736 env->ReleaseStringChars(text, textArray);
737 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 static void setShadowLayer(JNIEnv* env, jobject jpaint, jfloat radius,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000740 jfloat dx, jfloat dy, jint color) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741 NPE_CHECK_RETURN_VOID(env, jpaint);
Elliott Hughes8451b252011-04-07 19:17:57 -0700742
743 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 if (radius <= 0) {
745 paint->setLooper(NULL);
746 }
747 else {
748 paint->setLooper(new SkBlurDrawLooper(SkFloatToScalar(radius),
749 SkFloatToScalar(dx),
750 SkFloatToScalar(dy),
751 (SkColor)color))->unref();
752 }
753 }
754
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800755 static int breakText(JNIEnv* env, SkPaint& paint, const jchar text[],
Victoria Lease626d3c22013-03-27 15:35:53 -0700756 int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800757 SkPaint::TextBufferDirection tbd) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800758 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
Victoria Lease626d3c22013-03-27 15:35:53 -0700759 text, 0, count, count, bidiFlags);
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800760 if (value == NULL) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800761 return 0;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800762 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763 SkScalar measured;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800764 size_t bytes = paint.breakText(value->getGlyphs(), value->getGlyphsCount() << 1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 SkFloatToScalar(maxWidth), &measured, tbd);
766 SkASSERT((bytes & 1) == 0);
767
768 if (jmeasured && env->GetArrayLength(jmeasured) > 0) {
769 AutoJavaFloatArray autoMeasured(env, jmeasured, 1);
770 jfloat* array = autoMeasured.ptr();
771 array[0] = SkScalarToFloat(measured);
772 }
773 return bytes >> 1;
774 }
775
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000776 static jint breakTextC(JNIEnv* env, jobject jpaint, jcharArray jtext,
777 jint index, jint count, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 NPE_CHECK_RETURN_ZERO(env, jpaint);
779 NPE_CHECK_RETURN_ZERO(env, jtext);
780
781 SkPaint::TextBufferDirection tbd;
782 if (count < 0) {
783 tbd = SkPaint::kBackward_TextBufferDirection;
784 count = -count;
785 }
786 else {
787 tbd = SkPaint::kForward_TextBufferDirection;
788 }
789
790 if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700791 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800792 return 0;
793 }
794
795 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
796 const jchar* text = env->GetCharArrayElements(jtext, NULL);
797 count = breakText(env, *paint, text + index, count, maxWidth,
Victoria Lease626d3c22013-03-27 15:35:53 -0700798 bidiFlags, jmeasuredWidth, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text),
800 JNI_ABORT);
801 return count;
802 }
803
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000804 static jint breakTextS(JNIEnv* env, jobject jpaint, jstring jtext,
805 jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 NPE_CHECK_RETURN_ZERO(env, jpaint);
807 NPE_CHECK_RETURN_ZERO(env, jtext);
808
809 SkPaint::TextBufferDirection tbd = forwards ?
810 SkPaint::kForward_TextBufferDirection :
811 SkPaint::kBackward_TextBufferDirection;
812
813 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
814 int count = env->GetStringLength(jtext);
815 const jchar* text = env->GetStringChars(jtext, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700816 count = breakText(env, *paint, text, count, maxWidth, bidiFlags, jmeasuredWidth, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 env->ReleaseStringChars(jtext, text);
818 return count;
819 }
820
821 static void doTextBounds(JNIEnv* env, const jchar* text, int count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700822 jobject bounds, const SkPaint& paint, jint bidiFlags) {
Romain Guy059e12c2012-11-28 17:35:51 -0800823 SkRect r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 SkIRect ir;
Elliott Hughes8451b252011-04-07 19:17:57 -0700825
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800826 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
Victoria Lease626d3c22013-03-27 15:35:53 -0700827 text, 0, count, count, bidiFlags);
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800828 if (value == NULL) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800829 return;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800830 }
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800831 paint.measureText(value->getGlyphs(), value->getGlyphsCount() << 1, &r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 r.roundOut(&ir);
833 GraphicsJNI::irect_to_jrect(ir, env, bounds);
834 }
835
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000836 static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle,
837 jstring text, jint start, jint end, jint bidiFlags, jobject bounds) {
838 const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 const jchar* textArray = env->GetStringChars(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700840 doTextBounds(env, textArray + start, end - start, bounds, *paint, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 env->ReleaseStringChars(text, textArray);
842 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700843
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000844 static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle,
845 jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) {
846 const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700848 doTextBounds(env, textArray + index, count, bounds, *paint, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
850 JNI_ABORT);
851 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853};
854
855static JNINativeMethod methods[] = {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000856 {"finalizer", "(J)V", (void*) SkPaintGlue::finalizer},
857 {"native_init","()J", (void*) SkPaintGlue::init},
858 {"native_initWithPaint","(J)J", (void*) SkPaintGlue::initWithPaint},
859 {"native_reset","(J)V", (void*) SkPaintGlue::reset},
860 {"native_set","(JJ)V", (void*) SkPaintGlue::assign},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 {"getFlags","()I", (void*) SkPaintGlue::getFlags},
862 {"setFlags","(I)V", (void*) SkPaintGlue::setFlags},
Dianne Hackbornf43fa572011-08-12 18:59:39 -0700863 {"getHinting","()I", (void*) SkPaintGlue::getHinting},
864 {"setHinting","(I)V", (void*) SkPaintGlue::setHinting},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 {"setAntiAlias","(Z)V", (void*) SkPaintGlue::setAntiAlias},
866 {"setSubpixelText","(Z)V", (void*) SkPaintGlue::setSubpixelText},
867 {"setLinearText","(Z)V", (void*) SkPaintGlue::setLinearText},
868 {"setUnderlineText","(Z)V", (void*) SkPaintGlue::setUnderlineText},
869 {"setStrikeThruText","(Z)V", (void*) SkPaintGlue::setStrikeThruText},
870 {"setFakeBoldText","(Z)V", (void*) SkPaintGlue::setFakeBoldText},
871 {"setFilterBitmap","(Z)V", (void*) SkPaintGlue::setFilterBitmap},
872 {"setDither","(Z)V", (void*) SkPaintGlue::setDither},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000873 {"native_getStyle","(J)I", (void*) SkPaintGlue::getStyle},
874 {"native_setStyle","(JI)V", (void*) SkPaintGlue::setStyle},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 {"getColor","()I", (void*) SkPaintGlue::getColor},
876 {"setColor","(I)V", (void*) SkPaintGlue::setColor},
877 {"getAlpha","()I", (void*) SkPaintGlue::getAlpha},
878 {"setAlpha","(I)V", (void*) SkPaintGlue::setAlpha},
879 {"getStrokeWidth","()F", (void*) SkPaintGlue::getStrokeWidth},
880 {"setStrokeWidth","(F)V", (void*) SkPaintGlue::setStrokeWidth},
881 {"getStrokeMiter","()F", (void*) SkPaintGlue::getStrokeMiter},
882 {"setStrokeMiter","(F)V", (void*) SkPaintGlue::setStrokeMiter},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000883 {"native_getStrokeCap","(J)I", (void*) SkPaintGlue::getStrokeCap},
884 {"native_setStrokeCap","(JI)V", (void*) SkPaintGlue::setStrokeCap},
885 {"native_getStrokeJoin","(J)I", (void*) SkPaintGlue::getStrokeJoin},
886 {"native_setStrokeJoin","(JI)V", (void*) SkPaintGlue::setStrokeJoin},
887 {"native_getFillPath","(JJJ)Z", (void*) SkPaintGlue::getFillPath},
888 {"native_setShader","(JJ)J", (void*) SkPaintGlue::setShader},
889 {"native_setColorFilter","(JJ)J", (void*) SkPaintGlue::setColorFilter},
890 {"native_setXfermode","(JJ)J", (void*) SkPaintGlue::setXfermode},
891 {"native_setPathEffect","(JJ)J", (void*) SkPaintGlue::setPathEffect},
892 {"native_setMaskFilter","(JJ)J", (void*) SkPaintGlue::setMaskFilter},
893 {"native_setTypeface","(JJ)J", (void*) SkPaintGlue::setTypeface},
894 {"native_setRasterizer","(JJ)J", (void*) SkPaintGlue::setRasterizer},
895 {"native_getTextAlign","(J)I", (void*) SkPaintGlue::getTextAlign},
896 {"native_setTextAlign","(JI)V", (void*) SkPaintGlue::setTextAlign},
897 {"native_setTextLocale","(JLjava/lang/String;)V", (void*) SkPaintGlue::setTextLocale},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 {"getTextSize","()F", (void*) SkPaintGlue::getTextSize},
899 {"setTextSize","(F)V", (void*) SkPaintGlue::setTextSize},
900 {"getTextScaleX","()F", (void*) SkPaintGlue::getTextScaleX},
901 {"setTextScaleX","(F)V", (void*) SkPaintGlue::setTextScaleX},
902 {"getTextSkewX","()F", (void*) SkPaintGlue::getTextSkewX},
903 {"setTextSkewX","(F)V", (void*) SkPaintGlue::setTextSkewX},
904 {"ascent","()F", (void*) SkPaintGlue::ascent},
905 {"descent","()F", (void*) SkPaintGlue::descent},
906 {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)SkPaintGlue::getFontMetrics},
907 {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)SkPaintGlue::getFontMetricsInt},
Victoria Lease626d3c22013-03-27 15:35:53 -0700908 {"native_measureText","([CIII)F", (void*) SkPaintGlue::measureText_CIII},
909 {"native_measureText","(Ljava/lang/String;I)F", (void*) SkPaintGlue::measureText_StringI},
910 {"native_measureText","(Ljava/lang/String;III)F", (void*) SkPaintGlue::measureText_StringIII},
911 {"native_breakText","([CIIFI[F)I", (void*) SkPaintGlue::breakTextC},
912 {"native_breakText","(Ljava/lang/String;ZFI[F)I", (void*) SkPaintGlue::breakTextS},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000913 {"native_getTextWidths","(J[CIII[F)I", (void*) SkPaintGlue::getTextWidths___CIII_F},
914 {"native_getTextWidths","(JLjava/lang/String;III[F)I", (void*) SkPaintGlue::getTextWidths__StringIII_F},
915 {"native_getTextRunAdvances","(J[CIIIII[FI)F",
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700916 (void*) SkPaintGlue::getTextRunAdvances___CIIIII_FI},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000917 {"native_getTextRunAdvances","(JLjava/lang/String;IIIII[FI)F",
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700918 (void*) SkPaintGlue::getTextRunAdvances__StringIIIII_FI},
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700919
920
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000921 {"native_getTextGlyphs","(JLjava/lang/String;IIIII[C)I",
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700922 (void*) SkPaintGlue::getTextGlyphs__StringIIIII_C},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000923 {"native_getTextRunCursor", "(J[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C},
924 {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I",
Doug Felt0c702b82010-05-14 10:55:42 -0700925 (void*) SkPaintGlue::getTextRunCursor__String},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000926 {"native_getTextPath","(JI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C},
927 {"native_getTextPath","(JILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String},
928 {"nativeGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 (void*) SkPaintGlue::getStringBounds },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000930 {"nativeGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 (void*) SkPaintGlue::getCharArrayBounds },
Romain Guy1e45aae2010-08-13 19:39:53 -0700932 {"nSetShadowLayer", "(FFFI)V", (void*)SkPaintGlue::setShadowLayer}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933};
934
935static jfieldID req_fieldID(jfieldID id) {
936 SkASSERT(id);
937 return id;
938}
939
940int register_android_graphics_Paint(JNIEnv* env) {
941 gFontMetrics_class = env->FindClass("android/graphics/Paint$FontMetrics");
942 SkASSERT(gFontMetrics_class);
943 gFontMetrics_class = (jclass)env->NewGlobalRef(gFontMetrics_class);
944
945 gFontMetrics_fieldID.top = req_fieldID(env->GetFieldID(gFontMetrics_class, "top", "F"));
946 gFontMetrics_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetrics_class, "ascent", "F"));
947 gFontMetrics_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetrics_class, "descent", "F"));
948 gFontMetrics_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetrics_class, "bottom", "F"));
949 gFontMetrics_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetrics_class, "leading", "F"));
950
951 gFontMetricsInt_class = env->FindClass("android/graphics/Paint$FontMetricsInt");
952 SkASSERT(gFontMetricsInt_class);
953 gFontMetricsInt_class = (jclass)env->NewGlobalRef(gFontMetricsInt_class);
954
955 gFontMetricsInt_fieldID.top = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "top", "I"));
956 gFontMetricsInt_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "ascent", "I"));
957 gFontMetricsInt_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "descent", "I"));
958 gFontMetricsInt_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "bottom", "I"));
959 gFontMetricsInt_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "leading", "I"));
960
961 int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Paint", methods,
962 sizeof(methods) / sizeof(methods[0]));
963 return result;
964}
965
966}