blob: 22c17dd2c20f9f6d0cce1e38e6c54c4b2258cefe [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"
Derek Sollenbergerc29a0a42014-03-31 13:52:39 -040036#include "utils/Blur.h"
Doug Feltf7cb1f72010-07-01 16:20:43 -070037#include "TextLayout.h"
Doug Felt0c702b82010-05-14 10:55:42 -070038
39// temporary for debugging
Chet Haase5c13d892010-10-08 08:37:55 -070040#include <Caches.h>
Doug Felt0c702b82010-05-14 10:55:42 -070041#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042
43namespace android {
44
45struct JMetricsID {
46 jfieldID top;
47 jfieldID ascent;
48 jfieldID descent;
49 jfieldID bottom;
50 jfieldID leading;
51};
52
53static jclass gFontMetrics_class;
54static JMetricsID gFontMetrics_fieldID;
55
56static jclass gFontMetricsInt_class;
57static JMetricsID gFontMetricsInt_fieldID;
58
Mike Reed3d63e012009-07-27 09:50:31 -040059static void defaultSettingsForAndroid(SkPaint* paint) {
Fabrice Di Meglioc511bee82012-01-05 13:30:54 -080060 // GlyphID encoding is required because we are using Harfbuzz shaping
61 paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Derek Sollenbergerd7a80772013-05-28 10:44:26 -040062
63 SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
64 paintOpts.setUseFontFallbacks(true);
65 paint->setPaintOptionsAndroid(paintOpts);
Mike Reed3d63e012009-07-27 09:50:31 -040066}
67
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068class SkPaintGlue {
69public:
Doug Felt0c702b82010-05-14 10:55:42 -070070 enum MoveOpt {
71 AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT
72 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
Ashok Bhat36bef0b2014-01-20 20:08:01 +000074 static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
75 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 delete obj;
77 }
78
Ashok Bhat36bef0b2014-01-20 20:08:01 +000079 static jlong init(JNIEnv* env, jobject clazz) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 SkPaint* obj = new SkPaint();
Mike Reed3d63e012009-07-27 09:50:31 -040081 defaultSettingsForAndroid(obj);
Ashok Bhat36bef0b2014-01-20 20:08:01 +000082 return reinterpret_cast<jlong>(obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 }
84
Ashok Bhat36bef0b2014-01-20 20:08:01 +000085 static jlong initWithPaint(JNIEnv* env, jobject clazz, jlong paintHandle) {
86 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 SkPaint* obj = new SkPaint(*paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +000088 return reinterpret_cast<jlong>(obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 }
Elliott Hughes8451b252011-04-07 19:17:57 -070090
Ashok Bhat36bef0b2014-01-20 20:08:01 +000091 static void reset(JNIEnv* env, jobject clazz, jlong objHandle) {
92 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 obj->reset();
Mike Reed3d63e012009-07-27 09:50:31 -040094 defaultSettingsForAndroid(obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 }
Elliott Hughes8451b252011-04-07 19:17:57 -070096
Ashok Bhat36bef0b2014-01-20 20:08:01 +000097 static void assign(JNIEnv* env, jobject clazz, jlong dstPaintHandle, jlong srcPaintHandle) {
98 SkPaint* dst = reinterpret_cast<SkPaint*>(dstPaintHandle);
99 const SkPaint* src = reinterpret_cast<SkPaint*>(srcPaintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 *dst = *src;
101 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 static jint getFlags(JNIEnv* env, jobject paint) {
104 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000105 int result;
106 result = GraphicsJNI::getNativePaint(env, paint)->getFlags();
107 return static_cast<jint>(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 static void setFlags(JNIEnv* env, jobject paint, jint flags) {
111 NPE_CHECK_RETURN_VOID(env, paint);
112 GraphicsJNI::getNativePaint(env, paint)->setFlags(flags);
113 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700114
Dianne Hackbornf43fa572011-08-12 18:59:39 -0700115 static jint getHinting(JNIEnv* env, jobject paint) {
116 NPE_CHECK_RETURN_ZERO(env, paint);
117 return GraphicsJNI::getNativePaint(env, paint)->getHinting()
118 == SkPaint::kNo_Hinting ? 0 : 1;
119 }
120
121 static void setHinting(JNIEnv* env, jobject paint, jint mode) {
122 NPE_CHECK_RETURN_VOID(env, paint);
123 GraphicsJNI::getNativePaint(env, paint)->setHinting(
Victoria Lease88705382013-06-14 16:15:41 -0700124 mode == 0 ? SkPaint::kNo_Hinting : SkPaint::kNormal_Hinting);
Dianne Hackbornf43fa572011-08-12 18:59:39 -0700125 }
126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 static void setAntiAlias(JNIEnv* env, jobject paint, jboolean aa) {
128 NPE_CHECK_RETURN_VOID(env, paint);
129 GraphicsJNI::getNativePaint(env, paint)->setAntiAlias(aa);
130 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 static void setLinearText(JNIEnv* env, jobject paint, jboolean linearText) {
133 NPE_CHECK_RETURN_VOID(env, paint);
134 GraphicsJNI::getNativePaint(env, paint)->setLinearText(linearText);
135 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 static void setSubpixelText(JNIEnv* env, jobject paint, jboolean subpixelText) {
138 NPE_CHECK_RETURN_VOID(env, paint);
139 GraphicsJNI::getNativePaint(env, paint)->setSubpixelText(subpixelText);
140 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 static void setUnderlineText(JNIEnv* env, jobject paint, jboolean underlineText) {
143 NPE_CHECK_RETURN_VOID(env, paint);
144 GraphicsJNI::getNativePaint(env, paint)->setUnderlineText(underlineText);
145 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 static void setStrikeThruText(JNIEnv* env, jobject paint, jboolean strikeThruText) {
148 NPE_CHECK_RETURN_VOID(env, paint);
149 GraphicsJNI::getNativePaint(env, paint)->setStrikeThruText(strikeThruText);
150 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static void setFakeBoldText(JNIEnv* env, jobject paint, jboolean fakeBoldText) {
153 NPE_CHECK_RETURN_VOID(env, paint);
154 GraphicsJNI::getNativePaint(env, paint)->setFakeBoldText(fakeBoldText);
155 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
158 NPE_CHECK_RETURN_VOID(env, paint);
Derek Sollenbergerb644a3b2014-01-17 15:45:10 -0500159 GraphicsJNI::getNativePaint(env, paint)->setFilterLevel(
160 filterBitmap ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
164 NPE_CHECK_RETURN_VOID(env, paint);
165 GraphicsJNI::getNativePaint(env, paint)->setDither(dither);
166 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700167
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000168 static jint getStyle(JNIEnv* env, jobject clazz,jlong objHandle) {
169 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
170 return static_cast<jint>(obj->getStyle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700172
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000173 static void setStyle(JNIEnv* env, jobject clazz, jlong objHandle, jint styleHandle) {
174 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
175 SkPaint::Style style = static_cast<SkPaint::Style>(styleHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 obj->setStyle(style);
177 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 static jint getColor(JNIEnv* env, jobject paint) {
180 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000181 int color;
182 color = GraphicsJNI::getNativePaint(env, paint)->getColor();
183 return static_cast<jint>(color);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 static jint getAlpha(JNIEnv* env, jobject paint) {
187 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000188 int alpha;
189 alpha = GraphicsJNI::getNativePaint(env, paint)->getAlpha();
190 return static_cast<jint>(alpha);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 static void setColor(JNIEnv* env, jobject paint, jint color) {
194 NPE_CHECK_RETURN_VOID(env, paint);
195 GraphicsJNI::getNativePaint(env, paint)->setColor(color);
196 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 static void setAlpha(JNIEnv* env, jobject paint, jint a) {
199 NPE_CHECK_RETURN_VOID(env, paint);
200 GraphicsJNI::getNativePaint(env, paint)->setAlpha(a);
201 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 static jfloat getStrokeWidth(JNIEnv* env, jobject paint) {
204 NPE_CHECK_RETURN_ZERO(env, paint);
205 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeWidth());
206 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 static void setStrokeWidth(JNIEnv* env, jobject paint, jfloat width) {
209 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400210 GraphicsJNI::getNativePaint(env, paint)->setStrokeWidth(width);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 static jfloat getStrokeMiter(JNIEnv* env, jobject paint) {
214 NPE_CHECK_RETURN_ZERO(env, paint);
215 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeMiter());
216 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 static void setStrokeMiter(JNIEnv* env, jobject paint, jfloat miter) {
219 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400220 GraphicsJNI::getNativePaint(env, paint)->setStrokeMiter(miter);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700222
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000223 static jint getStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle) {
224 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
225 return static_cast<jint>(obj->getStrokeCap());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700227
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000228 static void setStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle, jint capHandle) {
229 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
230 SkPaint::Cap cap = static_cast<SkPaint::Cap>(capHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 obj->setStrokeCap(cap);
232 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700233
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000234 static jint getStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle) {
235 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
236 return static_cast<jint>(obj->getStrokeJoin());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700238
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000239 static void setStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle, jint joinHandle) {
240 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
241 SkPaint::Join join = (SkPaint::Join) joinHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 obj->setStrokeJoin(join);
243 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700244
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000245 static jboolean getFillPath(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jlong dstHandle) {
246 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
247 SkPath* src = reinterpret_cast<SkPath*>(srcHandle);
248 SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
249 return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700251
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000252 static jlong setShader(JNIEnv* env, jobject clazz, jlong objHandle, jlong shaderHandle) {
253 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
254 SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
255 return reinterpret_cast<jlong>(obj->setShader(shader));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700257
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000258 static jlong setColorFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong filterHandle) {
259 SkPaint* obj = reinterpret_cast<SkPaint *>(objHandle);
260 SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(filterHandle);
261 return reinterpret_cast<jlong>(obj->setColorFilter(filter));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700263
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000264 static jlong setXfermode(JNIEnv* env, jobject clazz, jlong objHandle, jlong xfermodeHandle) {
265 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
266 SkXfermode* xfermode = reinterpret_cast<SkXfermode*>(xfermodeHandle);
267 return reinterpret_cast<jlong>(obj->setXfermode(xfermode));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700269
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000270 static jlong setPathEffect(JNIEnv* env, jobject clazz, jlong objHandle, jlong effectHandle) {
271 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
272 SkPathEffect* effect = reinterpret_cast<SkPathEffect*>(effectHandle);
273 return reinterpret_cast<jlong>(obj->setPathEffect(effect));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700275
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000276 static jlong setMaskFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong maskfilterHandle) {
277 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
278 SkMaskFilter* maskfilter = reinterpret_cast<SkMaskFilter*>(maskfilterHandle);
279 return reinterpret_cast<jlong>(obj->setMaskFilter(maskfilter));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700281
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000282 static jlong setTypeface(JNIEnv* env, jobject clazz, jlong objHandle, jlong typefaceHandle) {
Raph Leviena0336302013-05-22 16:16:59 -0700283#ifndef USE_MINIKIN
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000284 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
285 SkTypeface* typeface = reinterpret_cast<SkTypeface*>(typefaceHandle);
286 return reinterpret_cast<jlong>(obj->setTypeface(typeface));
Raph Leviena0336302013-05-22 16:16:59 -0700287#else
288 // TODO(raph): not yet implemented
289 return NULL;
290#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700292
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000293 static jlong setRasterizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong rasterizerHandle) {
294 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
295 SkRasterizer* rasterizer = reinterpret_cast<SkRasterizer*>(rasterizerHandle);
296 return reinterpret_cast<jlong>(obj->setRasterizer(rasterizer));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700298
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000299 static jint getTextAlign(JNIEnv* env, jobject clazz, jlong objHandle) {
300 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
301 return static_cast<jint>(obj->getTextAlign());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700303
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000304 static void setTextAlign(JNIEnv* env, jobject clazz, jlong objHandle, jint alignHandle) {
305 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
306 SkPaint::Align align = static_cast<SkPaint::Align>(alignHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 obj->setTextAlign(align);
308 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700309
Billy Hewlettac1cbaf2012-07-18 09:51:45 -0700310 // generate bcp47 identifier for the supplied locale
311 static void toLanguageTag(char* output, size_t outSize,
312 const char* locale) {
313 if (output == NULL || outSize <= 0) {
314 return;
315 }
316 if (locale == NULL) {
317 output[0] = '\0';
318 return;
319 }
320 char canonicalChars[ULOC_FULLNAME_CAPACITY];
321 UErrorCode uErr = U_ZERO_ERROR;
322 uloc_canonicalize(locale, canonicalChars, ULOC_FULLNAME_CAPACITY,
323 &uErr);
324 if (U_SUCCESS(uErr)) {
325 char likelyChars[ULOC_FULLNAME_CAPACITY];
326 uErr = U_ZERO_ERROR;
327 uloc_addLikelySubtags(canonicalChars, likelyChars,
328 ULOC_FULLNAME_CAPACITY, &uErr);
329 if (U_SUCCESS(uErr)) {
330 uErr = U_ZERO_ERROR;
331 uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr);
332 if (U_SUCCESS(uErr)) {
333 return;
334 } else {
335 ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars,
336 u_errorName(uErr));
337 }
338 } else {
339 ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s",
340 canonicalChars, u_errorName(uErr));
341 }
342 } else {
343 ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale,
344 u_errorName(uErr));
345 }
346 // unable to build a proper language identifier
347 output[0] = '\0';
348 }
349
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000350 static void setTextLocale(JNIEnv* env, jobject clazz, jlong objHandle, jstring locale) {
351 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
Billy Hewlettac1cbaf2012-07-18 09:51:45 -0700352 ScopedUtfChars localeChars(env, locale);
353 char langTag[ULOC_FULLNAME_CAPACITY];
354 toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str());
Derek Sollenbergerd7a80772013-05-28 10:44:26 -0400355
356 SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
357 paintOpts.setLanguage(langTag);
358 obj->setPaintOptionsAndroid(paintOpts);
Fabrice Di Meglio517825f2012-04-06 16:53:48 -0700359 }
360
Raph Levien53c00772014-04-14 14:11:02 -0700361 static jboolean isElegantTextHeight(JNIEnv* env, jobject paint) {
362 NPE_CHECK_RETURN_ZERO(env, paint);
363 SkPaint* obj = GraphicsJNI::getNativePaint(env, paint);
364 SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
365 return paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant;
366 }
367
368 static void setElegantTextHeight(JNIEnv* env, jobject paint, jboolean aa) {
369 NPE_CHECK_RETURN_VOID(env, paint);
370 SkPaint* obj = GraphicsJNI::getNativePaint(env, paint);
371 SkPaintOptionsAndroid::FontVariant variant =
372 aa ? SkPaintOptionsAndroid::kElegant_Variant :
373 SkPaintOptionsAndroid::kDefault_Variant;
374 SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
375 paintOpts.setFontVariant(variant);
376 obj->setPaintOptionsAndroid(paintOpts);
377 }
378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 static jfloat getTextSize(JNIEnv* env, jobject paint) {
380 NPE_CHECK_RETURN_ZERO(env, paint);
381 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSize());
382 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 static void setTextSize(JNIEnv* env, jobject paint, jfloat textSize) {
385 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400386 GraphicsJNI::getNativePaint(env, paint)->setTextSize(textSize);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 static jfloat getTextScaleX(JNIEnv* env, jobject paint) {
390 NPE_CHECK_RETURN_ZERO(env, paint);
391 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextScaleX());
392 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 static void setTextScaleX(JNIEnv* env, jobject paint, jfloat scaleX) {
395 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400396 GraphicsJNI::getNativePaint(env, paint)->setTextScaleX(scaleX);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 static jfloat getTextSkewX(JNIEnv* env, jobject paint) {
400 NPE_CHECK_RETURN_ZERO(env, paint);
401 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSkewX());
402 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 static void setTextSkewX(JNIEnv* env, jobject paint, jfloat skewX) {
405 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400406 GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(skewX);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 static jfloat ascent(JNIEnv* env, jobject paint) {
410 NPE_CHECK_RETURN_ZERO(env, paint);
411 SkPaint::FontMetrics metrics;
412 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
413 return SkScalarToFloat(metrics.fAscent);
414 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 static jfloat descent(JNIEnv* env, jobject paint) {
417 NPE_CHECK_RETURN_ZERO(env, paint);
418 SkPaint::FontMetrics metrics;
419 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
420 return SkScalarToFloat(metrics.fDescent);
421 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700422
Raph Levien53c00772014-04-14 14:11:02 -0700423 static SkScalar getMetricsInternal(SkPaint *paint, SkPaint::FontMetrics *metrics) {
424 const int kElegantTop = 2500;
425 const int kElegantBottom = -1000;
426 const int kElegantAscent = 1946;
427 const int kElegantDescent = -512;
428 const int kElegantLeading = 0;
429 SkScalar spacing = paint->getFontMetrics(metrics);
430 SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
431 if (paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant) {
432 SkScalar size = paint->getTextSize();
433 metrics->fTop = -size * kElegantTop / 2048;
434 metrics->fBottom = -size * kElegantBottom / 2048;
435 metrics->fAscent = -size * kElegantAscent / 2048;
436 metrics->fDescent = -size * kElegantDescent / 2048;
437 metrics->fLeading = size * kElegantLeading / 2048;
438 spacing = metrics->fDescent - metrics->fAscent + metrics->fLeading;
439 }
440 return spacing;
441 }
442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
444 NPE_CHECK_RETURN_ZERO(env, paint);
445 SkPaint::FontMetrics metrics;
Raph Levien53c00772014-04-14 14:11:02 -0700446 SkScalar spacing = getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447
448 if (metricsObj) {
449 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
450 env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop));
451 env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent));
452 env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent));
453 env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom));
454 env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading));
455 }
456 return SkScalarToFloat(spacing);
457 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 static jint getFontMetricsInt(JNIEnv* env, jobject paint, jobject metricsObj) {
460 NPE_CHECK_RETURN_ZERO(env, paint);
461 SkPaint::FontMetrics metrics;
Elliott Hughes8451b252011-04-07 19:17:57 -0700462
Raph Levien53c00772014-04-14 14:11:02 -0700463 getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
Leon Scroggins46cb9bd2014-03-06 15:36:39 -0500464 int ascent = SkScalarRoundToInt(metrics.fAscent);
465 int descent = SkScalarRoundToInt(metrics.fDescent);
466 int leading = SkScalarRoundToInt(metrics.fLeading);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467
468 if (metricsObj) {
469 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class));
Leon Scroggins46cb9bd2014-03-06 15:36:39 -0500470 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloorToInt(metrics.fTop));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent);
472 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent);
Leon Scroggins46cb9bd2014-03-06 15:36:39 -0500473 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeilToInt(metrics.fBottom));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading);
475 }
476 return descent - ascent + leading;
477 }
478
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000479 static jfloat measureText_CIII(JNIEnv* env, jobject jpaint, jcharArray text, jint index, jint count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700480 jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 NPE_CHECK_RETURN_ZERO(env, jpaint);
482 NPE_CHECK_RETURN_ZERO(env, text);
483
484 size_t textLength = env->GetArrayLength(text);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 if ((index | count) < 0 || (size_t)(index + count) > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700486 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 return 0;
488 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700489 if (count == 0) {
490 return 0;
491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700493 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700495 jfloat result = 0;
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800496
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700497 TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700498 bidiFlags, NULL /* dont need all advances */, &result);
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800499
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700500 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
501 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700503
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000504 static jfloat measureText_StringIII(JNIEnv* env, jobject jpaint, jstring text, jint start, jint end,
Victoria Lease626d3c22013-03-27 15:35:53 -0700505 jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 NPE_CHECK_RETURN_ZERO(env, jpaint);
507 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700508
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700509 size_t textLength = env->GetStringLength(text);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510 int count = end - start;
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700511 if ((start | count) < 0 || (size_t)end > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700512 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 return 0;
514 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700515 if (count == 0) {
516 return 0;
517 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700518
519 const jchar* textArray = env->GetStringChars(text, NULL);
520 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700521 jfloat width = 0;
Elliott Hughes8451b252011-04-07 19:17:57 -0700522
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700523 TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700524 bidiFlags, NULL /* dont need all advances */, &width);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 env->ReleaseStringChars(text, textArray);
527 return width;
528 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700529
Victoria Lease626d3c22013-03-27 15:35:53 -0700530 static jfloat measureText_StringI(JNIEnv* env, jobject jpaint, jstring text, jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 NPE_CHECK_RETURN_ZERO(env, jpaint);
532 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 size_t textLength = env->GetStringLength(text);
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700535 if (textLength == 0) {
536 return 0;
537 }
538
539 const jchar* textArray = env->GetStringChars(text, NULL);
540 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700541 jfloat width = 0;
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700542
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700543 TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700544 bidiFlags, NULL /* dont need all advances */, &width);
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 env->ReleaseStringChars(text, textArray);
547 return width;
548 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700549
Victoria Lease626d3c22013-03-27 15:35:53 -0700550 static int dotextwidths(JNIEnv* env, SkPaint* paint, const jchar text[], int count, jfloatArray widths,
551 jint bidiFlags) {
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700552 NPE_CHECK_RETURN_ZERO(env, paint);
553 NPE_CHECK_RETURN_ZERO(env, text);
554
555 if (count < 0 || !widths) {
556 doThrowAIOOBE(env);
557 return 0;
558 }
559 if (count == 0) {
560 return 0;
561 }
562 size_t widthsLength = env->GetArrayLength(widths);
563 if ((size_t)count > widthsLength) {
564 doThrowAIOOBE(env);
565 return 0;
566 }
567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 AutoJavaFloatArray autoWidths(env, widths, count);
569 jfloat* widthsArray = autoWidths.ptr();
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700570
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700571 TextLayout::getTextRunAdvances(paint, text, 0, count, count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700572 bidiFlags, widthsArray, NULL /* dont need totalAdvance */);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 return count;
575 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700576
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000577 static jint getTextWidths___CIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text,
578 jint index, jint count, jint bidiFlags, jfloatArray widths) {
579 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700581 count = dotextwidths(env, paint, textArray + index, count, widths, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
Elliott Hughes8451b252011-04-07 19:17:57 -0700583 JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 return count;
585 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700586
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000587 static jint getTextWidths__StringIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text,
588 jint start, jint end, jint bidiFlags, jfloatArray widths) {
589 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 const jchar* textArray = env->GetStringChars(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700591 int count = dotextwidths(env, paint, textArray + start, end - start, widths, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 env->ReleaseStringChars(text, textArray);
593 return count;
594 }
Doug Felt0c702b82010-05-14 10:55:42 -0700595
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700596 static int doTextGlyphs(JNIEnv* env, SkPaint* paint, const jchar* text, jint start, jint count,
597 jint contextCount, jint flags, jcharArray glyphs) {
598 NPE_CHECK_RETURN_ZERO(env, paint);
599 NPE_CHECK_RETURN_ZERO(env, text);
600
601 if ((start | count | contextCount) < 0 || contextCount < count || !glyphs) {
602 doThrowAIOOBE(env);
603 return 0;
604 }
605 if (count == 0) {
606 return 0;
607 }
608 size_t glypthsLength = env->GetArrayLength(glyphs);
609 if ((size_t)count > glypthsLength) {
610 doThrowAIOOBE(env);
611 return 0;
612 }
613
614 jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL);
615
616 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
617 text, start, count, contextCount, flags);
618 const jchar* shapedGlyphs = value->getGlyphs();
619 size_t glyphsCount = value->getGlyphsCount();
620 memcpy(glyphsArray, shapedGlyphs, sizeof(jchar) * glyphsCount);
621
622 env->ReleaseCharArrayElements(glyphs, glyphsArray, JNI_ABORT);
623 return glyphsCount;
624 }
625
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000626 static jint getTextGlyphs__StringIIIII_C(JNIEnv* env, jobject clazz, jlong paintHandle,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700627 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
628 jcharArray glyphs) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000629 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700630 const jchar* textArray = env->GetStringChars(text, NULL);
631 int count = doTextGlyphs(env, paint, textArray + contextStart, start - contextStart,
632 end - start, contextEnd - contextStart, flags, glyphs);
633 env->ReleaseStringChars(text, textArray);
634 return count;
635 }
636
Doug Feltf7cb1f72010-07-01 16:20:43 -0700637 static jfloat doTextRunAdvances(JNIEnv *env, SkPaint *paint, const jchar *text,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700638 jint start, jint count, jint contextCount, jint flags,
Doug Felt0c702b82010-05-14 10:55:42 -0700639 jfloatArray advances, jint advancesIndex) {
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700640 NPE_CHECK_RETURN_ZERO(env, paint);
641 NPE_CHECK_RETURN_ZERO(env, text);
642
643 if ((start | count | contextCount | advancesIndex) < 0 || contextCount < count) {
644 doThrowAIOOBE(env);
645 return 0;
646 }
647 if (count == 0) {
648 return 0;
649 }
650 if (advances) {
651 size_t advancesLength = env->GetArrayLength(advances);
652 if ((size_t)count > advancesLength) {
653 doThrowAIOOBE(env);
654 return 0;
655 }
656 }
Victoria Lease3af2a372014-03-17 16:03:28 -0700657 jfloat* advancesArray = new jfloat[count];
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700658 jfloat totalAdvance = 0;
Doug Felt0c702b82010-05-14 10:55:42 -0700659
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700660 TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700661 advancesArray, &totalAdvance);
Doug Felt0c702b82010-05-14 10:55:42 -0700662
663 if (advances != NULL) {
664 env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
665 }
Victoria Lease3af2a372014-03-17 16:03:28 -0700666 delete [] advancesArray;
Doug Felt0c702b82010-05-14 10:55:42 -0700667 return totalAdvance;
668 }
669
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000670 static jfloat getTextRunAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
Doug Felt0c702b82010-05-14 10:55:42 -0700671 jcharArray text, jint index, jint count, jint contextIndex, jint contextCount,
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700672 jint flags, jfloatArray advances, jint advancesIndex) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000673 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700674 jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700675 jfloat result = doTextRunAdvances(env, paint, textArray + contextIndex,
676 index - contextIndex, count, contextCount, flags, advances, advancesIndex);
Doug Felt0c702b82010-05-14 10:55:42 -0700677 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
678 return result;
679 }
680
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000681 static jfloat getTextRunAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700682 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700683 jfloatArray advances, jint advancesIndex) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000684 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700685 const jchar* textArray = env->GetStringChars(text, NULL);
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700686 jfloat result = doTextRunAdvances(env, paint, textArray + contextStart,
687 start - contextStart, end - start, contextEnd - contextStart, flags,
688 advances, advancesIndex);
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700689 env->ReleaseStringChars(text, textArray);
690 return result;
691 }
692
Doug Felt0c702b82010-05-14 10:55:42 -0700693 static jint doTextRunCursor(JNIEnv *env, SkPaint* paint, const jchar *text, jint start,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700694 jint count, jint flags, jint offset, jint opt) {
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700695 jfloat scalarArray[count];
Fabrice Di Meglio9c418db2011-09-18 12:54:38 -0700696
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700697 TextLayout::getTextRunAdvances(paint, text, start, count, start + count, flags,
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700698 scalarArray, NULL /* dont need totalAdvance */);
Doug Felt0c702b82010-05-14 10:55:42 -0700699
Doug Felt0c702b82010-05-14 10:55:42 -0700700 jint pos = offset - start;
701 switch (opt) {
702 case AFTER:
703 if (pos < count) {
704 pos += 1;
705 }
706 // fall through
707 case AT_OR_AFTER:
708 while (pos < count && scalarArray[pos] == 0) {
709 ++pos;
710 }
711 break;
712 case BEFORE:
713 if (pos > 0) {
714 --pos;
715 }
716 // fall through
717 case AT_OR_BEFORE:
718 while (pos > 0 && scalarArray[pos] == 0) {
719 --pos;
720 }
721 break;
722 case AT:
723 default:
724 if (scalarArray[pos] == 0) {
725 pos = -1;
726 }
727 break;
728 }
729
730 if (pos != -1) {
731 pos += start;
732 }
733
734 return pos;
735 }
736
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000737 static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700738 jint contextStart, jint contextCount, jint flags, jint offset, jint cursorOpt) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000739 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700740 jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700741 jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, flags,
Doug Felt0c702b82010-05-14 10:55:42 -0700742 offset, cursorOpt);
743 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
744 return result;
745 }
746
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000747 static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700748 jint contextStart, jint contextEnd, jint flags, jint offset, jint cursorOpt) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000749 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700750 const jchar* textArray = env->GetStringChars(text, NULL);
751 jint result = doTextRunCursor(env, paint, textArray, contextStart,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700752 contextEnd - contextStart, flags, offset, cursorOpt);
Doug Felt0c702b82010-05-14 10:55:42 -0700753 env->ReleaseStringChars(text, textArray);
754 return result;
755 }
756
Doug Feltf7cb1f72010-07-01 16:20:43 -0700757 static void getTextPath(JNIEnv* env, SkPaint* paint, const jchar* text, jint count,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700758 jint bidiFlags, jfloat x, jfloat y, SkPath *path) {
759 TextLayout::getTextPath(paint, text, count, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700761
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000762 static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags,
763 jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) {
764 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
765 SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700766 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700767 getTextPath(env, paint, textArray + index, count, bidiFlags, x, y, path);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700768 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
769 }
770
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000771 static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags,
772 jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) {
773 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
774 SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 const jchar* textArray = env->GetStringChars(text, NULL);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700776 getTextPath(env, paint, textArray + start, end - start, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800777 env->ReleaseStringChars(text, textArray);
778 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700779
Derek Sollenbergerc29a0a42014-03-31 13:52:39 -0400780 static void setShadowLayer(JNIEnv* env, jobject clazz, jlong paintHandle, jfloat radius,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000781 jfloat dx, jfloat dy, jint color) {
Derek Sollenbergerc29a0a42014-03-31 13:52:39 -0400782 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 if (radius <= 0) {
784 paint->setLooper(NULL);
785 }
786 else {
Derek Sollenbergerc29a0a42014-03-31 13:52:39 -0400787 SkScalar sigma = android::uirenderer::Blur::convertRadiusToSigma(radius);
788 paint->setLooper(new SkBlurDrawLooper((SkColor)color, sigma, dx, dy))->unref();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 }
790 }
791
Derek Sollenbergerc29a0a42014-03-31 13:52:39 -0400792 static jboolean hasShadowLayer(JNIEnv* env, jobject clazz, jlong paintHandle) {
793 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
794 return paint->getLooper() && paint->getLooper()->asABlurShadow(NULL);
795 }
796
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800797 static int breakText(JNIEnv* env, SkPaint& paint, const jchar text[],
Victoria Lease626d3c22013-03-27 15:35:53 -0700798 int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 SkPaint::TextBufferDirection tbd) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800800 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
Victoria Lease626d3c22013-03-27 15:35:53 -0700801 text, 0, count, count, bidiFlags);
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800802 if (value == NULL) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800803 return 0;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 SkScalar measured;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800806 size_t bytes = paint.breakText(value->getGlyphs(), value->getGlyphsCount() << 1,
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400807 maxWidth, &measured, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808 SkASSERT((bytes & 1) == 0);
809
810 if (jmeasured && env->GetArrayLength(jmeasured) > 0) {
811 AutoJavaFloatArray autoMeasured(env, jmeasured, 1);
812 jfloat* array = autoMeasured.ptr();
813 array[0] = SkScalarToFloat(measured);
814 }
815 return bytes >> 1;
816 }
817
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000818 static jint breakTextC(JNIEnv* env, jobject jpaint, jcharArray jtext,
819 jint index, jint count, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 NPE_CHECK_RETURN_ZERO(env, jpaint);
821 NPE_CHECK_RETURN_ZERO(env, jtext);
822
823 SkPaint::TextBufferDirection tbd;
824 if (count < 0) {
825 tbd = SkPaint::kBackward_TextBufferDirection;
826 count = -count;
827 }
828 else {
829 tbd = SkPaint::kForward_TextBufferDirection;
830 }
831
832 if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700833 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 return 0;
835 }
836
837 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
838 const jchar* text = env->GetCharArrayElements(jtext, NULL);
839 count = breakText(env, *paint, text + index, count, maxWidth,
Victoria Lease626d3c22013-03-27 15:35:53 -0700840 bidiFlags, jmeasuredWidth, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text),
842 JNI_ABORT);
843 return count;
844 }
845
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000846 static jint breakTextS(JNIEnv* env, jobject jpaint, jstring jtext,
847 jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800848 NPE_CHECK_RETURN_ZERO(env, jpaint);
849 NPE_CHECK_RETURN_ZERO(env, jtext);
850
851 SkPaint::TextBufferDirection tbd = forwards ?
852 SkPaint::kForward_TextBufferDirection :
853 SkPaint::kBackward_TextBufferDirection;
854
855 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
856 int count = env->GetStringLength(jtext);
857 const jchar* text = env->GetStringChars(jtext, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700858 count = breakText(env, *paint, text, count, maxWidth, bidiFlags, jmeasuredWidth, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 env->ReleaseStringChars(jtext, text);
860 return count;
861 }
862
863 static void doTextBounds(JNIEnv* env, const jchar* text, int count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700864 jobject bounds, const SkPaint& paint, jint bidiFlags) {
Romain Guy059e12c2012-11-28 17:35:51 -0800865 SkRect r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 SkIRect ir;
Elliott Hughes8451b252011-04-07 19:17:57 -0700867
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800868 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
Victoria Lease626d3c22013-03-27 15:35:53 -0700869 text, 0, count, count, bidiFlags);
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800870 if (value == NULL) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800871 return;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800872 }
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800873 paint.measureText(value->getGlyphs(), value->getGlyphsCount() << 1, &r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874 r.roundOut(&ir);
875 GraphicsJNI::irect_to_jrect(ir, env, bounds);
876 }
877
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000878 static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle,
879 jstring text, jint start, jint end, jint bidiFlags, jobject bounds) {
880 const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 const jchar* textArray = env->GetStringChars(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700882 doTextBounds(env, textArray + start, end - start, bounds, *paint, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800883 env->ReleaseStringChars(text, textArray);
884 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700885
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000886 static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle,
887 jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) {
888 const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700890 doTextBounds(env, textArray + index, count, bounds, *paint, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
892 JNI_ABORT);
893 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895};
896
897static JNINativeMethod methods[] = {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000898 {"finalizer", "(J)V", (void*) SkPaintGlue::finalizer},
899 {"native_init","()J", (void*) SkPaintGlue::init},
900 {"native_initWithPaint","(J)J", (void*) SkPaintGlue::initWithPaint},
901 {"native_reset","(J)V", (void*) SkPaintGlue::reset},
902 {"native_set","(JJ)V", (void*) SkPaintGlue::assign},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 {"getFlags","()I", (void*) SkPaintGlue::getFlags},
904 {"setFlags","(I)V", (void*) SkPaintGlue::setFlags},
Dianne Hackbornf43fa572011-08-12 18:59:39 -0700905 {"getHinting","()I", (void*) SkPaintGlue::getHinting},
906 {"setHinting","(I)V", (void*) SkPaintGlue::setHinting},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 {"setAntiAlias","(Z)V", (void*) SkPaintGlue::setAntiAlias},
908 {"setSubpixelText","(Z)V", (void*) SkPaintGlue::setSubpixelText},
909 {"setLinearText","(Z)V", (void*) SkPaintGlue::setLinearText},
910 {"setUnderlineText","(Z)V", (void*) SkPaintGlue::setUnderlineText},
911 {"setStrikeThruText","(Z)V", (void*) SkPaintGlue::setStrikeThruText},
912 {"setFakeBoldText","(Z)V", (void*) SkPaintGlue::setFakeBoldText},
913 {"setFilterBitmap","(Z)V", (void*) SkPaintGlue::setFilterBitmap},
914 {"setDither","(Z)V", (void*) SkPaintGlue::setDither},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000915 {"native_getStyle","(J)I", (void*) SkPaintGlue::getStyle},
916 {"native_setStyle","(JI)V", (void*) SkPaintGlue::setStyle},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 {"getColor","()I", (void*) SkPaintGlue::getColor},
918 {"setColor","(I)V", (void*) SkPaintGlue::setColor},
919 {"getAlpha","()I", (void*) SkPaintGlue::getAlpha},
920 {"setAlpha","(I)V", (void*) SkPaintGlue::setAlpha},
921 {"getStrokeWidth","()F", (void*) SkPaintGlue::getStrokeWidth},
922 {"setStrokeWidth","(F)V", (void*) SkPaintGlue::setStrokeWidth},
923 {"getStrokeMiter","()F", (void*) SkPaintGlue::getStrokeMiter},
924 {"setStrokeMiter","(F)V", (void*) SkPaintGlue::setStrokeMiter},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000925 {"native_getStrokeCap","(J)I", (void*) SkPaintGlue::getStrokeCap},
926 {"native_setStrokeCap","(JI)V", (void*) SkPaintGlue::setStrokeCap},
927 {"native_getStrokeJoin","(J)I", (void*) SkPaintGlue::getStrokeJoin},
928 {"native_setStrokeJoin","(JI)V", (void*) SkPaintGlue::setStrokeJoin},
929 {"native_getFillPath","(JJJ)Z", (void*) SkPaintGlue::getFillPath},
930 {"native_setShader","(JJ)J", (void*) SkPaintGlue::setShader},
931 {"native_setColorFilter","(JJ)J", (void*) SkPaintGlue::setColorFilter},
932 {"native_setXfermode","(JJ)J", (void*) SkPaintGlue::setXfermode},
933 {"native_setPathEffect","(JJ)J", (void*) SkPaintGlue::setPathEffect},
934 {"native_setMaskFilter","(JJ)J", (void*) SkPaintGlue::setMaskFilter},
935 {"native_setTypeface","(JJ)J", (void*) SkPaintGlue::setTypeface},
936 {"native_setRasterizer","(JJ)J", (void*) SkPaintGlue::setRasterizer},
937 {"native_getTextAlign","(J)I", (void*) SkPaintGlue::getTextAlign},
938 {"native_setTextAlign","(JI)V", (void*) SkPaintGlue::setTextAlign},
939 {"native_setTextLocale","(JLjava/lang/String;)V", (void*) SkPaintGlue::setTextLocale},
Raph Levien53c00772014-04-14 14:11:02 -0700940 {"isElegantTextHeight","()Z", (void*) SkPaintGlue::isElegantTextHeight},
941 {"setElegantTextHeight","(Z)V", (void*) SkPaintGlue::setElegantTextHeight},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 {"getTextSize","()F", (void*) SkPaintGlue::getTextSize},
943 {"setTextSize","(F)V", (void*) SkPaintGlue::setTextSize},
944 {"getTextScaleX","()F", (void*) SkPaintGlue::getTextScaleX},
945 {"setTextScaleX","(F)V", (void*) SkPaintGlue::setTextScaleX},
946 {"getTextSkewX","()F", (void*) SkPaintGlue::getTextSkewX},
947 {"setTextSkewX","(F)V", (void*) SkPaintGlue::setTextSkewX},
948 {"ascent","()F", (void*) SkPaintGlue::ascent},
949 {"descent","()F", (void*) SkPaintGlue::descent},
950 {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)SkPaintGlue::getFontMetrics},
951 {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)SkPaintGlue::getFontMetricsInt},
Victoria Lease626d3c22013-03-27 15:35:53 -0700952 {"native_measureText","([CIII)F", (void*) SkPaintGlue::measureText_CIII},
953 {"native_measureText","(Ljava/lang/String;I)F", (void*) SkPaintGlue::measureText_StringI},
954 {"native_measureText","(Ljava/lang/String;III)F", (void*) SkPaintGlue::measureText_StringIII},
955 {"native_breakText","([CIIFI[F)I", (void*) SkPaintGlue::breakTextC},
956 {"native_breakText","(Ljava/lang/String;ZFI[F)I", (void*) SkPaintGlue::breakTextS},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000957 {"native_getTextWidths","(J[CIII[F)I", (void*) SkPaintGlue::getTextWidths___CIII_F},
958 {"native_getTextWidths","(JLjava/lang/String;III[F)I", (void*) SkPaintGlue::getTextWidths__StringIII_F},
959 {"native_getTextRunAdvances","(J[CIIIII[FI)F",
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700960 (void*) SkPaintGlue::getTextRunAdvances___CIIIII_FI},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000961 {"native_getTextRunAdvances","(JLjava/lang/String;IIIII[FI)F",
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700962 (void*) SkPaintGlue::getTextRunAdvances__StringIIIII_FI},
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700963
964
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000965 {"native_getTextGlyphs","(JLjava/lang/String;IIIII[C)I",
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700966 (void*) SkPaintGlue::getTextGlyphs__StringIIIII_C},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000967 {"native_getTextRunCursor", "(J[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C},
968 {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I",
Doug Felt0c702b82010-05-14 10:55:42 -0700969 (void*) SkPaintGlue::getTextRunCursor__String},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000970 {"native_getTextPath","(JI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C},
971 {"native_getTextPath","(JILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String},
972 {"nativeGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 (void*) SkPaintGlue::getStringBounds },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000974 {"nativeGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 (void*) SkPaintGlue::getCharArrayBounds },
Derek Sollenbergerc29a0a42014-03-31 13:52:39 -0400976 {"native_setShadowLayer", "(JFFFI)V", (void*)SkPaintGlue::setShadowLayer},
977 {"native_hasShadowLayer", "(J)Z", (void*)SkPaintGlue::hasShadowLayer}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978};
979
980static jfieldID req_fieldID(jfieldID id) {
981 SkASSERT(id);
982 return id;
983}
984
985int register_android_graphics_Paint(JNIEnv* env) {
986 gFontMetrics_class = env->FindClass("android/graphics/Paint$FontMetrics");
987 SkASSERT(gFontMetrics_class);
988 gFontMetrics_class = (jclass)env->NewGlobalRef(gFontMetrics_class);
989
990 gFontMetrics_fieldID.top = req_fieldID(env->GetFieldID(gFontMetrics_class, "top", "F"));
991 gFontMetrics_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetrics_class, "ascent", "F"));
992 gFontMetrics_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetrics_class, "descent", "F"));
993 gFontMetrics_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetrics_class, "bottom", "F"));
994 gFontMetrics_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetrics_class, "leading", "F"));
995
996 gFontMetricsInt_class = env->FindClass("android/graphics/Paint$FontMetricsInt");
997 SkASSERT(gFontMetricsInt_class);
998 gFontMetricsInt_class = (jclass)env->NewGlobalRef(gFontMetricsInt_class);
999
1000 gFontMetricsInt_fieldID.top = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "top", "I"));
1001 gFontMetricsInt_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "ascent", "I"));
1002 gFontMetricsInt_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "descent", "I"));
1003 gFontMetricsInt_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "bottom", "I"));
1004 gFontMetricsInt_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "leading", "I"));
1005
1006 int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Paint", methods,
1007 sizeof(methods) / sizeof(methods[0]));
1008 return result;
1009}
1010
1011}