blob: 08a88d15974e2a51e892b66f507526b3ac7237a3 [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);
Derek Sollenbergerb644a3b2014-01-17 15:45:10 -0500158 GraphicsJNI::getNativePaint(env, paint)->setFilterLevel(
159 filterBitmap ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
163 NPE_CHECK_RETURN_VOID(env, paint);
164 GraphicsJNI::getNativePaint(env, paint)->setDither(dither);
165 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700166
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000167 static jint getStyle(JNIEnv* env, jobject clazz,jlong objHandle) {
168 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
169 return static_cast<jint>(obj->getStyle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700171
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000172 static void setStyle(JNIEnv* env, jobject clazz, jlong objHandle, jint styleHandle) {
173 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
174 SkPaint::Style style = static_cast<SkPaint::Style>(styleHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 obj->setStyle(style);
176 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 static jint getColor(JNIEnv* env, jobject paint) {
179 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000180 int color;
181 color = GraphicsJNI::getNativePaint(env, paint)->getColor();
182 return static_cast<jint>(color);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 static jint getAlpha(JNIEnv* env, jobject paint) {
186 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000187 int alpha;
188 alpha = GraphicsJNI::getNativePaint(env, paint)->getAlpha();
189 return static_cast<jint>(alpha);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 static void setColor(JNIEnv* env, jobject paint, jint color) {
193 NPE_CHECK_RETURN_VOID(env, paint);
194 GraphicsJNI::getNativePaint(env, paint)->setColor(color);
195 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 static void setAlpha(JNIEnv* env, jobject paint, jint a) {
198 NPE_CHECK_RETURN_VOID(env, paint);
199 GraphicsJNI::getNativePaint(env, paint)->setAlpha(a);
200 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 static jfloat getStrokeWidth(JNIEnv* env, jobject paint) {
203 NPE_CHECK_RETURN_ZERO(env, paint);
204 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeWidth());
205 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 static void setStrokeWidth(JNIEnv* env, jobject paint, jfloat width) {
208 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400209 GraphicsJNI::getNativePaint(env, paint)->setStrokeWidth(width);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 static jfloat getStrokeMiter(JNIEnv* env, jobject paint) {
213 NPE_CHECK_RETURN_ZERO(env, paint);
214 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeMiter());
215 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 static void setStrokeMiter(JNIEnv* env, jobject paint, jfloat miter) {
218 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400219 GraphicsJNI::getNativePaint(env, paint)->setStrokeMiter(miter);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700221
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000222 static jint getStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle) {
223 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
224 return static_cast<jint>(obj->getStrokeCap());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700226
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000227 static void setStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle, jint capHandle) {
228 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
229 SkPaint::Cap cap = static_cast<SkPaint::Cap>(capHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 obj->setStrokeCap(cap);
231 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700232
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000233 static jint getStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle) {
234 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
235 return static_cast<jint>(obj->getStrokeJoin());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700237
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000238 static void setStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle, jint joinHandle) {
239 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
240 SkPaint::Join join = (SkPaint::Join) joinHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 obj->setStrokeJoin(join);
242 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700243
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000244 static jboolean getFillPath(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jlong dstHandle) {
245 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
246 SkPath* src = reinterpret_cast<SkPath*>(srcHandle);
247 SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
248 return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700250
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000251 static jlong setShader(JNIEnv* env, jobject clazz, jlong objHandle, jlong shaderHandle) {
252 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
253 SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
254 return reinterpret_cast<jlong>(obj->setShader(shader));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700256
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000257 static jlong setColorFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong filterHandle) {
258 SkPaint* obj = reinterpret_cast<SkPaint *>(objHandle);
259 SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(filterHandle);
260 return reinterpret_cast<jlong>(obj->setColorFilter(filter));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700262
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000263 static jlong setXfermode(JNIEnv* env, jobject clazz, jlong objHandle, jlong xfermodeHandle) {
264 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
265 SkXfermode* xfermode = reinterpret_cast<SkXfermode*>(xfermodeHandle);
266 return reinterpret_cast<jlong>(obj->setXfermode(xfermode));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700268
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000269 static jlong setPathEffect(JNIEnv* env, jobject clazz, jlong objHandle, jlong effectHandle) {
270 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
271 SkPathEffect* effect = reinterpret_cast<SkPathEffect*>(effectHandle);
272 return reinterpret_cast<jlong>(obj->setPathEffect(effect));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700274
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000275 static jlong setMaskFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong maskfilterHandle) {
276 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
277 SkMaskFilter* maskfilter = reinterpret_cast<SkMaskFilter*>(maskfilterHandle);
278 return reinterpret_cast<jlong>(obj->setMaskFilter(maskfilter));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700280
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000281 static jlong setTypeface(JNIEnv* env, jobject clazz, jlong objHandle, jlong typefaceHandle) {
Raph Leviena0336302013-05-22 16:16:59 -0700282#ifndef USE_MINIKIN
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000283 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
284 SkTypeface* typeface = reinterpret_cast<SkTypeface*>(typefaceHandle);
285 return reinterpret_cast<jlong>(obj->setTypeface(typeface));
Raph Leviena0336302013-05-22 16:16:59 -0700286#else
287 // TODO(raph): not yet implemented
288 return NULL;
289#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700291
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000292 static jlong setRasterizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong rasterizerHandle) {
293 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
294 SkRasterizer* rasterizer = reinterpret_cast<SkRasterizer*>(rasterizerHandle);
295 return reinterpret_cast<jlong>(obj->setRasterizer(rasterizer));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700297
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000298 static jint getTextAlign(JNIEnv* env, jobject clazz, jlong objHandle) {
299 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
300 return static_cast<jint>(obj->getTextAlign());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700302
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000303 static void setTextAlign(JNIEnv* env, jobject clazz, jlong objHandle, jint alignHandle) {
304 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
305 SkPaint::Align align = static_cast<SkPaint::Align>(alignHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 obj->setTextAlign(align);
307 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700308
Billy Hewlettac1cbaf2012-07-18 09:51:45 -0700309 // generate bcp47 identifier for the supplied locale
310 static void toLanguageTag(char* output, size_t outSize,
311 const char* locale) {
312 if (output == NULL || outSize <= 0) {
313 return;
314 }
315 if (locale == NULL) {
316 output[0] = '\0';
317 return;
318 }
319 char canonicalChars[ULOC_FULLNAME_CAPACITY];
320 UErrorCode uErr = U_ZERO_ERROR;
321 uloc_canonicalize(locale, canonicalChars, ULOC_FULLNAME_CAPACITY,
322 &uErr);
323 if (U_SUCCESS(uErr)) {
324 char likelyChars[ULOC_FULLNAME_CAPACITY];
325 uErr = U_ZERO_ERROR;
326 uloc_addLikelySubtags(canonicalChars, likelyChars,
327 ULOC_FULLNAME_CAPACITY, &uErr);
328 if (U_SUCCESS(uErr)) {
329 uErr = U_ZERO_ERROR;
330 uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr);
331 if (U_SUCCESS(uErr)) {
332 return;
333 } else {
334 ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars,
335 u_errorName(uErr));
336 }
337 } else {
338 ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s",
339 canonicalChars, u_errorName(uErr));
340 }
341 } else {
342 ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale,
343 u_errorName(uErr));
344 }
345 // unable to build a proper language identifier
346 output[0] = '\0';
347 }
348
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000349 static void setTextLocale(JNIEnv* env, jobject clazz, jlong objHandle, jstring locale) {
350 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
Billy Hewlettac1cbaf2012-07-18 09:51:45 -0700351 ScopedUtfChars localeChars(env, locale);
352 char langTag[ULOC_FULLNAME_CAPACITY];
353 toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str());
Derek Sollenbergerd7a80772013-05-28 10:44:26 -0400354
355 SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
356 paintOpts.setLanguage(langTag);
357 obj->setPaintOptionsAndroid(paintOpts);
Fabrice Di Meglio517825f2012-04-06 16:53:48 -0700358 }
359
Raph Levien53c00772014-04-14 14:11:02 -0700360 static jboolean isElegantTextHeight(JNIEnv* env, jobject paint) {
361 NPE_CHECK_RETURN_ZERO(env, paint);
362 SkPaint* obj = GraphicsJNI::getNativePaint(env, paint);
363 SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
364 return paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant;
365 }
366
367 static void setElegantTextHeight(JNIEnv* env, jobject paint, jboolean aa) {
368 NPE_CHECK_RETURN_VOID(env, paint);
369 SkPaint* obj = GraphicsJNI::getNativePaint(env, paint);
370 SkPaintOptionsAndroid::FontVariant variant =
371 aa ? SkPaintOptionsAndroid::kElegant_Variant :
372 SkPaintOptionsAndroid::kDefault_Variant;
373 SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
374 paintOpts.setFontVariant(variant);
375 obj->setPaintOptionsAndroid(paintOpts);
376 }
377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 static jfloat getTextSize(JNIEnv* env, jobject paint) {
379 NPE_CHECK_RETURN_ZERO(env, paint);
380 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSize());
381 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 static void setTextSize(JNIEnv* env, jobject paint, jfloat textSize) {
384 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400385 GraphicsJNI::getNativePaint(env, paint)->setTextSize(textSize);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 static jfloat getTextScaleX(JNIEnv* env, jobject paint) {
389 NPE_CHECK_RETURN_ZERO(env, paint);
390 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextScaleX());
391 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 static void setTextScaleX(JNIEnv* env, jobject paint, jfloat scaleX) {
394 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400395 GraphicsJNI::getNativePaint(env, paint)->setTextScaleX(scaleX);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 static jfloat getTextSkewX(JNIEnv* env, jobject paint) {
399 NPE_CHECK_RETURN_ZERO(env, paint);
400 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSkewX());
401 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 static void setTextSkewX(JNIEnv* env, jobject paint, jfloat skewX) {
404 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400405 GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(skewX);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 static jfloat ascent(JNIEnv* env, jobject paint) {
409 NPE_CHECK_RETURN_ZERO(env, paint);
410 SkPaint::FontMetrics metrics;
411 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
412 return SkScalarToFloat(metrics.fAscent);
413 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 static jfloat descent(JNIEnv* env, jobject paint) {
416 NPE_CHECK_RETURN_ZERO(env, paint);
417 SkPaint::FontMetrics metrics;
418 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
419 return SkScalarToFloat(metrics.fDescent);
420 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700421
Raph Levien53c00772014-04-14 14:11:02 -0700422 static SkScalar getMetricsInternal(SkPaint *paint, SkPaint::FontMetrics *metrics) {
423 const int kElegantTop = 2500;
424 const int kElegantBottom = -1000;
425 const int kElegantAscent = 1946;
426 const int kElegantDescent = -512;
427 const int kElegantLeading = 0;
428 SkScalar spacing = paint->getFontMetrics(metrics);
429 SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
430 if (paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant) {
431 SkScalar size = paint->getTextSize();
432 metrics->fTop = -size * kElegantTop / 2048;
433 metrics->fBottom = -size * kElegantBottom / 2048;
434 metrics->fAscent = -size * kElegantAscent / 2048;
435 metrics->fDescent = -size * kElegantDescent / 2048;
436 metrics->fLeading = size * kElegantLeading / 2048;
437 spacing = metrics->fDescent - metrics->fAscent + metrics->fLeading;
438 }
439 return spacing;
440 }
441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
443 NPE_CHECK_RETURN_ZERO(env, paint);
444 SkPaint::FontMetrics metrics;
Raph Levien53c00772014-04-14 14:11:02 -0700445 SkScalar spacing = getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446
447 if (metricsObj) {
448 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
449 env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop));
450 env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent));
451 env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent));
452 env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom));
453 env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading));
454 }
455 return SkScalarToFloat(spacing);
456 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 static jint getFontMetricsInt(JNIEnv* env, jobject paint, jobject metricsObj) {
459 NPE_CHECK_RETURN_ZERO(env, paint);
460 SkPaint::FontMetrics metrics;
Elliott Hughes8451b252011-04-07 19:17:57 -0700461
Raph Levien53c00772014-04-14 14:11:02 -0700462 getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
Leon Scroggins46cb9bd2014-03-06 15:36:39 -0500463 int ascent = SkScalarRoundToInt(metrics.fAscent);
464 int descent = SkScalarRoundToInt(metrics.fDescent);
465 int leading = SkScalarRoundToInt(metrics.fLeading);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466
467 if (metricsObj) {
468 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class));
Leon Scroggins46cb9bd2014-03-06 15:36:39 -0500469 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloorToInt(metrics.fTop));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent);
471 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent);
Leon Scroggins46cb9bd2014-03-06 15:36:39 -0500472 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeilToInt(metrics.fBottom));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading);
474 }
475 return descent - ascent + leading;
476 }
477
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000478 static jfloat measureText_CIII(JNIEnv* env, jobject jpaint, jcharArray text, jint index, jint count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700479 jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 NPE_CHECK_RETURN_ZERO(env, jpaint);
481 NPE_CHECK_RETURN_ZERO(env, text);
482
483 size_t textLength = env->GetArrayLength(text);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 if ((index | count) < 0 || (size_t)(index + count) > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700485 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 return 0;
487 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700488 if (count == 0) {
489 return 0;
490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700492 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700494 jfloat result = 0;
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800495
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700496 TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700497 bidiFlags, NULL /* dont need all advances */, &result);
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800498
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700499 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
500 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700502
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000503 static jfloat measureText_StringIII(JNIEnv* env, jobject jpaint, jstring text, jint start, jint end,
Victoria Lease626d3c22013-03-27 15:35:53 -0700504 jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 NPE_CHECK_RETURN_ZERO(env, jpaint);
506 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700507
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700508 size_t textLength = env->GetStringLength(text);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 int count = end - start;
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700510 if ((start | count) < 0 || (size_t)end > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700511 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 return 0;
513 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700514 if (count == 0) {
515 return 0;
516 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700517
518 const jchar* textArray = env->GetStringChars(text, NULL);
519 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700520 jfloat width = 0;
Elliott Hughes8451b252011-04-07 19:17:57 -0700521
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700522 TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700523 bidiFlags, NULL /* dont need all advances */, &width);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 env->ReleaseStringChars(text, textArray);
526 return width;
527 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700528
Victoria Lease626d3c22013-03-27 15:35:53 -0700529 static jfloat measureText_StringI(JNIEnv* env, jobject jpaint, jstring text, jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 NPE_CHECK_RETURN_ZERO(env, jpaint);
531 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 size_t textLength = env->GetStringLength(text);
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700534 if (textLength == 0) {
535 return 0;
536 }
537
538 const jchar* textArray = env->GetStringChars(text, NULL);
539 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700540 jfloat width = 0;
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700541
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700542 TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700543 bidiFlags, NULL /* dont need all advances */, &width);
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 env->ReleaseStringChars(text, textArray);
546 return width;
547 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700548
Victoria Lease626d3c22013-03-27 15:35:53 -0700549 static int dotextwidths(JNIEnv* env, SkPaint* paint, const jchar text[], int count, jfloatArray widths,
550 jint bidiFlags) {
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700551 NPE_CHECK_RETURN_ZERO(env, paint);
552 NPE_CHECK_RETURN_ZERO(env, text);
553
554 if (count < 0 || !widths) {
555 doThrowAIOOBE(env);
556 return 0;
557 }
558 if (count == 0) {
559 return 0;
560 }
561 size_t widthsLength = env->GetArrayLength(widths);
562 if ((size_t)count > widthsLength) {
563 doThrowAIOOBE(env);
564 return 0;
565 }
566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 AutoJavaFloatArray autoWidths(env, widths, count);
568 jfloat* widthsArray = autoWidths.ptr();
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700569
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700570 TextLayout::getTextRunAdvances(paint, text, 0, count, count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700571 bidiFlags, widthsArray, NULL /* dont need totalAdvance */);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573 return count;
574 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700575
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000576 static jint getTextWidths___CIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text,
577 jint index, jint count, jint bidiFlags, jfloatArray widths) {
578 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700580 count = dotextwidths(env, paint, textArray + index, count, widths, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
Elliott Hughes8451b252011-04-07 19:17:57 -0700582 JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 return count;
584 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700585
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000586 static jint getTextWidths__StringIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text,
587 jint start, jint end, jint bidiFlags, jfloatArray widths) {
588 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 const jchar* textArray = env->GetStringChars(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700590 int count = dotextwidths(env, paint, textArray + start, end - start, widths, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 env->ReleaseStringChars(text, textArray);
592 return count;
593 }
Doug Felt0c702b82010-05-14 10:55:42 -0700594
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700595 static int doTextGlyphs(JNIEnv* env, SkPaint* paint, const jchar* text, jint start, jint count,
596 jint contextCount, jint flags, jcharArray glyphs) {
597 NPE_CHECK_RETURN_ZERO(env, paint);
598 NPE_CHECK_RETURN_ZERO(env, text);
599
600 if ((start | count | contextCount) < 0 || contextCount < count || !glyphs) {
601 doThrowAIOOBE(env);
602 return 0;
603 }
604 if (count == 0) {
605 return 0;
606 }
607 size_t glypthsLength = env->GetArrayLength(glyphs);
608 if ((size_t)count > glypthsLength) {
609 doThrowAIOOBE(env);
610 return 0;
611 }
612
613 jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL);
614
615 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
616 text, start, count, contextCount, flags);
617 const jchar* shapedGlyphs = value->getGlyphs();
618 size_t glyphsCount = value->getGlyphsCount();
619 memcpy(glyphsArray, shapedGlyphs, sizeof(jchar) * glyphsCount);
620
621 env->ReleaseCharArrayElements(glyphs, glyphsArray, JNI_ABORT);
622 return glyphsCount;
623 }
624
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000625 static jint getTextGlyphs__StringIIIII_C(JNIEnv* env, jobject clazz, jlong paintHandle,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700626 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
627 jcharArray glyphs) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000628 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700629 const jchar* textArray = env->GetStringChars(text, NULL);
630 int count = doTextGlyphs(env, paint, textArray + contextStart, start - contextStart,
631 end - start, contextEnd - contextStart, flags, glyphs);
632 env->ReleaseStringChars(text, textArray);
633 return count;
634 }
635
Doug Feltf7cb1f72010-07-01 16:20:43 -0700636 static jfloat doTextRunAdvances(JNIEnv *env, SkPaint *paint, const jchar *text,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700637 jint start, jint count, jint contextCount, jint flags,
Doug Felt0c702b82010-05-14 10:55:42 -0700638 jfloatArray advances, jint advancesIndex) {
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700639 NPE_CHECK_RETURN_ZERO(env, paint);
640 NPE_CHECK_RETURN_ZERO(env, text);
641
642 if ((start | count | contextCount | advancesIndex) < 0 || contextCount < count) {
643 doThrowAIOOBE(env);
644 return 0;
645 }
646 if (count == 0) {
647 return 0;
648 }
649 if (advances) {
650 size_t advancesLength = env->GetArrayLength(advances);
651 if ((size_t)count > advancesLength) {
652 doThrowAIOOBE(env);
653 return 0;
654 }
655 }
Victoria Lease3af2a372014-03-17 16:03:28 -0700656 jfloat* advancesArray = new jfloat[count];
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700657 jfloat totalAdvance = 0;
Doug Felt0c702b82010-05-14 10:55:42 -0700658
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700659 TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700660 advancesArray, &totalAdvance);
Doug Felt0c702b82010-05-14 10:55:42 -0700661
662 if (advances != NULL) {
663 env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
664 }
Victoria Lease3af2a372014-03-17 16:03:28 -0700665 delete [] advancesArray;
Doug Felt0c702b82010-05-14 10:55:42 -0700666 return totalAdvance;
667 }
668
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000669 static jfloat getTextRunAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
Doug Felt0c702b82010-05-14 10:55:42 -0700670 jcharArray text, jint index, jint count, jint contextIndex, jint contextCount,
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700671 jint flags, jfloatArray advances, jint advancesIndex) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000672 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700673 jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700674 jfloat result = doTextRunAdvances(env, paint, textArray + contextIndex,
675 index - contextIndex, count, contextCount, flags, advances, advancesIndex);
Doug Felt0c702b82010-05-14 10:55:42 -0700676 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
677 return result;
678 }
679
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000680 static jfloat getTextRunAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700681 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700682 jfloatArray advances, jint advancesIndex) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000683 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700684 const jchar* textArray = env->GetStringChars(text, NULL);
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700685 jfloat result = doTextRunAdvances(env, paint, textArray + contextStart,
686 start - contextStart, end - start, contextEnd - contextStart, flags,
687 advances, advancesIndex);
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700688 env->ReleaseStringChars(text, textArray);
689 return result;
690 }
691
Doug Felt0c702b82010-05-14 10:55:42 -0700692 static jint doTextRunCursor(JNIEnv *env, SkPaint* paint, const jchar *text, jint start,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700693 jint count, jint flags, jint offset, jint opt) {
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700694 jfloat scalarArray[count];
Fabrice Di Meglio9c418db2011-09-18 12:54:38 -0700695
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700696 TextLayout::getTextRunAdvances(paint, text, start, count, start + count, flags,
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700697 scalarArray, NULL /* dont need totalAdvance */);
Doug Felt0c702b82010-05-14 10:55:42 -0700698
Doug Felt0c702b82010-05-14 10:55:42 -0700699 jint pos = offset - start;
700 switch (opt) {
701 case AFTER:
702 if (pos < count) {
703 pos += 1;
704 }
705 // fall through
706 case AT_OR_AFTER:
707 while (pos < count && scalarArray[pos] == 0) {
708 ++pos;
709 }
710 break;
711 case BEFORE:
712 if (pos > 0) {
713 --pos;
714 }
715 // fall through
716 case AT_OR_BEFORE:
717 while (pos > 0 && scalarArray[pos] == 0) {
718 --pos;
719 }
720 break;
721 case AT:
722 default:
723 if (scalarArray[pos] == 0) {
724 pos = -1;
725 }
726 break;
727 }
728
729 if (pos != -1) {
730 pos += start;
731 }
732
733 return pos;
734 }
735
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000736 static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700737 jint contextStart, jint contextCount, jint flags, jint offset, jint cursorOpt) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000738 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700739 jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700740 jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, flags,
Doug Felt0c702b82010-05-14 10:55:42 -0700741 offset, cursorOpt);
742 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
743 return result;
744 }
745
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000746 static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700747 jint contextStart, jint contextEnd, jint flags, jint offset, jint cursorOpt) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000748 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700749 const jchar* textArray = env->GetStringChars(text, NULL);
750 jint result = doTextRunCursor(env, paint, textArray, contextStart,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700751 contextEnd - contextStart, flags, offset, cursorOpt);
Doug Felt0c702b82010-05-14 10:55:42 -0700752 env->ReleaseStringChars(text, textArray);
753 return result;
754 }
755
Doug Feltf7cb1f72010-07-01 16:20:43 -0700756 static void getTextPath(JNIEnv* env, SkPaint* paint, const jchar* text, jint count,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700757 jint bidiFlags, jfloat x, jfloat y, SkPath *path) {
758 TextLayout::getTextPath(paint, text, count, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800759 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700760
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000761 static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags,
762 jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) {
763 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
764 SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700765 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700766 getTextPath(env, paint, textArray + index, count, bidiFlags, x, y, path);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700767 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
768 }
769
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000770 static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags,
771 jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) {
772 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
773 SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800774 const jchar* textArray = env->GetStringChars(text, NULL);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700775 getTextPath(env, paint, textArray + start, end - start, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 env->ReleaseStringChars(text, textArray);
777 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700778
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 static void setShadowLayer(JNIEnv* env, jobject jpaint, jfloat radius,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000780 jfloat dx, jfloat dy, jint color) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 NPE_CHECK_RETURN_VOID(env, jpaint);
Elliott Hughes8451b252011-04-07 19:17:57 -0700782
783 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 if (radius <= 0) {
785 paint->setLooper(NULL);
786 }
787 else {
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400788 paint->setLooper(new SkBlurDrawLooper(radius, dx, dy, (SkColor)color))->unref();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 }
790 }
791
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800792 static int breakText(JNIEnv* env, SkPaint& paint, const jchar text[],
Victoria Lease626d3c22013-03-27 15:35:53 -0700793 int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 SkPaint::TextBufferDirection tbd) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800795 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
Victoria Lease626d3c22013-03-27 15:35:53 -0700796 text, 0, count, count, bidiFlags);
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800797 if (value == NULL) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800798 return 0;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800799 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800 SkScalar measured;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800801 size_t bytes = paint.breakText(value->getGlyphs(), value->getGlyphsCount() << 1,
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400802 maxWidth, &measured, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800803 SkASSERT((bytes & 1) == 0);
804
805 if (jmeasured && env->GetArrayLength(jmeasured) > 0) {
806 AutoJavaFloatArray autoMeasured(env, jmeasured, 1);
807 jfloat* array = autoMeasured.ptr();
808 array[0] = SkScalarToFloat(measured);
809 }
810 return bytes >> 1;
811 }
812
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000813 static jint breakTextC(JNIEnv* env, jobject jpaint, jcharArray jtext,
814 jint index, jint count, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 NPE_CHECK_RETURN_ZERO(env, jpaint);
816 NPE_CHECK_RETURN_ZERO(env, jtext);
817
818 SkPaint::TextBufferDirection tbd;
819 if (count < 0) {
820 tbd = SkPaint::kBackward_TextBufferDirection;
821 count = -count;
822 }
823 else {
824 tbd = SkPaint::kForward_TextBufferDirection;
825 }
826
827 if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700828 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 return 0;
830 }
831
832 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
833 const jchar* text = env->GetCharArrayElements(jtext, NULL);
834 count = breakText(env, *paint, text + index, count, maxWidth,
Victoria Lease626d3c22013-03-27 15:35:53 -0700835 bidiFlags, jmeasuredWidth, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text),
837 JNI_ABORT);
838 return count;
839 }
840
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000841 static jint breakTextS(JNIEnv* env, jobject jpaint, jstring jtext,
842 jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 NPE_CHECK_RETURN_ZERO(env, jpaint);
844 NPE_CHECK_RETURN_ZERO(env, jtext);
845
846 SkPaint::TextBufferDirection tbd = forwards ?
847 SkPaint::kForward_TextBufferDirection :
848 SkPaint::kBackward_TextBufferDirection;
849
850 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
851 int count = env->GetStringLength(jtext);
852 const jchar* text = env->GetStringChars(jtext, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700853 count = breakText(env, *paint, text, count, maxWidth, bidiFlags, jmeasuredWidth, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 env->ReleaseStringChars(jtext, text);
855 return count;
856 }
857
858 static void doTextBounds(JNIEnv* env, const jchar* text, int count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700859 jobject bounds, const SkPaint& paint, jint bidiFlags) {
Romain Guy059e12c2012-11-28 17:35:51 -0800860 SkRect r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 SkIRect ir;
Elliott Hughes8451b252011-04-07 19:17:57 -0700862
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800863 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
Victoria Lease626d3c22013-03-27 15:35:53 -0700864 text, 0, count, count, bidiFlags);
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800865 if (value == NULL) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800866 return;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800867 }
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800868 paint.measureText(value->getGlyphs(), value->getGlyphsCount() << 1, &r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 r.roundOut(&ir);
870 GraphicsJNI::irect_to_jrect(ir, env, bounds);
871 }
872
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000873 static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle,
874 jstring text, jint start, jint end, jint bidiFlags, jobject bounds) {
875 const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 const jchar* textArray = env->GetStringChars(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700877 doTextBounds(env, textArray + start, end - start, bounds, *paint, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 env->ReleaseStringChars(text, textArray);
879 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700880
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000881 static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle,
882 jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) {
883 const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700885 doTextBounds(env, textArray + index, count, bounds, *paint, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
887 JNI_ABORT);
888 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890};
891
892static JNINativeMethod methods[] = {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000893 {"finalizer", "(J)V", (void*) SkPaintGlue::finalizer},
894 {"native_init","()J", (void*) SkPaintGlue::init},
895 {"native_initWithPaint","(J)J", (void*) SkPaintGlue::initWithPaint},
896 {"native_reset","(J)V", (void*) SkPaintGlue::reset},
897 {"native_set","(JJ)V", (void*) SkPaintGlue::assign},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 {"getFlags","()I", (void*) SkPaintGlue::getFlags},
899 {"setFlags","(I)V", (void*) SkPaintGlue::setFlags},
Dianne Hackbornf43fa572011-08-12 18:59:39 -0700900 {"getHinting","()I", (void*) SkPaintGlue::getHinting},
901 {"setHinting","(I)V", (void*) SkPaintGlue::setHinting},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 {"setAntiAlias","(Z)V", (void*) SkPaintGlue::setAntiAlias},
903 {"setSubpixelText","(Z)V", (void*) SkPaintGlue::setSubpixelText},
904 {"setLinearText","(Z)V", (void*) SkPaintGlue::setLinearText},
905 {"setUnderlineText","(Z)V", (void*) SkPaintGlue::setUnderlineText},
906 {"setStrikeThruText","(Z)V", (void*) SkPaintGlue::setStrikeThruText},
907 {"setFakeBoldText","(Z)V", (void*) SkPaintGlue::setFakeBoldText},
908 {"setFilterBitmap","(Z)V", (void*) SkPaintGlue::setFilterBitmap},
909 {"setDither","(Z)V", (void*) SkPaintGlue::setDither},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000910 {"native_getStyle","(J)I", (void*) SkPaintGlue::getStyle},
911 {"native_setStyle","(JI)V", (void*) SkPaintGlue::setStyle},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 {"getColor","()I", (void*) SkPaintGlue::getColor},
913 {"setColor","(I)V", (void*) SkPaintGlue::setColor},
914 {"getAlpha","()I", (void*) SkPaintGlue::getAlpha},
915 {"setAlpha","(I)V", (void*) SkPaintGlue::setAlpha},
916 {"getStrokeWidth","()F", (void*) SkPaintGlue::getStrokeWidth},
917 {"setStrokeWidth","(F)V", (void*) SkPaintGlue::setStrokeWidth},
918 {"getStrokeMiter","()F", (void*) SkPaintGlue::getStrokeMiter},
919 {"setStrokeMiter","(F)V", (void*) SkPaintGlue::setStrokeMiter},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000920 {"native_getStrokeCap","(J)I", (void*) SkPaintGlue::getStrokeCap},
921 {"native_setStrokeCap","(JI)V", (void*) SkPaintGlue::setStrokeCap},
922 {"native_getStrokeJoin","(J)I", (void*) SkPaintGlue::getStrokeJoin},
923 {"native_setStrokeJoin","(JI)V", (void*) SkPaintGlue::setStrokeJoin},
924 {"native_getFillPath","(JJJ)Z", (void*) SkPaintGlue::getFillPath},
925 {"native_setShader","(JJ)J", (void*) SkPaintGlue::setShader},
926 {"native_setColorFilter","(JJ)J", (void*) SkPaintGlue::setColorFilter},
927 {"native_setXfermode","(JJ)J", (void*) SkPaintGlue::setXfermode},
928 {"native_setPathEffect","(JJ)J", (void*) SkPaintGlue::setPathEffect},
929 {"native_setMaskFilter","(JJ)J", (void*) SkPaintGlue::setMaskFilter},
930 {"native_setTypeface","(JJ)J", (void*) SkPaintGlue::setTypeface},
931 {"native_setRasterizer","(JJ)J", (void*) SkPaintGlue::setRasterizer},
932 {"native_getTextAlign","(J)I", (void*) SkPaintGlue::getTextAlign},
933 {"native_setTextAlign","(JI)V", (void*) SkPaintGlue::setTextAlign},
934 {"native_setTextLocale","(JLjava/lang/String;)V", (void*) SkPaintGlue::setTextLocale},
Raph Levien53c00772014-04-14 14:11:02 -0700935 {"isElegantTextHeight","()Z", (void*) SkPaintGlue::isElegantTextHeight},
936 {"setElegantTextHeight","(Z)V", (void*) SkPaintGlue::setElegantTextHeight},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 {"getTextSize","()F", (void*) SkPaintGlue::getTextSize},
938 {"setTextSize","(F)V", (void*) SkPaintGlue::setTextSize},
939 {"getTextScaleX","()F", (void*) SkPaintGlue::getTextScaleX},
940 {"setTextScaleX","(F)V", (void*) SkPaintGlue::setTextScaleX},
941 {"getTextSkewX","()F", (void*) SkPaintGlue::getTextSkewX},
942 {"setTextSkewX","(F)V", (void*) SkPaintGlue::setTextSkewX},
943 {"ascent","()F", (void*) SkPaintGlue::ascent},
944 {"descent","()F", (void*) SkPaintGlue::descent},
945 {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)SkPaintGlue::getFontMetrics},
946 {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)SkPaintGlue::getFontMetricsInt},
Victoria Lease626d3c22013-03-27 15:35:53 -0700947 {"native_measureText","([CIII)F", (void*) SkPaintGlue::measureText_CIII},
948 {"native_measureText","(Ljava/lang/String;I)F", (void*) SkPaintGlue::measureText_StringI},
949 {"native_measureText","(Ljava/lang/String;III)F", (void*) SkPaintGlue::measureText_StringIII},
950 {"native_breakText","([CIIFI[F)I", (void*) SkPaintGlue::breakTextC},
951 {"native_breakText","(Ljava/lang/String;ZFI[F)I", (void*) SkPaintGlue::breakTextS},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000952 {"native_getTextWidths","(J[CIII[F)I", (void*) SkPaintGlue::getTextWidths___CIII_F},
953 {"native_getTextWidths","(JLjava/lang/String;III[F)I", (void*) SkPaintGlue::getTextWidths__StringIII_F},
954 {"native_getTextRunAdvances","(J[CIIIII[FI)F",
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700955 (void*) SkPaintGlue::getTextRunAdvances___CIIIII_FI},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000956 {"native_getTextRunAdvances","(JLjava/lang/String;IIIII[FI)F",
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700957 (void*) SkPaintGlue::getTextRunAdvances__StringIIIII_FI},
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700958
959
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000960 {"native_getTextGlyphs","(JLjava/lang/String;IIIII[C)I",
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700961 (void*) SkPaintGlue::getTextGlyphs__StringIIIII_C},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000962 {"native_getTextRunCursor", "(J[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C},
963 {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I",
Doug Felt0c702b82010-05-14 10:55:42 -0700964 (void*) SkPaintGlue::getTextRunCursor__String},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000965 {"native_getTextPath","(JI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C},
966 {"native_getTextPath","(JILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String},
967 {"nativeGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 (void*) SkPaintGlue::getStringBounds },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000969 {"nativeGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 (void*) SkPaintGlue::getCharArrayBounds },
Romain Guy1e45aae2010-08-13 19:39:53 -0700971 {"nSetShadowLayer", "(FFFI)V", (void*)SkPaintGlue::setShadowLayer}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800972};
973
974static jfieldID req_fieldID(jfieldID id) {
975 SkASSERT(id);
976 return id;
977}
978
979int register_android_graphics_Paint(JNIEnv* env) {
980 gFontMetrics_class = env->FindClass("android/graphics/Paint$FontMetrics");
981 SkASSERT(gFontMetrics_class);
982 gFontMetrics_class = (jclass)env->NewGlobalRef(gFontMetrics_class);
983
984 gFontMetrics_fieldID.top = req_fieldID(env->GetFieldID(gFontMetrics_class, "top", "F"));
985 gFontMetrics_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetrics_class, "ascent", "F"));
986 gFontMetrics_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetrics_class, "descent", "F"));
987 gFontMetrics_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetrics_class, "bottom", "F"));
988 gFontMetrics_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetrics_class, "leading", "F"));
989
990 gFontMetricsInt_class = env->FindClass("android/graphics/Paint$FontMetricsInt");
991 SkASSERT(gFontMetricsInt_class);
992 gFontMetricsInt_class = (jclass)env->NewGlobalRef(gFontMetricsInt_class);
993
994 gFontMetricsInt_fieldID.top = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "top", "I"));
995 gFontMetricsInt_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "ascent", "I"));
996 gFontMetricsInt_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "descent", "I"));
997 gFontMetricsInt_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "bottom", "I"));
998 gFontMetricsInt_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "leading", "I"));
999
1000 int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Paint", methods,
1001 sizeof(methods) / sizeof(methods[0]));
1002 return result;
1003}
1004
1005}