blob: a4c2dd23a01a23eb6ed025fe47d0f60afcd0a80d [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
Raph Levien1a73f7322014-01-30 16:06:28 -080038#ifdef USE_MINIKIN
39#include <minikin/Layout.h>
40#include "MinikinSkia.h"
41#include "MinikinUtils.h"
42#endif
43
Doug Felt0c702b82010-05-14 10:55:42 -070044// temporary for debugging
Chet Haase5c13d892010-10-08 08:37:55 -070045#include <Caches.h>
Doug Felt0c702b82010-05-14 10:55:42 -070046#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
48namespace android {
49
50struct JMetricsID {
51 jfieldID top;
52 jfieldID ascent;
53 jfieldID descent;
54 jfieldID bottom;
55 jfieldID leading;
56};
57
58static jclass gFontMetrics_class;
59static JMetricsID gFontMetrics_fieldID;
60
61static jclass gFontMetricsInt_class;
62static JMetricsID gFontMetricsInt_fieldID;
63
Mike Reed3d63e012009-07-27 09:50:31 -040064static void defaultSettingsForAndroid(SkPaint* paint) {
Fabrice Di Meglioc511bee82012-01-05 13:30:54 -080065 // GlyphID encoding is required because we are using Harfbuzz shaping
66 paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Derek Sollenbergerd7a80772013-05-28 10:44:26 -040067
68 SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
69 paintOpts.setUseFontFallbacks(true);
70 paint->setPaintOptionsAndroid(paintOpts);
Mike Reed3d63e012009-07-27 09:50:31 -040071}
72
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073class SkPaintGlue {
74public:
Doug Felt0c702b82010-05-14 10:55:42 -070075 enum MoveOpt {
76 AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT
77 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078
Ashok Bhat36bef0b2014-01-20 20:08:01 +000079 static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
80 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 delete obj;
82 }
83
Ashok Bhat36bef0b2014-01-20 20:08:01 +000084 static jlong init(JNIEnv* env, jobject clazz) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 SkPaint* obj = new SkPaint();
Mike Reed3d63e012009-07-27 09:50:31 -040086 defaultSettingsForAndroid(obj);
Ashok Bhat36bef0b2014-01-20 20:08:01 +000087 return reinterpret_cast<jlong>(obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 }
89
Ashok Bhat36bef0b2014-01-20 20:08:01 +000090 static jlong initWithPaint(JNIEnv* env, jobject clazz, jlong paintHandle) {
91 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 SkPaint* obj = new SkPaint(*paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +000093 return reinterpret_cast<jlong>(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 reset(JNIEnv* env, jobject clazz, jlong objHandle) {
97 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 obj->reset();
Mike Reed3d63e012009-07-27 09:50:31 -040099 defaultSettingsForAndroid(obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700101
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000102 static void assign(JNIEnv* env, jobject clazz, jlong dstPaintHandle, jlong srcPaintHandle) {
103 SkPaint* dst = reinterpret_cast<SkPaint*>(dstPaintHandle);
104 const SkPaint* src = reinterpret_cast<SkPaint*>(srcPaintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 *dst = *src;
106 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 static jint getFlags(JNIEnv* env, jobject paint) {
109 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000110 int result;
111 result = GraphicsJNI::getNativePaint(env, paint)->getFlags();
112 return static_cast<jint>(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115 static void setFlags(JNIEnv* env, jobject paint, jint flags) {
116 NPE_CHECK_RETURN_VOID(env, paint);
117 GraphicsJNI::getNativePaint(env, paint)->setFlags(flags);
118 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700119
Dianne Hackbornf43fa572011-08-12 18:59:39 -0700120 static jint getHinting(JNIEnv* env, jobject paint) {
121 NPE_CHECK_RETURN_ZERO(env, paint);
122 return GraphicsJNI::getNativePaint(env, paint)->getHinting()
123 == SkPaint::kNo_Hinting ? 0 : 1;
124 }
125
126 static void setHinting(JNIEnv* env, jobject paint, jint mode) {
127 NPE_CHECK_RETURN_VOID(env, paint);
128 GraphicsJNI::getNativePaint(env, paint)->setHinting(
Victoria Lease88705382013-06-14 16:15:41 -0700129 mode == 0 ? SkPaint::kNo_Hinting : SkPaint::kNormal_Hinting);
Dianne Hackbornf43fa572011-08-12 18:59:39 -0700130 }
131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 static void setAntiAlias(JNIEnv* env, jobject paint, jboolean aa) {
133 NPE_CHECK_RETURN_VOID(env, paint);
134 GraphicsJNI::getNativePaint(env, paint)->setAntiAlias(aa);
135 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 static void setLinearText(JNIEnv* env, jobject paint, jboolean linearText) {
138 NPE_CHECK_RETURN_VOID(env, paint);
139 GraphicsJNI::getNativePaint(env, paint)->setLinearText(linearText);
140 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 static void setSubpixelText(JNIEnv* env, jobject paint, jboolean subpixelText) {
143 NPE_CHECK_RETURN_VOID(env, paint);
144 GraphicsJNI::getNativePaint(env, paint)->setSubpixelText(subpixelText);
145 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 static void setUnderlineText(JNIEnv* env, jobject paint, jboolean underlineText) {
148 NPE_CHECK_RETURN_VOID(env, paint);
149 GraphicsJNI::getNativePaint(env, paint)->setUnderlineText(underlineText);
150 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static void setStrikeThruText(JNIEnv* env, jobject paint, jboolean strikeThruText) {
153 NPE_CHECK_RETURN_VOID(env, paint);
154 GraphicsJNI::getNativePaint(env, paint)->setStrikeThruText(strikeThruText);
155 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 static void setFakeBoldText(JNIEnv* env, jobject paint, jboolean fakeBoldText) {
158 NPE_CHECK_RETURN_VOID(env, paint);
159 GraphicsJNI::getNativePaint(env, paint)->setFakeBoldText(fakeBoldText);
160 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
163 NPE_CHECK_RETURN_VOID(env, paint);
Derek Sollenbergerb644a3b2014-01-17 15:45:10 -0500164 GraphicsJNI::getNativePaint(env, paint)->setFilterLevel(
165 filterBitmap ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
169 NPE_CHECK_RETURN_VOID(env, paint);
170 GraphicsJNI::getNativePaint(env, paint)->setDither(dither);
171 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700172
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000173 static jint getStyle(JNIEnv* env, jobject clazz,jlong objHandle) {
174 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
175 return static_cast<jint>(obj->getStyle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700177
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000178 static void setStyle(JNIEnv* env, jobject clazz, jlong objHandle, jint styleHandle) {
179 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
180 SkPaint::Style style = static_cast<SkPaint::Style>(styleHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 obj->setStyle(style);
182 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 static jint getColor(JNIEnv* env, jobject paint) {
185 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000186 int color;
187 color = GraphicsJNI::getNativePaint(env, paint)->getColor();
188 return static_cast<jint>(color);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 static jint getAlpha(JNIEnv* env, jobject paint) {
192 NPE_CHECK_RETURN_ZERO(env, paint);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000193 int alpha;
194 alpha = GraphicsJNI::getNativePaint(env, paint)->getAlpha();
195 return static_cast<jint>(alpha);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 static void setColor(JNIEnv* env, jobject paint, jint color) {
199 NPE_CHECK_RETURN_VOID(env, paint);
200 GraphicsJNI::getNativePaint(env, paint)->setColor(color);
201 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 static void setAlpha(JNIEnv* env, jobject paint, jint a) {
204 NPE_CHECK_RETURN_VOID(env, paint);
205 GraphicsJNI::getNativePaint(env, paint)->setAlpha(a);
206 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 static jfloat getStrokeWidth(JNIEnv* env, jobject paint) {
209 NPE_CHECK_RETURN_ZERO(env, paint);
210 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeWidth());
211 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 static void setStrokeWidth(JNIEnv* env, jobject paint, jfloat width) {
214 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400215 GraphicsJNI::getNativePaint(env, paint)->setStrokeWidth(width);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 static jfloat getStrokeMiter(JNIEnv* env, jobject paint) {
219 NPE_CHECK_RETURN_ZERO(env, paint);
220 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeMiter());
221 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 static void setStrokeMiter(JNIEnv* env, jobject paint, jfloat miter) {
224 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400225 GraphicsJNI::getNativePaint(env, paint)->setStrokeMiter(miter);
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 jint getStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle) {
229 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
230 return static_cast<jint>(obj->getStrokeCap());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700232
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000233 static void setStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle, jint capHandle) {
234 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
235 SkPaint::Cap cap = static_cast<SkPaint::Cap>(capHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 obj->setStrokeCap(cap);
237 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700238
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000239 static jint getStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle) {
240 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
241 return static_cast<jint>(obj->getStrokeJoin());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700243
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000244 static void setStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle, jint joinHandle) {
245 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
246 SkPaint::Join join = (SkPaint::Join) joinHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 obj->setStrokeJoin(join);
248 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700249
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000250 static jboolean getFillPath(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jlong dstHandle) {
251 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
252 SkPath* src = reinterpret_cast<SkPath*>(srcHandle);
253 SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
254 return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE;
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 setShader(JNIEnv* env, jobject clazz, jlong objHandle, jlong shaderHandle) {
258 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
259 SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
260 return reinterpret_cast<jlong>(obj->setShader(shader));
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 setColorFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong filterHandle) {
264 SkPaint* obj = reinterpret_cast<SkPaint *>(objHandle);
265 SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(filterHandle);
266 return reinterpret_cast<jlong>(obj->setColorFilter(filter));
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 setXfermode(JNIEnv* env, jobject clazz, jlong objHandle, jlong xfermodeHandle) {
270 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
271 SkXfermode* xfermode = reinterpret_cast<SkXfermode*>(xfermodeHandle);
272 return reinterpret_cast<jlong>(obj->setXfermode(xfermode));
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 setPathEffect(JNIEnv* env, jobject clazz, jlong objHandle, jlong effectHandle) {
276 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
277 SkPathEffect* effect = reinterpret_cast<SkPathEffect*>(effectHandle);
278 return reinterpret_cast<jlong>(obj->setPathEffect(effect));
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 setMaskFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong maskfilterHandle) {
282 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
283 SkMaskFilter* maskfilter = reinterpret_cast<SkMaskFilter*>(maskfilterHandle);
284 return reinterpret_cast<jlong>(obj->setMaskFilter(maskfilter));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700286
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000287 static jlong setTypeface(JNIEnv* env, jobject clazz, jlong objHandle, jlong typefaceHandle) {
Raph Leviena0336302013-05-22 16:16:59 -0700288#ifndef USE_MINIKIN
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000289 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
290 SkTypeface* typeface = reinterpret_cast<SkTypeface*>(typefaceHandle);
291 return reinterpret_cast<jlong>(obj->setTypeface(typeface));
Raph Leviena0336302013-05-22 16:16:59 -0700292#else
293 // TODO(raph): not yet implemented
294 return NULL;
295#endif
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 jlong setRasterizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong rasterizerHandle) {
299 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
300 SkRasterizer* rasterizer = reinterpret_cast<SkRasterizer*>(rasterizerHandle);
301 return reinterpret_cast<jlong>(obj->setRasterizer(rasterizer));
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 jint getTextAlign(JNIEnv* env, jobject clazz, jlong objHandle) {
305 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
306 return static_cast<jint>(obj->getTextAlign());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700308
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000309 static void setTextAlign(JNIEnv* env, jobject clazz, jlong objHandle, jint alignHandle) {
310 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
311 SkPaint::Align align = static_cast<SkPaint::Align>(alignHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 obj->setTextAlign(align);
313 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700314
Billy Hewlettac1cbaf2012-07-18 09:51:45 -0700315 // generate bcp47 identifier for the supplied locale
316 static void toLanguageTag(char* output, size_t outSize,
317 const char* locale) {
318 if (output == NULL || outSize <= 0) {
319 return;
320 }
321 if (locale == NULL) {
322 output[0] = '\0';
323 return;
324 }
325 char canonicalChars[ULOC_FULLNAME_CAPACITY];
326 UErrorCode uErr = U_ZERO_ERROR;
327 uloc_canonicalize(locale, canonicalChars, ULOC_FULLNAME_CAPACITY,
328 &uErr);
329 if (U_SUCCESS(uErr)) {
330 char likelyChars[ULOC_FULLNAME_CAPACITY];
331 uErr = U_ZERO_ERROR;
332 uloc_addLikelySubtags(canonicalChars, likelyChars,
333 ULOC_FULLNAME_CAPACITY, &uErr);
334 if (U_SUCCESS(uErr)) {
335 uErr = U_ZERO_ERROR;
336 uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr);
337 if (U_SUCCESS(uErr)) {
338 return;
339 } else {
340 ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars,
341 u_errorName(uErr));
342 }
343 } else {
344 ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s",
345 canonicalChars, u_errorName(uErr));
346 }
347 } else {
348 ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale,
349 u_errorName(uErr));
350 }
351 // unable to build a proper language identifier
352 output[0] = '\0';
353 }
354
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000355 static void setTextLocale(JNIEnv* env, jobject clazz, jlong objHandle, jstring locale) {
356 SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
Billy Hewlettac1cbaf2012-07-18 09:51:45 -0700357 ScopedUtfChars localeChars(env, locale);
358 char langTag[ULOC_FULLNAME_CAPACITY];
359 toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str());
Derek Sollenbergerd7a80772013-05-28 10:44:26 -0400360
361 SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
362 paintOpts.setLanguage(langTag);
363 obj->setPaintOptionsAndroid(paintOpts);
Fabrice Di Meglio517825f2012-04-06 16:53:48 -0700364 }
365
Raph Levien53c00772014-04-14 14:11:02 -0700366 static jboolean isElegantTextHeight(JNIEnv* env, jobject paint) {
367 NPE_CHECK_RETURN_ZERO(env, paint);
368 SkPaint* obj = GraphicsJNI::getNativePaint(env, paint);
369 SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
370 return paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant;
371 }
372
373 static void setElegantTextHeight(JNIEnv* env, jobject paint, jboolean aa) {
374 NPE_CHECK_RETURN_VOID(env, paint);
375 SkPaint* obj = GraphicsJNI::getNativePaint(env, paint);
376 SkPaintOptionsAndroid::FontVariant variant =
377 aa ? SkPaintOptionsAndroid::kElegant_Variant :
378 SkPaintOptionsAndroid::kDefault_Variant;
379 SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
380 paintOpts.setFontVariant(variant);
381 obj->setPaintOptionsAndroid(paintOpts);
382 }
383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 static jfloat getTextSize(JNIEnv* env, jobject paint) {
385 NPE_CHECK_RETURN_ZERO(env, paint);
386 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSize());
387 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 static void setTextSize(JNIEnv* env, jobject paint, jfloat textSize) {
390 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400391 GraphicsJNI::getNativePaint(env, paint)->setTextSize(textSize);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 static jfloat getTextScaleX(JNIEnv* env, jobject paint) {
395 NPE_CHECK_RETURN_ZERO(env, paint);
396 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextScaleX());
397 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 static void setTextScaleX(JNIEnv* env, jobject paint, jfloat scaleX) {
400 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400401 GraphicsJNI::getNativePaint(env, paint)->setTextScaleX(scaleX);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 static jfloat getTextSkewX(JNIEnv* env, jobject paint) {
405 NPE_CHECK_RETURN_ZERO(env, paint);
406 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSkewX());
407 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 static void setTextSkewX(JNIEnv* env, jobject paint, jfloat skewX) {
410 NPE_CHECK_RETURN_VOID(env, paint);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400411 GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(skewX);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 static jfloat ascent(JNIEnv* env, jobject paint) {
415 NPE_CHECK_RETURN_ZERO(env, paint);
416 SkPaint::FontMetrics metrics;
417 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
418 return SkScalarToFloat(metrics.fAscent);
419 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 static jfloat descent(JNIEnv* env, jobject paint) {
422 NPE_CHECK_RETURN_ZERO(env, paint);
423 SkPaint::FontMetrics metrics;
424 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
425 return SkScalarToFloat(metrics.fDescent);
426 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700427
Raph Levien53c00772014-04-14 14:11:02 -0700428 static SkScalar getMetricsInternal(SkPaint *paint, SkPaint::FontMetrics *metrics) {
429 const int kElegantTop = 2500;
430 const int kElegantBottom = -1000;
431 const int kElegantAscent = 1946;
432 const int kElegantDescent = -512;
433 const int kElegantLeading = 0;
434 SkScalar spacing = paint->getFontMetrics(metrics);
435 SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
436 if (paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant) {
437 SkScalar size = paint->getTextSize();
438 metrics->fTop = -size * kElegantTop / 2048;
439 metrics->fBottom = -size * kElegantBottom / 2048;
440 metrics->fAscent = -size * kElegantAscent / 2048;
441 metrics->fDescent = -size * kElegantDescent / 2048;
442 metrics->fLeading = size * kElegantLeading / 2048;
443 spacing = metrics->fDescent - metrics->fAscent + metrics->fLeading;
444 }
445 return spacing;
446 }
447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
449 NPE_CHECK_RETURN_ZERO(env, paint);
450 SkPaint::FontMetrics metrics;
Raph Levien53c00772014-04-14 14:11:02 -0700451 SkScalar spacing = getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452
453 if (metricsObj) {
454 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
455 env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop));
456 env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent));
457 env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent));
458 env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom));
459 env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading));
460 }
461 return SkScalarToFloat(spacing);
462 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 static jint getFontMetricsInt(JNIEnv* env, jobject paint, jobject metricsObj) {
465 NPE_CHECK_RETURN_ZERO(env, paint);
466 SkPaint::FontMetrics metrics;
Elliott Hughes8451b252011-04-07 19:17:57 -0700467
Raph Levien53c00772014-04-14 14:11:02 -0700468 getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
Leon Scroggins46cb9bd2014-03-06 15:36:39 -0500469 int ascent = SkScalarRoundToInt(metrics.fAscent);
470 int descent = SkScalarRoundToInt(metrics.fDescent);
471 int leading = SkScalarRoundToInt(metrics.fLeading);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472
473 if (metricsObj) {
474 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class));
Leon Scroggins46cb9bd2014-03-06 15:36:39 -0500475 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloorToInt(metrics.fTop));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent);
477 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent);
Leon Scroggins46cb9bd2014-03-06 15:36:39 -0500478 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeilToInt(metrics.fBottom));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading);
480 }
481 return descent - ascent + leading;
482 }
483
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000484 static jfloat measureText_CIII(JNIEnv* env, jobject jpaint, jcharArray text, jint index, jint count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700485 jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 NPE_CHECK_RETURN_ZERO(env, jpaint);
487 NPE_CHECK_RETURN_ZERO(env, text);
488
489 size_t textLength = env->GetArrayLength(text);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 if ((index | count) < 0 || (size_t)(index + count) > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700491 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 return 0;
493 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700494 if (count == 0) {
495 return 0;
496 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700498 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700500 jfloat result = 0;
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800501
Raph Levien1a73f7322014-01-30 16:06:28 -0800502#ifdef USE_MINIKIN
503 Layout layout;
504 TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
505 MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
506 layout.doLayout(textArray + index, count);
507 result = layout.getAdvance();
508#else
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700509 TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700510 bidiFlags, NULL /* dont need all advances */, &result);
Raph Levien1a73f7322014-01-30 16:06:28 -0800511#endif
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800512
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700513 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
514 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700516
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000517 static jfloat measureText_StringIII(JNIEnv* env, jobject jpaint, jstring text, jint start, jint end,
Victoria Lease626d3c22013-03-27 15:35:53 -0700518 jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 NPE_CHECK_RETURN_ZERO(env, jpaint);
520 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700521
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700522 size_t textLength = env->GetStringLength(text);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 int count = end - start;
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700524 if ((start | count) < 0 || (size_t)end > textLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700525 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 return 0;
527 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700528 if (count == 0) {
529 return 0;
530 }
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700531
532 const jchar* textArray = env->GetStringChars(text, NULL);
533 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700534 jfloat width = 0;
Elliott Hughes8451b252011-04-07 19:17:57 -0700535
Raph Levien1a73f7322014-01-30 16:06:28 -0800536#ifdef USE_MINIKIN
537 Layout layout;
538 TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
539 MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
540 layout.doLayout(textArray + start, count);
541 width = layout.getAdvance();
542#else
Fabrice Di Meglio51f383d2011-09-13 15:57:58 -0700543 TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700544 bidiFlags, NULL /* dont need all advances */, &width);
Raph Levien1a73f7322014-01-30 16:06:28 -0800545#endif
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 env->ReleaseStringChars(text, textArray);
548 return width;
549 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700550
Victoria Lease626d3c22013-03-27 15:35:53 -0700551 static jfloat measureText_StringI(JNIEnv* env, jobject jpaint, jstring text, jint bidiFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 NPE_CHECK_RETURN_ZERO(env, jpaint);
553 NPE_CHECK_RETURN_ZERO(env, text);
Elliott Hughes8451b252011-04-07 19:17:57 -0700554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 size_t textLength = env->GetStringLength(text);
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700556 if (textLength == 0) {
557 return 0;
558 }
559
560 const jchar* textArray = env->GetStringChars(text, NULL);
561 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700562 jfloat width = 0;
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700563
Raph Levien1a73f7322014-01-30 16:06:28 -0800564#ifdef USE_MINIKIN
565 Layout layout;
566 TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
567 MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
568 layout.doLayout(textArray, textLength);
569 width = layout.getAdvance();
570#else
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700571 TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength,
Victoria Lease626d3c22013-03-27 15:35:53 -0700572 bidiFlags, NULL /* dont need all advances */, &width);
Raph Levien1a73f7322014-01-30 16:06:28 -0800573#endif
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 env->ReleaseStringChars(text, textArray);
576 return width;
577 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700578
Raph Levien1a73f7322014-01-30 16:06:28 -0800579 static int dotextwidths(JNIEnv* env, SkPaint* paint, TypefaceImpl* typeface, const jchar text[], int count,
580 jfloatArray widths, jint bidiFlags) {
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700581 NPE_CHECK_RETURN_ZERO(env, paint);
582 NPE_CHECK_RETURN_ZERO(env, text);
583
584 if (count < 0 || !widths) {
585 doThrowAIOOBE(env);
586 return 0;
587 }
588 if (count == 0) {
589 return 0;
590 }
591 size_t widthsLength = env->GetArrayLength(widths);
592 if ((size_t)count > widthsLength) {
593 doThrowAIOOBE(env);
594 return 0;
595 }
596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 AutoJavaFloatArray autoWidths(env, widths, count);
598 jfloat* widthsArray = autoWidths.ptr();
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700599
Raph Levien1a73f7322014-01-30 16:06:28 -0800600#ifdef USE_MINIKIN
601 Layout layout;
602 MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
603 layout.doLayout(text, count);
604 layout.getAdvances(widthsArray);
605#else
Fabrice Di Meglio8fb50712011-05-13 18:51:21 -0700606 TextLayout::getTextRunAdvances(paint, text, 0, count, count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700607 bidiFlags, widthsArray, NULL /* dont need totalAdvance */);
Raph Levien1a73f7322014-01-30 16:06:28 -0800608#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 return count;
611 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700612
Raph Levien1a73f7322014-01-30 16:06:28 -0800613 static jint getTextWidths___CIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jcharArray text,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000614 jint index, jint count, jint bidiFlags, jfloatArray widths) {
615 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Raph Levien1a73f7322014-01-30 16:06:28 -0800616 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Raph Levien1a73f7322014-01-30 16:06:28 -0800618 count = dotextwidths(env, paint, typeface, textArray + index, count, widths, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
Elliott Hughes8451b252011-04-07 19:17:57 -0700620 JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 return count;
622 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700623
Raph Levien1a73f7322014-01-30 16:06:28 -0800624 static jint getTextWidths__StringIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring text,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000625 jint start, jint end, jint bidiFlags, jfloatArray widths) {
626 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Raph Levien1a73f7322014-01-30 16:06:28 -0800627 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 const jchar* textArray = env->GetStringChars(text, NULL);
Raph Levien1a73f7322014-01-30 16:06:28 -0800629 int count = dotextwidths(env, paint, typeface, textArray + start, end - start, widths, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 env->ReleaseStringChars(text, textArray);
631 return count;
632 }
Doug Felt0c702b82010-05-14 10:55:42 -0700633
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700634 static int doTextGlyphs(JNIEnv* env, SkPaint* paint, const jchar* text, jint start, jint count,
635 jint contextCount, jint flags, jcharArray glyphs) {
636 NPE_CHECK_RETURN_ZERO(env, paint);
637 NPE_CHECK_RETURN_ZERO(env, text);
638
639 if ((start | count | contextCount) < 0 || contextCount < count || !glyphs) {
640 doThrowAIOOBE(env);
641 return 0;
642 }
643 if (count == 0) {
644 return 0;
645 }
646 size_t glypthsLength = env->GetArrayLength(glyphs);
647 if ((size_t)count > glypthsLength) {
648 doThrowAIOOBE(env);
649 return 0;
650 }
651
652 jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL);
653
654 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
655 text, start, count, contextCount, flags);
656 const jchar* shapedGlyphs = value->getGlyphs();
657 size_t glyphsCount = value->getGlyphsCount();
658 memcpy(glyphsArray, shapedGlyphs, sizeof(jchar) * glyphsCount);
659
660 env->ReleaseCharArrayElements(glyphs, glyphsArray, JNI_ABORT);
661 return glyphsCount;
662 }
663
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000664 static jint getTextGlyphs__StringIIIII_C(JNIEnv* env, jobject clazz, jlong paintHandle,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700665 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
666 jcharArray glyphs) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000667 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700668 const jchar* textArray = env->GetStringChars(text, NULL);
669 int count = doTextGlyphs(env, paint, textArray + contextStart, start - contextStart,
670 end - start, contextEnd - contextStart, flags, glyphs);
671 env->ReleaseStringChars(text, textArray);
672 return count;
673 }
674
Raph Levien1a73f7322014-01-30 16:06:28 -0800675 static jfloat doTextRunAdvances(JNIEnv *env, SkPaint *paint, TypefaceImpl* typeface, const jchar *text,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700676 jint start, jint count, jint contextCount, jint flags,
Doug Felt0c702b82010-05-14 10:55:42 -0700677 jfloatArray advances, jint advancesIndex) {
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700678 NPE_CHECK_RETURN_ZERO(env, paint);
679 NPE_CHECK_RETURN_ZERO(env, text);
680
681 if ((start | count | contextCount | advancesIndex) < 0 || contextCount < count) {
682 doThrowAIOOBE(env);
683 return 0;
684 }
685 if (count == 0) {
686 return 0;
687 }
688 if (advances) {
689 size_t advancesLength = env->GetArrayLength(advances);
690 if ((size_t)count > advancesLength) {
691 doThrowAIOOBE(env);
692 return 0;
693 }
694 }
Victoria Lease3af2a372014-03-17 16:03:28 -0700695 jfloat* advancesArray = new jfloat[count];
Fabrice Di Meglio6ab90ed2011-08-08 16:19:38 -0700696 jfloat totalAdvance = 0;
Doug Felt0c702b82010-05-14 10:55:42 -0700697
Raph Levien1a73f7322014-01-30 16:06:28 -0800698#ifdef USE_MINIKIN
699 Layout layout;
700 MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
701 layout.doLayout(text + start, count);
702 layout.getAdvances(advancesArray);
703 totalAdvance = layout.getAdvance();
704#else
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700705 TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700706 advancesArray, &totalAdvance);
Raph Levien1a73f7322014-01-30 16:06:28 -0800707#endif
Doug Felt0c702b82010-05-14 10:55:42 -0700708
709 if (advances != NULL) {
710 env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
711 }
Victoria Lease3af2a372014-03-17 16:03:28 -0700712 delete [] advancesArray;
Doug Felt0c702b82010-05-14 10:55:42 -0700713 return totalAdvance;
714 }
715
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000716 static jfloat getTextRunAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
Raph Levien1a73f7322014-01-30 16:06:28 -0800717 jlong typefaceHandle,
Doug Felt0c702b82010-05-14 10:55:42 -0700718 jcharArray text, jint index, jint count, jint contextIndex, jint contextCount,
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700719 jint flags, jfloatArray advances, jint advancesIndex) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000720 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Raph Levien1a73f7322014-01-30 16:06:28 -0800721 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700722 jchar* textArray = env->GetCharArrayElements(text, NULL);
Raph Levien1a73f7322014-01-30 16:06:28 -0800723 jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextIndex,
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700724 index - contextIndex, count, contextCount, flags, advances, advancesIndex);
Doug Felt0c702b82010-05-14 10:55:42 -0700725 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
726 return result;
727 }
728
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000729 static jfloat getTextRunAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
Raph Levien1a73f7322014-01-30 16:06:28 -0800730 jlong typefaceHandle,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700731 jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700732 jfloatArray advances, jint advancesIndex) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000733 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Raph Levien1a73f7322014-01-30 16:06:28 -0800734 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700735 const jchar* textArray = env->GetStringChars(text, NULL);
Raph Levien1a73f7322014-01-30 16:06:28 -0800736 jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextStart,
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -0700737 start - contextStart, end - start, contextEnd - contextStart, flags,
738 advances, advancesIndex);
Fabrice Di Meglioeee49c62011-03-24 17:21:23 -0700739 env->ReleaseStringChars(text, textArray);
740 return result;
741 }
742
Doug Felt0c702b82010-05-14 10:55:42 -0700743 static jint doTextRunCursor(JNIEnv *env, SkPaint* paint, const jchar *text, jint start,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700744 jint count, jint flags, jint offset, jint opt) {
Fabrice Di Meglio4f810c82011-04-19 14:53:58 -0700745 jfloat scalarArray[count];
Fabrice Di Meglio9c418db2011-09-18 12:54:38 -0700746
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700747 TextLayout::getTextRunAdvances(paint, text, start, count, start + count, flags,
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700748 scalarArray, NULL /* dont need totalAdvance */);
Doug Felt0c702b82010-05-14 10:55:42 -0700749
Doug Felt0c702b82010-05-14 10:55:42 -0700750 jint pos = offset - start;
751 switch (opt) {
752 case AFTER:
753 if (pos < count) {
754 pos += 1;
755 }
756 // fall through
757 case AT_OR_AFTER:
758 while (pos < count && scalarArray[pos] == 0) {
759 ++pos;
760 }
761 break;
762 case BEFORE:
763 if (pos > 0) {
764 --pos;
765 }
766 // fall through
767 case AT_OR_BEFORE:
768 while (pos > 0 && scalarArray[pos] == 0) {
769 --pos;
770 }
771 break;
772 case AT:
773 default:
774 if (scalarArray[pos] == 0) {
775 pos = -1;
776 }
777 break;
778 }
779
780 if (pos != -1) {
781 pos += start;
782 }
783
784 return pos;
785 }
786
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000787 static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700788 jint contextStart, jint contextCount, jint flags, jint offset, jint cursorOpt) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000789 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700790 jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700791 jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, flags,
Doug Felt0c702b82010-05-14 10:55:42 -0700792 offset, cursorOpt);
793 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
794 return result;
795 }
796
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000797 static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700798 jint contextStart, jint contextEnd, jint flags, jint offset, jint cursorOpt) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000799 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
Doug Felt0c702b82010-05-14 10:55:42 -0700800 const jchar* textArray = env->GetStringChars(text, NULL);
801 jint result = doTextRunCursor(env, paint, textArray, contextStart,
Fabrice Di Meglioa4bf8112013-03-15 11:22:29 -0700802 contextEnd - contextStart, flags, offset, cursorOpt);
Doug Felt0c702b82010-05-14 10:55:42 -0700803 env->ReleaseStringChars(text, textArray);
804 return result;
805 }
806
Doug Feltf7cb1f72010-07-01 16:20:43 -0700807 static void getTextPath(JNIEnv* env, SkPaint* paint, const jchar* text, jint count,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700808 jint bidiFlags, jfloat x, jfloat y, SkPath *path) {
809 TextLayout::getTextPath(paint, text, count, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700811
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000812 static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags,
813 jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) {
814 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
815 SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700816 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700817 getTextPath(env, paint, textArray + index, count, bidiFlags, x, y, path);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700818 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
819 }
820
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000821 static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags,
822 jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) {
823 SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
824 SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 const jchar* textArray = env->GetStringChars(text, NULL);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -0700826 getTextPath(env, paint, textArray + start, end - start, bidiFlags, x, y, path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 env->ReleaseStringChars(text, textArray);
828 }
Doug Feltf7cb1f72010-07-01 16:20:43 -0700829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 static void setShadowLayer(JNIEnv* env, jobject jpaint, jfloat radius,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000831 jfloat dx, jfloat dy, jint color) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 NPE_CHECK_RETURN_VOID(env, jpaint);
Elliott Hughes8451b252011-04-07 19:17:57 -0700833
834 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800835 if (radius <= 0) {
836 paint->setLooper(NULL);
837 }
838 else {
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400839 paint->setLooper(new SkBlurDrawLooper(radius, dx, dy, (SkColor)color))->unref();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 }
841 }
842
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800843 static int breakText(JNIEnv* env, SkPaint& paint, const jchar text[],
Victoria Lease626d3c22013-03-27 15:35:53 -0700844 int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 SkPaint::TextBufferDirection tbd) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800846 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
Victoria Lease626d3c22013-03-27 15:35:53 -0700847 text, 0, count, count, bidiFlags);
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800848 if (value == NULL) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800849 return 0;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800851 SkScalar measured;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800852 size_t bytes = paint.breakText(value->getGlyphs(), value->getGlyphsCount() << 1,
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400853 maxWidth, &measured, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 SkASSERT((bytes & 1) == 0);
855
856 if (jmeasured && env->GetArrayLength(jmeasured) > 0) {
857 AutoJavaFloatArray autoMeasured(env, jmeasured, 1);
858 jfloat* array = autoMeasured.ptr();
859 array[0] = SkScalarToFloat(measured);
860 }
861 return bytes >> 1;
862 }
863
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000864 static jint breakTextC(JNIEnv* env, jobject jpaint, jcharArray jtext,
865 jint index, jint count, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 NPE_CHECK_RETURN_ZERO(env, jpaint);
867 NPE_CHECK_RETURN_ZERO(env, jtext);
868
869 SkPaint::TextBufferDirection tbd;
870 if (count < 0) {
871 tbd = SkPaint::kBackward_TextBufferDirection;
872 count = -count;
873 }
874 else {
875 tbd = SkPaint::kForward_TextBufferDirection;
876 }
877
878 if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700879 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 return 0;
881 }
882
883 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
884 const jchar* text = env->GetCharArrayElements(jtext, NULL);
885 count = breakText(env, *paint, text + index, count, maxWidth,
Victoria Lease626d3c22013-03-27 15:35:53 -0700886 bidiFlags, jmeasuredWidth, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text),
888 JNI_ABORT);
889 return count;
890 }
891
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000892 static jint breakTextS(JNIEnv* env, jobject jpaint, jstring jtext,
893 jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800894 NPE_CHECK_RETURN_ZERO(env, jpaint);
895 NPE_CHECK_RETURN_ZERO(env, jtext);
896
897 SkPaint::TextBufferDirection tbd = forwards ?
898 SkPaint::kForward_TextBufferDirection :
899 SkPaint::kBackward_TextBufferDirection;
900
901 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
902 int count = env->GetStringLength(jtext);
903 const jchar* text = env->GetStringChars(jtext, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700904 count = breakText(env, *paint, text, count, maxWidth, bidiFlags, jmeasuredWidth, tbd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800905 env->ReleaseStringChars(jtext, text);
906 return count;
907 }
908
909 static void doTextBounds(JNIEnv* env, const jchar* text, int count,
Victoria Lease626d3c22013-03-27 15:35:53 -0700910 jobject bounds, const SkPaint& paint, jint bidiFlags) {
Romain Guy059e12c2012-11-28 17:35:51 -0800911 SkRect r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 SkIRect ir;
Elliott Hughes8451b252011-04-07 19:17:57 -0700913
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800914 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
Victoria Lease626d3c22013-03-27 15:35:53 -0700915 text, 0, count, count, bidiFlags);
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800916 if (value == NULL) {
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800917 return;
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800918 }
Fabrice Di Megliobd901de2012-01-20 17:41:55 -0800919 paint.measureText(value->getGlyphs(), value->getGlyphsCount() << 1, &r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 r.roundOut(&ir);
921 GraphicsJNI::irect_to_jrect(ir, env, bounds);
922 }
923
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000924 static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle,
925 jstring text, jint start, jint end, jint bidiFlags, jobject bounds) {
926 const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 const jchar* textArray = env->GetStringChars(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700928 doTextBounds(env, textArray + start, end - start, bounds, *paint, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 env->ReleaseStringChars(text, textArray);
930 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700931
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000932 static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle,
933 jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) {
934 const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 const jchar* textArray = env->GetCharArrayElements(text, NULL);
Victoria Lease626d3c22013-03-27 15:35:53 -0700936 doTextBounds(env, textArray + index, count, bounds, *paint, bidiFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
938 JNI_ABORT);
939 }
Elliott Hughes8451b252011-04-07 19:17:57 -0700940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941};
942
943static JNINativeMethod methods[] = {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000944 {"finalizer", "(J)V", (void*) SkPaintGlue::finalizer},
945 {"native_init","()J", (void*) SkPaintGlue::init},
946 {"native_initWithPaint","(J)J", (void*) SkPaintGlue::initWithPaint},
947 {"native_reset","(J)V", (void*) SkPaintGlue::reset},
948 {"native_set","(JJ)V", (void*) SkPaintGlue::assign},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 {"getFlags","()I", (void*) SkPaintGlue::getFlags},
950 {"setFlags","(I)V", (void*) SkPaintGlue::setFlags},
Dianne Hackbornf43fa572011-08-12 18:59:39 -0700951 {"getHinting","()I", (void*) SkPaintGlue::getHinting},
952 {"setHinting","(I)V", (void*) SkPaintGlue::setHinting},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 {"setAntiAlias","(Z)V", (void*) SkPaintGlue::setAntiAlias},
954 {"setSubpixelText","(Z)V", (void*) SkPaintGlue::setSubpixelText},
955 {"setLinearText","(Z)V", (void*) SkPaintGlue::setLinearText},
956 {"setUnderlineText","(Z)V", (void*) SkPaintGlue::setUnderlineText},
957 {"setStrikeThruText","(Z)V", (void*) SkPaintGlue::setStrikeThruText},
958 {"setFakeBoldText","(Z)V", (void*) SkPaintGlue::setFakeBoldText},
959 {"setFilterBitmap","(Z)V", (void*) SkPaintGlue::setFilterBitmap},
960 {"setDither","(Z)V", (void*) SkPaintGlue::setDither},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000961 {"native_getStyle","(J)I", (void*) SkPaintGlue::getStyle},
962 {"native_setStyle","(JI)V", (void*) SkPaintGlue::setStyle},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 {"getColor","()I", (void*) SkPaintGlue::getColor},
964 {"setColor","(I)V", (void*) SkPaintGlue::setColor},
965 {"getAlpha","()I", (void*) SkPaintGlue::getAlpha},
966 {"setAlpha","(I)V", (void*) SkPaintGlue::setAlpha},
967 {"getStrokeWidth","()F", (void*) SkPaintGlue::getStrokeWidth},
968 {"setStrokeWidth","(F)V", (void*) SkPaintGlue::setStrokeWidth},
969 {"getStrokeMiter","()F", (void*) SkPaintGlue::getStrokeMiter},
970 {"setStrokeMiter","(F)V", (void*) SkPaintGlue::setStrokeMiter},
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000971 {"native_getStrokeCap","(J)I", (void*) SkPaintGlue::getStrokeCap},
972 {"native_setStrokeCap","(JI)V", (void*) SkPaintGlue::setStrokeCap},
973 {"native_getStrokeJoin","(J)I", (void*) SkPaintGlue::getStrokeJoin},
974 {"native_setStrokeJoin","(JI)V", (void*) SkPaintGlue::setStrokeJoin},
975 {"native_getFillPath","(JJJ)Z", (void*) SkPaintGlue::getFillPath},
976 {"native_setShader","(JJ)J", (void*) SkPaintGlue::setShader},
977 {"native_setColorFilter","(JJ)J", (void*) SkPaintGlue::setColorFilter},
978 {"native_setXfermode","(JJ)J", (void*) SkPaintGlue::setXfermode},
979 {"native_setPathEffect","(JJ)J", (void*) SkPaintGlue::setPathEffect},
980 {"native_setMaskFilter","(JJ)J", (void*) SkPaintGlue::setMaskFilter},
981 {"native_setTypeface","(JJ)J", (void*) SkPaintGlue::setTypeface},
982 {"native_setRasterizer","(JJ)J", (void*) SkPaintGlue::setRasterizer},
983 {"native_getTextAlign","(J)I", (void*) SkPaintGlue::getTextAlign},
984 {"native_setTextAlign","(JI)V", (void*) SkPaintGlue::setTextAlign},
985 {"native_setTextLocale","(JLjava/lang/String;)V", (void*) SkPaintGlue::setTextLocale},
Raph Levien53c00772014-04-14 14:11:02 -0700986 {"isElegantTextHeight","()Z", (void*) SkPaintGlue::isElegantTextHeight},
987 {"setElegantTextHeight","(Z)V", (void*) SkPaintGlue::setElegantTextHeight},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 {"getTextSize","()F", (void*) SkPaintGlue::getTextSize},
989 {"setTextSize","(F)V", (void*) SkPaintGlue::setTextSize},
990 {"getTextScaleX","()F", (void*) SkPaintGlue::getTextScaleX},
991 {"setTextScaleX","(F)V", (void*) SkPaintGlue::setTextScaleX},
992 {"getTextSkewX","()F", (void*) SkPaintGlue::getTextSkewX},
993 {"setTextSkewX","(F)V", (void*) SkPaintGlue::setTextSkewX},
994 {"ascent","()F", (void*) SkPaintGlue::ascent},
995 {"descent","()F", (void*) SkPaintGlue::descent},
996 {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)SkPaintGlue::getFontMetrics},
997 {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)SkPaintGlue::getFontMetricsInt},
Victoria Lease626d3c22013-03-27 15:35:53 -0700998 {"native_measureText","([CIII)F", (void*) SkPaintGlue::measureText_CIII},
999 {"native_measureText","(Ljava/lang/String;I)F", (void*) SkPaintGlue::measureText_StringI},
1000 {"native_measureText","(Ljava/lang/String;III)F", (void*) SkPaintGlue::measureText_StringIII},
1001 {"native_breakText","([CIIFI[F)I", (void*) SkPaintGlue::breakTextC},
1002 {"native_breakText","(Ljava/lang/String;ZFI[F)I", (void*) SkPaintGlue::breakTextS},
Raph Levien1a73f7322014-01-30 16:06:28 -08001003 {"native_getTextWidths","(JJ[CIII[F)I", (void*) SkPaintGlue::getTextWidths___CIII_F},
1004 {"native_getTextWidths","(JJLjava/lang/String;III[F)I", (void*) SkPaintGlue::getTextWidths__StringIII_F},
1005 {"native_getTextRunAdvances","(JJ[CIIIII[FI)F",
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -07001006 (void*) SkPaintGlue::getTextRunAdvances___CIIIII_FI},
Raph Levien1a73f7322014-01-30 16:06:28 -08001007 {"native_getTextRunAdvances","(JJLjava/lang/String;IIIII[FI)F",
Fabrice Di Meglio665f02c2013-03-20 14:56:05 -07001008 (void*) SkPaintGlue::getTextRunAdvances__StringIIIII_FI},
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001009
1010
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001011 {"native_getTextGlyphs","(JLjava/lang/String;IIIII[C)I",
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001012 (void*) SkPaintGlue::getTextGlyphs__StringIIIII_C},
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001013 {"native_getTextRunCursor", "(J[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C},
1014 {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I",
Doug Felt0c702b82010-05-14 10:55:42 -07001015 (void*) SkPaintGlue::getTextRunCursor__String},
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001016 {"native_getTextPath","(JI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C},
1017 {"native_getTextPath","(JILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String},
1018 {"nativeGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 (void*) SkPaintGlue::getStringBounds },
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001020 {"nativeGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 (void*) SkPaintGlue::getCharArrayBounds },
Romain Guy1e45aae2010-08-13 19:39:53 -07001022 {"nSetShadowLayer", "(FFFI)V", (void*)SkPaintGlue::setShadowLayer}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023};
1024
1025static jfieldID req_fieldID(jfieldID id) {
1026 SkASSERT(id);
1027 return id;
1028}
1029
1030int register_android_graphics_Paint(JNIEnv* env) {
1031 gFontMetrics_class = env->FindClass("android/graphics/Paint$FontMetrics");
1032 SkASSERT(gFontMetrics_class);
1033 gFontMetrics_class = (jclass)env->NewGlobalRef(gFontMetrics_class);
1034
1035 gFontMetrics_fieldID.top = req_fieldID(env->GetFieldID(gFontMetrics_class, "top", "F"));
1036 gFontMetrics_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetrics_class, "ascent", "F"));
1037 gFontMetrics_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetrics_class, "descent", "F"));
1038 gFontMetrics_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetrics_class, "bottom", "F"));
1039 gFontMetrics_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetrics_class, "leading", "F"));
1040
1041 gFontMetricsInt_class = env->FindClass("android/graphics/Paint$FontMetricsInt");
1042 SkASSERT(gFontMetricsInt_class);
1043 gFontMetricsInt_class = (jclass)env->NewGlobalRef(gFontMetricsInt_class);
1044
1045 gFontMetricsInt_fieldID.top = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "top", "I"));
1046 gFontMetricsInt_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "ascent", "I"));
1047 gFontMetricsInt_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "descent", "I"));
1048 gFontMetricsInt_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "bottom", "I"));
1049 gFontMetricsInt_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "leading", "I"));
1050
1051 int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Paint", methods,
1052 sizeof(methods) / sizeof(methods[0]));
1053 return result;
1054}
1055
1056}