1 /* libs/android_runtime/android/graphics/Paint.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** 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
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** 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
15 ** limitations under the License.
16 */
17
18 // This file was generated from the C++ include file: SkPaint.h
19 // Any changes made to this file will be discarded by the build.
20 // To change this file, either edit the include, or device/tools/gluemaker/main.cpp,
21 // or one of the auxilary file specifications in device/tools/gluemaker.
22
23 #include "jni.h"
24 #include "GraphicsJNI.h"
25 #include <android_runtime/AndroidRuntime.h>
26
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"
34
35 namespace android {
36
37 struct JMetricsID {
38 jfieldID top;
39 jfieldID ascent;
40 jfieldID descent;
41 jfieldID bottom;
42 jfieldID leading;
43 };
44
45 static jclass gFontMetrics_class;
46 static JMetricsID gFontMetrics_fieldID;
47
48 static jclass gFontMetricsInt_class;
49 static JMetricsID gFontMetricsInt_fieldID;
50
defaultSettingsForAndroid(SkPaint * paint)51 static void defaultSettingsForAndroid(SkPaint* paint) {
52 // looks best we decided
53 paint->setHinting(SkPaint::kSlight_Hinting);
54 // utf16 is required for java
55 paint->setTextEncoding(SkPaint::kUTF16_TextEncoding);
56 }
57
58 class SkPaintGlue {
59 public:
60
finalizer(JNIEnv * env,jobject clazz,SkPaint * obj)61 static void finalizer(JNIEnv* env, jobject clazz, SkPaint* obj) {
62 delete obj;
63 }
64
init(JNIEnv * env,jobject clazz)65 static SkPaint* init(JNIEnv* env, jobject clazz) {
66 SkPaint* obj = new SkPaint();
67 defaultSettingsForAndroid(obj);
68 return obj;
69 }
70
intiWithPaint(JNIEnv * env,jobject clazz,SkPaint * paint)71 static SkPaint* intiWithPaint(JNIEnv* env, jobject clazz, SkPaint* paint) {
72 SkPaint* obj = new SkPaint(*paint);
73 return obj;
74 }
75
reset(JNIEnv * env,jobject clazz,SkPaint * obj)76 static void reset(JNIEnv* env, jobject clazz, SkPaint* obj) {
77 obj->reset();
78 defaultSettingsForAndroid(obj);
79 }
80
assign(JNIEnv * env,jobject clazz,SkPaint * dst,const SkPaint * src)81 static void assign(JNIEnv* env, jobject clazz, SkPaint* dst, const SkPaint* src) {
82 *dst = *src;
83 }
84
getFlags(JNIEnv * env,jobject paint)85 static jint getFlags(JNIEnv* env, jobject paint) {
86 NPE_CHECK_RETURN_ZERO(env, paint);
87 return GraphicsJNI::getNativePaint(env, paint)->getFlags();
88 }
89
setFlags(JNIEnv * env,jobject paint,jint flags)90 static void setFlags(JNIEnv* env, jobject paint, jint flags) {
91 NPE_CHECK_RETURN_VOID(env, paint);
92 GraphicsJNI::getNativePaint(env, paint)->setFlags(flags);
93 }
94
setAntiAlias(JNIEnv * env,jobject paint,jboolean aa)95 static void setAntiAlias(JNIEnv* env, jobject paint, jboolean aa) {
96 NPE_CHECK_RETURN_VOID(env, paint);
97 GraphicsJNI::getNativePaint(env, paint)->setAntiAlias(aa);
98 }
99
setLinearText(JNIEnv * env,jobject paint,jboolean linearText)100 static void setLinearText(JNIEnv* env, jobject paint, jboolean linearText) {
101 NPE_CHECK_RETURN_VOID(env, paint);
102 GraphicsJNI::getNativePaint(env, paint)->setLinearText(linearText);
103 }
104
setSubpixelText(JNIEnv * env,jobject paint,jboolean subpixelText)105 static void setSubpixelText(JNIEnv* env, jobject paint, jboolean subpixelText) {
106 NPE_CHECK_RETURN_VOID(env, paint);
107 GraphicsJNI::getNativePaint(env, paint)->setSubpixelText(subpixelText);
108 }
109
setUnderlineText(JNIEnv * env,jobject paint,jboolean underlineText)110 static void setUnderlineText(JNIEnv* env, jobject paint, jboolean underlineText) {
111 NPE_CHECK_RETURN_VOID(env, paint);
112 GraphicsJNI::getNativePaint(env, paint)->setUnderlineText(underlineText);
113 }
114
setStrikeThruText(JNIEnv * env,jobject paint,jboolean strikeThruText)115 static void setStrikeThruText(JNIEnv* env, jobject paint, jboolean strikeThruText) {
116 NPE_CHECK_RETURN_VOID(env, paint);
117 GraphicsJNI::getNativePaint(env, paint)->setStrikeThruText(strikeThruText);
118 }
119
setFakeBoldText(JNIEnv * env,jobject paint,jboolean fakeBoldText)120 static void setFakeBoldText(JNIEnv* env, jobject paint, jboolean fakeBoldText) {
121 NPE_CHECK_RETURN_VOID(env, paint);
122 GraphicsJNI::getNativePaint(env, paint)->setFakeBoldText(fakeBoldText);
123 }
124
setFilterBitmap(JNIEnv * env,jobject paint,jboolean filterBitmap)125 static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
126 NPE_CHECK_RETURN_VOID(env, paint);
127 GraphicsJNI::getNativePaint(env, paint)->setFilterBitmap(filterBitmap);
128 }
129
setDither(JNIEnv * env,jobject paint,jboolean dither)130 static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
131 NPE_CHECK_RETURN_VOID(env, paint);
132 GraphicsJNI::getNativePaint(env, paint)->setDither(dither);
133 }
134
getStyle(JNIEnv * env,jobject clazz,SkPaint * obj)135 static jint getStyle(JNIEnv* env, jobject clazz, SkPaint* obj) {
136 return obj->getStyle();
137 }
138
setStyle(JNIEnv * env,jobject clazz,SkPaint * obj,SkPaint::Style style)139 static void setStyle(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Style style) {
140 obj->setStyle(style);
141 }
142
getColor(JNIEnv * env,jobject paint)143 static jint getColor(JNIEnv* env, jobject paint) {
144 NPE_CHECK_RETURN_ZERO(env, paint);
145 return GraphicsJNI::getNativePaint(env, paint)->getColor();
146 }
147
getAlpha(JNIEnv * env,jobject paint)148 static jint getAlpha(JNIEnv* env, jobject paint) {
149 NPE_CHECK_RETURN_ZERO(env, paint);
150 return GraphicsJNI::getNativePaint(env, paint)->getAlpha();
151 }
152
setColor(JNIEnv * env,jobject paint,jint color)153 static void setColor(JNIEnv* env, jobject paint, jint color) {
154 NPE_CHECK_RETURN_VOID(env, paint);
155 GraphicsJNI::getNativePaint(env, paint)->setColor(color);
156 }
157
setAlpha(JNIEnv * env,jobject paint,jint a)158 static void setAlpha(JNIEnv* env, jobject paint, jint a) {
159 NPE_CHECK_RETURN_VOID(env, paint);
160 GraphicsJNI::getNativePaint(env, paint)->setAlpha(a);
161 }
162
getStrokeWidth(JNIEnv * env,jobject paint)163 static jfloat getStrokeWidth(JNIEnv* env, jobject paint) {
164 NPE_CHECK_RETURN_ZERO(env, paint);
165 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeWidth());
166 }
167
setStrokeWidth(JNIEnv * env,jobject paint,jfloat width)168 static void setStrokeWidth(JNIEnv* env, jobject paint, jfloat width) {
169 NPE_CHECK_RETURN_VOID(env, paint);
170 GraphicsJNI::getNativePaint(env, paint)->setStrokeWidth(SkFloatToScalar(width));
171 }
172
getStrokeMiter(JNIEnv * env,jobject paint)173 static jfloat getStrokeMiter(JNIEnv* env, jobject paint) {
174 NPE_CHECK_RETURN_ZERO(env, paint);
175 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeMiter());
176 }
177
setStrokeMiter(JNIEnv * env,jobject paint,jfloat miter)178 static void setStrokeMiter(JNIEnv* env, jobject paint, jfloat miter) {
179 NPE_CHECK_RETURN_VOID(env, paint);
180 GraphicsJNI::getNativePaint(env, paint)->setStrokeMiter(SkFloatToScalar(miter));
181 }
182
getStrokeCap(JNIEnv * env,jobject clazz,SkPaint * obj)183 static jint getStrokeCap(JNIEnv* env, jobject clazz, SkPaint* obj) {
184 return obj->getStrokeCap();
185 }
186
setStrokeCap(JNIEnv * env,jobject clazz,SkPaint * obj,SkPaint::Cap cap)187 static void setStrokeCap(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Cap cap) {
188 obj->setStrokeCap(cap);
189 }
190
getStrokeJoin(JNIEnv * env,jobject clazz,SkPaint * obj)191 static jint getStrokeJoin(JNIEnv* env, jobject clazz, SkPaint* obj) {
192 return obj->getStrokeJoin();
193 }
194
setStrokeJoin(JNIEnv * env,jobject clazz,SkPaint * obj,SkPaint::Join join)195 static void setStrokeJoin(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Join join) {
196 obj->setStrokeJoin(join);
197 }
198
getFillPath(JNIEnv * env,jobject clazz,SkPaint * obj,SkPath * src,SkPath * dst)199 static jboolean getFillPath(JNIEnv* env, jobject clazz, SkPaint* obj, SkPath* src, SkPath* dst) {
200 return obj->getFillPath(*src, dst);
201 }
202
setShader(JNIEnv * env,jobject clazz,SkPaint * obj,SkShader * shader)203 static SkShader* setShader(JNIEnv* env, jobject clazz, SkPaint* obj, SkShader* shader) {
204 return obj->setShader(shader);
205 }
206
setColorFilter(JNIEnv * env,jobject clazz,SkPaint * obj,SkColorFilter * filter)207 static SkColorFilter* setColorFilter(JNIEnv* env, jobject clazz, SkPaint* obj, SkColorFilter* filter) {
208 return obj->setColorFilter(filter);
209 }
210
setXfermode(JNIEnv * env,jobject clazz,SkPaint * obj,SkXfermode * xfermode)211 static SkXfermode* setXfermode(JNIEnv* env, jobject clazz, SkPaint* obj, SkXfermode* xfermode) {
212 return obj->setXfermode(xfermode);
213 }
214
setPathEffect(JNIEnv * env,jobject clazz,SkPaint * obj,SkPathEffect * effect)215 static SkPathEffect* setPathEffect(JNIEnv* env, jobject clazz, SkPaint* obj, SkPathEffect* effect) {
216 return obj->setPathEffect(effect);
217 }
218
setMaskFilter(JNIEnv * env,jobject clazz,SkPaint * obj,SkMaskFilter * maskfilter)219 static SkMaskFilter* setMaskFilter(JNIEnv* env, jobject clazz, SkPaint* obj, SkMaskFilter* maskfilter) {
220 return obj->setMaskFilter(maskfilter);
221 }
222
setTypeface(JNIEnv * env,jobject clazz,SkPaint * obj,SkTypeface * typeface)223 static SkTypeface* setTypeface(JNIEnv* env, jobject clazz, SkPaint* obj, SkTypeface* typeface) {
224 return obj->setTypeface(typeface);
225 }
226
setRasterizer(JNIEnv * env,jobject clazz,SkPaint * obj,SkRasterizer * rasterizer)227 static SkRasterizer* setRasterizer(JNIEnv* env, jobject clazz, SkPaint* obj, SkRasterizer* rasterizer) {
228 return obj->setRasterizer(rasterizer);
229 }
230
getTextAlign(JNIEnv * env,jobject clazz,SkPaint * obj)231 static jint getTextAlign(JNIEnv* env, jobject clazz, SkPaint* obj) {
232 return obj->getTextAlign();
233 }
234
setTextAlign(JNIEnv * env,jobject clazz,SkPaint * obj,SkPaint::Align align)235 static void setTextAlign(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Align align) {
236 obj->setTextAlign(align);
237 }
238
getTextSize(JNIEnv * env,jobject paint)239 static jfloat getTextSize(JNIEnv* env, jobject paint) {
240 NPE_CHECK_RETURN_ZERO(env, paint);
241 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSize());
242 }
243
setTextSize(JNIEnv * env,jobject paint,jfloat textSize)244 static void setTextSize(JNIEnv* env, jobject paint, jfloat textSize) {
245 NPE_CHECK_RETURN_VOID(env, paint);
246 GraphicsJNI::getNativePaint(env, paint)->setTextSize(SkFloatToScalar(textSize));
247 }
248
getTextScaleX(JNIEnv * env,jobject paint)249 static jfloat getTextScaleX(JNIEnv* env, jobject paint) {
250 NPE_CHECK_RETURN_ZERO(env, paint);
251 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextScaleX());
252 }
253
setTextScaleX(JNIEnv * env,jobject paint,jfloat scaleX)254 static void setTextScaleX(JNIEnv* env, jobject paint, jfloat scaleX) {
255 NPE_CHECK_RETURN_VOID(env, paint);
256 GraphicsJNI::getNativePaint(env, paint)->setTextScaleX(SkFloatToScalar(scaleX));
257 }
258
getTextSkewX(JNIEnv * env,jobject paint)259 static jfloat getTextSkewX(JNIEnv* env, jobject paint) {
260 NPE_CHECK_RETURN_ZERO(env, paint);
261 return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSkewX());
262 }
263
setTextSkewX(JNIEnv * env,jobject paint,jfloat skewX)264 static void setTextSkewX(JNIEnv* env, jobject paint, jfloat skewX) {
265 NPE_CHECK_RETURN_VOID(env, paint);
266 GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(SkFloatToScalar(skewX));
267 }
268
ascent(JNIEnv * env,jobject paint)269 static jfloat ascent(JNIEnv* env, jobject paint) {
270 NPE_CHECK_RETURN_ZERO(env, paint);
271 SkPaint::FontMetrics metrics;
272 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
273 return SkScalarToFloat(metrics.fAscent);
274 }
275
descent(JNIEnv * env,jobject paint)276 static jfloat descent(JNIEnv* env, jobject paint) {
277 NPE_CHECK_RETURN_ZERO(env, paint);
278 SkPaint::FontMetrics metrics;
279 (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
280 return SkScalarToFloat(metrics.fDescent);
281 }
282
getFontMetrics(JNIEnv * env,jobject paint,jobject metricsObj)283 static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
284 NPE_CHECK_RETURN_ZERO(env, paint);
285 SkPaint::FontMetrics metrics;
286 SkScalar spacing = GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
287
288 if (metricsObj) {
289 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
290 env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop));
291 env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent));
292 env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent));
293 env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom));
294 env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading));
295 }
296 return SkScalarToFloat(spacing);
297 }
298
getFontMetricsInt(JNIEnv * env,jobject paint,jobject metricsObj)299 static jint getFontMetricsInt(JNIEnv* env, jobject paint, jobject metricsObj) {
300 NPE_CHECK_RETURN_ZERO(env, paint);
301 SkPaint::FontMetrics metrics;
302
303 GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
304 int ascent = SkScalarRound(metrics.fAscent);
305 int descent = SkScalarRound(metrics.fDescent);
306 int leading = SkScalarRound(metrics.fLeading);
307
308 if (metricsObj) {
309 SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class));
310 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloor(metrics.fTop));
311 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent);
312 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent);
313 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeil(metrics.fBottom));
314 env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading);
315 }
316 return descent - ascent + leading;
317 }
318
measureText_CII(JNIEnv * env,jobject jpaint,jcharArray text,int index,int count)319 static jfloat measureText_CII(JNIEnv* env, jobject jpaint, jcharArray text, int index, int count) {
320 NPE_CHECK_RETURN_ZERO(env, jpaint);
321 NPE_CHECK_RETURN_ZERO(env, text);
322
323 size_t textLength = env->GetArrayLength(text);
324
325 if ((index | count) < 0 || (size_t)(index + count) > textLength) {
326 doThrow(env, "java/lang/ArrayIndexOutOfBoundsException");
327 return 0;
328 }
329
330 const SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
331 const jchar* textArray = env->GetCharArrayElements(text, NULL);
332 // we double count, since measureText wants a byteLength
333 SkScalar width = paint->measureText(textArray + index, count << 1);
334 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
335 JNI_ABORT);
336
337 return SkScalarToFloat(width);
338 }
339
measureText_StringII(JNIEnv * env,jobject jpaint,jstring text,int start,int end)340 static jfloat measureText_StringII(JNIEnv* env, jobject jpaint, jstring text, int start, int end) {
341 NPE_CHECK_RETURN_ZERO(env, jpaint);
342 NPE_CHECK_RETURN_ZERO(env, text);
343
344 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
345 const jchar* textArray = env->GetStringChars(text, NULL);
346 size_t textLength = env->GetStringLength(text);
347
348 int count = end - start;
349 if ((start | count) < 0 || (size_t)count > textLength) {
350 doThrow(env, "java/lang/IndexOutOfBoundsException");
351 return 0;
352 }
353
354 jfloat width = SkScalarToFloat(paint->measureText(textArray + start, count << 1));
355 env->ReleaseStringChars(text, textArray);
356 return width;
357 }
358
measureText_String(JNIEnv * env,jobject jpaint,jstring text)359 static jfloat measureText_String(JNIEnv* env, jobject jpaint, jstring text) {
360 NPE_CHECK_RETURN_ZERO(env, jpaint);
361 NPE_CHECK_RETURN_ZERO(env, text);
362
363 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
364 const jchar* textArray = env->GetStringChars(text, NULL);
365 size_t textLength = env->GetStringLength(text);
366
367 jfloat width = SkScalarToFloat(paint->measureText(textArray, textLength << 1));
368 env->ReleaseStringChars(text, textArray);
369 return width;
370 }
371
dotextwidths(JNIEnv * env,SkPaint * paint,const jchar text[],int count,jfloatArray widths)372 static int dotextwidths(JNIEnv* env, SkPaint* paint, const jchar text[], int count, jfloatArray widths) {
373 AutoJavaFloatArray autoWidths(env, widths, count);
374 jfloat* widthsArray = autoWidths.ptr();
375 SkScalar* scalarArray = (SkScalar*)widthsArray;
376
377 count = paint->getTextWidths(text, count << 1, scalarArray);
378 for (int i = 0; i < count; i++) {
379 widthsArray[i] = SkScalarToFloat(scalarArray[i]);
380 }
381 return count;
382 }
383
getTextWidths___CII_F(JNIEnv * env,jobject clazz,SkPaint * paint,jcharArray text,int index,int count,jfloatArray widths)384 static int getTextWidths___CII_F(JNIEnv* env, jobject clazz, SkPaint* paint, jcharArray text, int index, int count, jfloatArray widths) {
385 const jchar* textArray = env->GetCharArrayElements(text, NULL);
386 count = dotextwidths(env, paint, textArray + index, count, widths);
387 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
388 JNI_ABORT);
389 return count;
390 }
391
getTextWidths__StringII_F(JNIEnv * env,jobject clazz,SkPaint * paint,jstring text,int start,int end,jfloatArray widths)392 static int getTextWidths__StringII_F(JNIEnv* env, jobject clazz, SkPaint* paint, jstring text, int start, int end, jfloatArray widths) {
393 const jchar* textArray = env->GetStringChars(text, NULL);
394 int count = dotextwidths(env, paint, textArray + start, end - start, widths);
395 env->ReleaseStringChars(text, textArray);
396 return count;
397 }
398
getTextPath___CIIFFPath(JNIEnv * env,jobject clazz,SkPaint * paint,jcharArray text,int index,int count,jfloat x,jfloat y,SkPath * path)399 static void getTextPath___CIIFFPath(JNIEnv* env, jobject clazz, SkPaint* paint, jcharArray text, int index, int count, jfloat x, jfloat y, SkPath* path) {
400 const jchar* textArray = env->GetCharArrayElements(text, NULL);
401 paint->getTextPath(textArray + index, count << 1, SkFloatToScalar(x), SkFloatToScalar(y), path);
402 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
403 JNI_ABORT);
404 }
405
getTextPath__StringIIFFPath(JNIEnv * env,jobject clazz,SkPaint * paint,jstring text,int start,int end,jfloat x,jfloat y,SkPath * path)406 static void getTextPath__StringIIFFPath(JNIEnv* env, jobject clazz, SkPaint* paint, jstring text, int start, int end, jfloat x, jfloat y, SkPath* path) {
407 const jchar* textArray = env->GetStringChars(text, NULL);
408 paint->getTextPath(textArray + start, (end - start) << 1, SkFloatToScalar(x), SkFloatToScalar(y), path);
409 env->ReleaseStringChars(text, textArray);
410 }
411
setShadowLayer(JNIEnv * env,jobject jpaint,jfloat radius,jfloat dx,jfloat dy,int color)412 static void setShadowLayer(JNIEnv* env, jobject jpaint, jfloat radius,
413 jfloat dx, jfloat dy, int color) {
414 NPE_CHECK_RETURN_VOID(env, jpaint);
415
416 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
417 if (radius <= 0) {
418 paint->setLooper(NULL);
419 }
420 else {
421 paint->setLooper(new SkBlurDrawLooper(SkFloatToScalar(radius),
422 SkFloatToScalar(dx),
423 SkFloatToScalar(dy),
424 (SkColor)color))->unref();
425 }
426 }
427
breakText(JNIEnv * env,const SkPaint & paint,const jchar text[],int count,float maxWidth,jfloatArray jmeasured,SkPaint::TextBufferDirection tbd)428 static int breakText(JNIEnv* env, const SkPaint& paint, const jchar text[],
429 int count, float maxWidth, jfloatArray jmeasured,
430 SkPaint::TextBufferDirection tbd) {
431 SkASSERT(paint.getTextEncoding() == SkPaint::kUTF16_TextEncoding);
432
433 SkScalar measured;
434 size_t bytes = paint.breakText(text, count << 1,
435 SkFloatToScalar(maxWidth), &measured, tbd);
436 SkASSERT((bytes & 1) == 0);
437
438 if (jmeasured && env->GetArrayLength(jmeasured) > 0) {
439 AutoJavaFloatArray autoMeasured(env, jmeasured, 1);
440 jfloat* array = autoMeasured.ptr();
441 array[0] = SkScalarToFloat(measured);
442 }
443 return bytes >> 1;
444 }
445
breakTextC(JNIEnv * env,jobject jpaint,jcharArray jtext,int index,int count,float maxWidth,jfloatArray jmeasuredWidth)446 static int breakTextC(JNIEnv* env, jobject jpaint, jcharArray jtext,
447 int index, int count, float maxWidth, jfloatArray jmeasuredWidth) {
448 NPE_CHECK_RETURN_ZERO(env, jpaint);
449 NPE_CHECK_RETURN_ZERO(env, jtext);
450
451 SkPaint::TextBufferDirection tbd;
452 if (count < 0) {
453 tbd = SkPaint::kBackward_TextBufferDirection;
454 count = -count;
455 }
456 else {
457 tbd = SkPaint::kForward_TextBufferDirection;
458 }
459
460 if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
461 doThrow(env, "java/lang/ArrayIndexOutOfBoundsException");
462 return 0;
463 }
464
465 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
466 const jchar* text = env->GetCharArrayElements(jtext, NULL);
467 count = breakText(env, *paint, text + index, count, maxWidth,
468 jmeasuredWidth, tbd);
469 env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text),
470 JNI_ABORT);
471 return count;
472 }
473
breakTextS(JNIEnv * env,jobject jpaint,jstring jtext,bool forwards,float maxWidth,jfloatArray jmeasuredWidth)474 static int breakTextS(JNIEnv* env, jobject jpaint, jstring jtext,
475 bool forwards, float maxWidth, jfloatArray jmeasuredWidth) {
476 NPE_CHECK_RETURN_ZERO(env, jpaint);
477 NPE_CHECK_RETURN_ZERO(env, jtext);
478
479 SkPaint::TextBufferDirection tbd = forwards ?
480 SkPaint::kForward_TextBufferDirection :
481 SkPaint::kBackward_TextBufferDirection;
482
483 SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
484 int count = env->GetStringLength(jtext);
485 const jchar* text = env->GetStringChars(jtext, NULL);
486 count = breakText(env, *paint, text, count, maxWidth,
487 jmeasuredWidth, tbd);
488 env->ReleaseStringChars(jtext, text);
489 return count;
490 }
491
doTextBounds(JNIEnv * env,const jchar * text,int count,jobject bounds,const SkPaint & paint)492 static void doTextBounds(JNIEnv* env, const jchar* text, int count,
493 jobject bounds, const SkPaint& paint)
494 {
495 SkRect r;
496 SkIRect ir;
497
498 paint.measureText(text, count << 1, &r);
499 r.roundOut(&ir);
500 GraphicsJNI::irect_to_jrect(ir, env, bounds);
501 }
502
getStringBounds(JNIEnv * env,jobject,const SkPaint * paint,jstring text,int start,int end,jobject bounds)503 static void getStringBounds(JNIEnv* env, jobject, const SkPaint* paint,
504 jstring text, int start, int end, jobject bounds)
505 {
506 const jchar* textArray = env->GetStringChars(text, NULL);
507 doTextBounds(env, textArray + start, end - start, bounds, *paint);
508 env->ReleaseStringChars(text, textArray);
509 }
510
getCharArrayBounds(JNIEnv * env,jobject,const SkPaint * paint,jcharArray text,int index,int count,jobject bounds)511 static void getCharArrayBounds(JNIEnv* env, jobject, const SkPaint* paint,
512 jcharArray text, int index, int count, jobject bounds)
513 {
514 const jchar* textArray = env->GetCharArrayElements(text, NULL);
515 doTextBounds(env, textArray + index, count, bounds, *paint);
516 env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
517 JNI_ABORT);
518 }
519
520 };
521
522 static JNINativeMethod methods[] = {
523 {"finalizer", "(I)V", (void*) SkPaintGlue::finalizer},
524 {"native_init","()I", (void*) SkPaintGlue::init},
525 {"native_initWithPaint","(I)I", (void*) SkPaintGlue::intiWithPaint},
526 {"native_reset","(I)V", (void*) SkPaintGlue::reset},
527 {"native_set","(II)V", (void*) SkPaintGlue::assign},
528 {"getFlags","()I", (void*) SkPaintGlue::getFlags},
529 {"setFlags","(I)V", (void*) SkPaintGlue::setFlags},
530 {"setAntiAlias","(Z)V", (void*) SkPaintGlue::setAntiAlias},
531 {"setSubpixelText","(Z)V", (void*) SkPaintGlue::setSubpixelText},
532 {"setLinearText","(Z)V", (void*) SkPaintGlue::setLinearText},
533 {"setUnderlineText","(Z)V", (void*) SkPaintGlue::setUnderlineText},
534 {"setStrikeThruText","(Z)V", (void*) SkPaintGlue::setStrikeThruText},
535 {"setFakeBoldText","(Z)V", (void*) SkPaintGlue::setFakeBoldText},
536 {"setFilterBitmap","(Z)V", (void*) SkPaintGlue::setFilterBitmap},
537 {"setDither","(Z)V", (void*) SkPaintGlue::setDither},
538 {"native_getStyle","(I)I", (void*) SkPaintGlue::getStyle},
539 {"native_setStyle","(II)V", (void*) SkPaintGlue::setStyle},
540 {"getColor","()I", (void*) SkPaintGlue::getColor},
541 {"setColor","(I)V", (void*) SkPaintGlue::setColor},
542 {"getAlpha","()I", (void*) SkPaintGlue::getAlpha},
543 {"setAlpha","(I)V", (void*) SkPaintGlue::setAlpha},
544 {"getStrokeWidth","()F", (void*) SkPaintGlue::getStrokeWidth},
545 {"setStrokeWidth","(F)V", (void*) SkPaintGlue::setStrokeWidth},
546 {"getStrokeMiter","()F", (void*) SkPaintGlue::getStrokeMiter},
547 {"setStrokeMiter","(F)V", (void*) SkPaintGlue::setStrokeMiter},
548 {"native_getStrokeCap","(I)I", (void*) SkPaintGlue::getStrokeCap},
549 {"native_setStrokeCap","(II)V", (void*) SkPaintGlue::setStrokeCap},
550 {"native_getStrokeJoin","(I)I", (void*) SkPaintGlue::getStrokeJoin},
551 {"native_setStrokeJoin","(II)V", (void*) SkPaintGlue::setStrokeJoin},
552 {"native_getFillPath","(III)Z", (void*) SkPaintGlue::getFillPath},
553 {"native_setShader","(II)I", (void*) SkPaintGlue::setShader},
554 {"native_setColorFilter","(II)I", (void*) SkPaintGlue::setColorFilter},
555 {"native_setXfermode","(II)I", (void*) SkPaintGlue::setXfermode},
556 {"native_setPathEffect","(II)I", (void*) SkPaintGlue::setPathEffect},
557 {"native_setMaskFilter","(II)I", (void*) SkPaintGlue::setMaskFilter},
558 {"native_setTypeface","(II)I", (void*) SkPaintGlue::setTypeface},
559 {"native_setRasterizer","(II)I", (void*) SkPaintGlue::setRasterizer},
560 {"native_getTextAlign","(I)I", (void*) SkPaintGlue::getTextAlign},
561 {"native_setTextAlign","(II)V", (void*) SkPaintGlue::setTextAlign},
562 {"getTextSize","()F", (void*) SkPaintGlue::getTextSize},
563 {"setTextSize","(F)V", (void*) SkPaintGlue::setTextSize},
564 {"getTextScaleX","()F", (void*) SkPaintGlue::getTextScaleX},
565 {"setTextScaleX","(F)V", (void*) SkPaintGlue::setTextScaleX},
566 {"getTextSkewX","()F", (void*) SkPaintGlue::getTextSkewX},
567 {"setTextSkewX","(F)V", (void*) SkPaintGlue::setTextSkewX},
568 {"ascent","()F", (void*) SkPaintGlue::ascent},
569 {"descent","()F", (void*) SkPaintGlue::descent},
570 {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)SkPaintGlue::getFontMetrics},
571 {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)SkPaintGlue::getFontMetricsInt},
572 {"native_measureText","([CII)F", (void*) SkPaintGlue::measureText_CII},
573 {"native_measureText","(Ljava/lang/String;)F", (void*) SkPaintGlue::measureText_String},
574 {"native_measureText","(Ljava/lang/String;II)F", (void*) SkPaintGlue::measureText_StringII},
575 {"native_breakText","([CIIF[F)I", (void*) SkPaintGlue::breakTextC},
576 {"native_breakText","(Ljava/lang/String;ZF[F)I", (void*) SkPaintGlue::breakTextS},
577 {"native_getTextWidths","(I[CII[F)I", (void*) SkPaintGlue::getTextWidths___CII_F},
578 {"native_getTextWidths","(ILjava/lang/String;II[F)I", (void*) SkPaintGlue::getTextWidths__StringII_F},
579 {"native_getTextPath","(I[CIIFFI)V", (void*) SkPaintGlue::getTextPath___CIIFFPath},
580 {"native_getTextPath","(ILjava/lang/String;IIFFI)V", (void*) SkPaintGlue::getTextPath__StringIIFFPath},
581 {"nativeGetStringBounds", "(ILjava/lang/String;IILandroid/graphics/Rect;)V",
582 (void*) SkPaintGlue::getStringBounds },
583 {"nativeGetCharArrayBounds", "(I[CIILandroid/graphics/Rect;)V",
584 (void*) SkPaintGlue::getCharArrayBounds },
585 {"setShadowLayer", "(FFFI)V", (void*)SkPaintGlue::setShadowLayer}
586 };
587
req_fieldID(jfieldID id)588 static jfieldID req_fieldID(jfieldID id) {
589 SkASSERT(id);
590 return id;
591 }
592
register_android_graphics_Paint(JNIEnv * env)593 int register_android_graphics_Paint(JNIEnv* env) {
594 gFontMetrics_class = env->FindClass("android/graphics/Paint$FontMetrics");
595 SkASSERT(gFontMetrics_class);
596 gFontMetrics_class = (jclass)env->NewGlobalRef(gFontMetrics_class);
597
598 gFontMetrics_fieldID.top = req_fieldID(env->GetFieldID(gFontMetrics_class, "top", "F"));
599 gFontMetrics_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetrics_class, "ascent", "F"));
600 gFontMetrics_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetrics_class, "descent", "F"));
601 gFontMetrics_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetrics_class, "bottom", "F"));
602 gFontMetrics_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetrics_class, "leading", "F"));
603
604 gFontMetricsInt_class = env->FindClass("android/graphics/Paint$FontMetricsInt");
605 SkASSERT(gFontMetricsInt_class);
606 gFontMetricsInt_class = (jclass)env->NewGlobalRef(gFontMetricsInt_class);
607
608 gFontMetricsInt_fieldID.top = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "top", "I"));
609 gFontMetricsInt_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "ascent", "I"));
610 gFontMetricsInt_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "descent", "I"));
611 gFontMetricsInt_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "bottom", "I"));
612 gFontMetricsInt_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "leading", "I"));
613
614 int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Paint", methods,
615 sizeof(methods) / sizeof(methods[0]));
616 return result;
617 }
618
619 }
620