1 /*
2 * Copyright (C) 2006-2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "jni.h"
18 #include "GraphicsJNI.h"
19 #include <android_runtime/AndroidRuntime.h>
20
21 #include "SkCanvas.h"
22 #include "SkDevice.h"
23 #include "SkGLCanvas.h"
24 #include "SkGraphics.h"
25 #include "SkImageRef_GlobalPool.h"
26 #include "SkPorterDuff.h"
27 #include "SkShader.h"
28 #include "SkTemplates.h"
29
30 #define TIME_DRAWx
31
get_thread_msec()32 static uint32_t get_thread_msec() {
33 #if defined(HAVE_POSIX_CLOCKS)
34 struct timespec tm;
35
36 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm);
37
38 return tm.tv_sec * 1000LL + tm.tv_nsec / 1000000;
39 #else
40 struct timeval tv;
41
42 gettimeofday(&tv, NULL);
43 return tv.tv_sec * 1000LL + tv.tv_usec / 1000;
44 #endif
45 }
46
47 namespace android {
48
49 class SkCanvasGlue {
50 public:
51
finalizer(JNIEnv * env,jobject clazz,SkCanvas * canvas)52 static void finalizer(JNIEnv* env, jobject clazz, SkCanvas* canvas) {
53 canvas->unref();
54 }
55
initRaster(JNIEnv * env,jobject,SkBitmap * bitmap)56 static SkCanvas* initRaster(JNIEnv* env, jobject, SkBitmap* bitmap) {
57 return bitmap ? new SkCanvas(*bitmap) : new SkCanvas;
58 }
59
initGL(JNIEnv * env,jobject)60 static SkCanvas* initGL(JNIEnv* env, jobject) {
61 return new SkGLCanvas;
62 }
63
freeCaches(JNIEnv * env,jobject)64 static void freeCaches(JNIEnv* env, jobject) {
65 // these are called in no particular order
66 SkGLCanvas::DeleteAllTextures();
67 SkImageRef_GlobalPool::SetRAMUsed(0);
68 SkGraphics::SetFontCacheUsed(0);
69 }
70
isOpaque(JNIEnv * env,jobject jcanvas)71 static jboolean isOpaque(JNIEnv* env, jobject jcanvas) {
72 NPE_CHECK_RETURN_ZERO(env, jcanvas);
73 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
74
75 /*
76 Currently we cannot support transparency in GL-based canvas' at
77 the view level. Therefore we cannot base our answer on the device's
78 bitmap, but need to hard-code the answer. If we relax this
79 limitation in views, we can simplify the following code as well.
80
81 Use the getViewport() call to find out if we're gl-based...
82 */
83 if (canvas->getViewport(NULL)) {
84 return true;
85 }
86
87 // normal technique, rely on the device's bitmap for the answer
88 return canvas->getDevice()->accessBitmap(false).isOpaque();
89 }
90
getWidth(JNIEnv * env,jobject jcanvas)91 static int getWidth(JNIEnv* env, jobject jcanvas) {
92 NPE_CHECK_RETURN_ZERO(env, jcanvas);
93 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
94 return canvas->getDevice()->accessBitmap(false).width();
95 }
96
getHeight(JNIEnv * env,jobject jcanvas)97 static int getHeight(JNIEnv* env, jobject jcanvas) {
98 NPE_CHECK_RETURN_ZERO(env, jcanvas);
99 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
100 return canvas->getDevice()->accessBitmap(false).height();
101 }
102
setViewport(JNIEnv * env,jobject,SkCanvas * canvas,int width,int height)103 static void setViewport(JNIEnv* env, jobject, SkCanvas* canvas,
104 int width, int height) {
105 canvas->setViewport(width, height);
106 }
107
setBitmap(JNIEnv * env,jobject,SkCanvas * canvas,SkBitmap * bitmap)108 static void setBitmap(JNIEnv* env, jobject, SkCanvas* canvas,
109 SkBitmap* bitmap) {
110 canvas->setBitmapDevice(*bitmap);
111 }
112
saveAll(JNIEnv * env,jobject jcanvas)113 static int saveAll(JNIEnv* env, jobject jcanvas) {
114 NPE_CHECK_RETURN_ZERO(env, jcanvas);
115 return GraphicsJNI::getNativeCanvas(env, jcanvas)->save();
116 }
117
save(JNIEnv * env,jobject jcanvas,SkCanvas::SaveFlags flags)118 static int save(JNIEnv* env, jobject jcanvas, SkCanvas::SaveFlags flags) {
119 NPE_CHECK_RETURN_ZERO(env, jcanvas);
120 return GraphicsJNI::getNativeCanvas(env, jcanvas)->save(flags);
121 }
122
saveLayer(JNIEnv * env,jobject,SkCanvas * canvas,jobject bounds,SkPaint * paint,int flags)123 static int saveLayer(JNIEnv* env, jobject, SkCanvas* canvas, jobject bounds,
124 SkPaint* paint, int flags) {
125 SkRect* bounds_ = NULL;
126 SkRect storage;
127 if (bounds != NULL) {
128 GraphicsJNI::jrectf_to_rect(env, bounds, &storage);
129 bounds_ = &storage;
130 }
131 return canvas->saveLayer(bounds_, paint, (SkCanvas::SaveFlags)flags);
132 }
133
saveLayer4F(JNIEnv * env,jobject,SkCanvas * canvas,jfloat l,jfloat t,jfloat r,jfloat b,SkPaint * paint,int flags)134 static int saveLayer4F(JNIEnv* env, jobject, SkCanvas* canvas,
135 jfloat l, jfloat t, jfloat r, jfloat b,
136 SkPaint* paint, int flags) {
137 SkRect bounds;
138 bounds.set(SkFloatToScalar(l), SkFloatToScalar(t), SkFloatToScalar(r),
139 SkFloatToScalar(b));
140 return canvas->saveLayer(&bounds, paint, (SkCanvas::SaveFlags)flags);
141 }
142
saveLayerAlpha(JNIEnv * env,jobject,SkCanvas * canvas,jobject bounds,int alpha,int flags)143 static int saveLayerAlpha(JNIEnv* env, jobject, SkCanvas* canvas,
144 jobject bounds, int alpha, int flags) {
145 SkRect* bounds_ = NULL;
146 SkRect storage;
147 if (bounds != NULL) {
148 GraphicsJNI::jrectf_to_rect(env, bounds, &storage);
149 bounds_ = &storage;
150 }
151 return canvas->saveLayerAlpha(bounds_, alpha,
152 (SkCanvas::SaveFlags)flags);
153 }
154
saveLayerAlpha4F(JNIEnv * env,jobject,SkCanvas * canvas,jfloat l,jfloat t,jfloat r,jfloat b,int alpha,int flags)155 static int saveLayerAlpha4F(JNIEnv* env, jobject, SkCanvas* canvas,
156 jfloat l, jfloat t, jfloat r, jfloat b,
157 int alpha, int flags) {
158 SkRect bounds;
159 bounds.set(SkFloatToScalar(l), SkFloatToScalar(t), SkFloatToScalar(r),
160 SkFloatToScalar(b));
161 return canvas->saveLayerAlpha(&bounds, alpha,
162 (SkCanvas::SaveFlags)flags);
163 }
164
restore(JNIEnv * env,jobject jcanvas)165 static void restore(JNIEnv* env, jobject jcanvas) {
166 NPE_CHECK_RETURN_VOID(env, jcanvas);
167 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
168 if (canvas->getSaveCount() <= 1) { // cannot restore anymore
169 doThrowISE(env, "Underflow in restore");
170 return;
171 }
172 canvas->restore();
173 }
174
getSaveCount(JNIEnv * env,jobject jcanvas)175 static int getSaveCount(JNIEnv* env, jobject jcanvas) {
176 NPE_CHECK_RETURN_ZERO(env, jcanvas);
177 return GraphicsJNI::getNativeCanvas(env, jcanvas)->getSaveCount();
178 }
179
restoreToCount(JNIEnv * env,jobject jcanvas,int restoreCount)180 static void restoreToCount(JNIEnv* env, jobject jcanvas, int restoreCount) {
181 NPE_CHECK_RETURN_VOID(env, jcanvas);
182 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
183 if (restoreCount < 1) {
184 doThrowIAE(env, "Underflow in restoreToCount");
185 return;
186 }
187 canvas->restoreToCount(restoreCount);
188 }
189
translate(JNIEnv * env,jobject jcanvas,jfloat dx,jfloat dy)190 static void translate(JNIEnv* env, jobject jcanvas, jfloat dx, jfloat dy) {
191 NPE_CHECK_RETURN_VOID(env, jcanvas);
192 SkScalar dx_ = SkFloatToScalar(dx);
193 SkScalar dy_ = SkFloatToScalar(dy);
194 (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->translate(dx_, dy_);
195 }
196
scale__FF(JNIEnv * env,jobject jcanvas,jfloat sx,jfloat sy)197 static void scale__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) {
198 NPE_CHECK_RETURN_VOID(env, jcanvas);
199 SkScalar sx_ = SkFloatToScalar(sx);
200 SkScalar sy_ = SkFloatToScalar(sy);
201 (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->scale(sx_, sy_);
202 }
203
rotate__F(JNIEnv * env,jobject jcanvas,jfloat degrees)204 static void rotate__F(JNIEnv* env, jobject jcanvas, jfloat degrees) {
205 NPE_CHECK_RETURN_VOID(env, jcanvas);
206 SkScalar degrees_ = SkFloatToScalar(degrees);
207 (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->rotate(degrees_);
208 }
209
skew__FF(JNIEnv * env,jobject jcanvas,jfloat sx,jfloat sy)210 static void skew__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) {
211 NPE_CHECK_RETURN_VOID(env, jcanvas);
212 SkScalar sx_ = SkFloatToScalar(sx);
213 SkScalar sy_ = SkFloatToScalar(sy);
214 (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->skew(sx_, sy_);
215 }
216
concat(JNIEnv * env,jobject,SkCanvas * canvas,const SkMatrix * matrix)217 static void concat(JNIEnv* env, jobject, SkCanvas* canvas,
218 const SkMatrix* matrix) {
219 canvas->concat(*matrix);
220 }
221
setMatrix(JNIEnv * env,jobject,SkCanvas * canvas,const SkMatrix * matrix)222 static void setMatrix(JNIEnv* env, jobject, SkCanvas* canvas,
223 const SkMatrix* matrix) {
224 if (NULL == matrix) {
225 canvas->resetMatrix();
226 } else {
227 canvas->setMatrix(*matrix);
228 }
229 }
230
clipRect_FFFF(JNIEnv * env,jobject jcanvas,jfloat left,jfloat top,jfloat right,jfloat bottom)231 static jboolean clipRect_FFFF(JNIEnv* env, jobject jcanvas, jfloat left,
232 jfloat top, jfloat right, jfloat bottom) {
233 NPE_CHECK_RETURN_ZERO(env, jcanvas);
234 SkRect r;
235 r.set(SkFloatToScalar(left), SkFloatToScalar(top),
236 SkFloatToScalar(right), SkFloatToScalar(bottom));
237 SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
238 return c->clipRect(r);
239 }
240
clipRect_IIII(JNIEnv * env,jobject jcanvas,jint left,jint top,jint right,jint bottom)241 static jboolean clipRect_IIII(JNIEnv* env, jobject jcanvas, jint left,
242 jint top, jint right, jint bottom) {
243 NPE_CHECK_RETURN_ZERO(env, jcanvas);
244 SkRect r;
245 r.set(SkIntToScalar(left), SkIntToScalar(top),
246 SkIntToScalar(right), SkIntToScalar(bottom));
247 return GraphicsJNI::getNativeCanvas(env, jcanvas)->clipRect(r);
248 }
249
clipRect_RectF(JNIEnv * env,jobject jcanvas,jobject rectf)250 static jboolean clipRect_RectF(JNIEnv* env, jobject jcanvas, jobject rectf) {
251 NPE_CHECK_RETURN_ZERO(env, jcanvas);
252 NPE_CHECK_RETURN_ZERO(env, rectf);
253 SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
254 SkRect tmp;
255 return c->clipRect(*GraphicsJNI::jrectf_to_rect(env, rectf, &tmp));
256 }
257
clipRect_Rect(JNIEnv * env,jobject jcanvas,jobject rect)258 static jboolean clipRect_Rect(JNIEnv* env, jobject jcanvas, jobject rect) {
259 NPE_CHECK_RETURN_ZERO(env, jcanvas);
260 NPE_CHECK_RETURN_ZERO(env, rect);
261 SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
262 SkRect tmp;
263 return c->clipRect(*GraphicsJNI::jrect_to_rect(env, rect, &tmp));
264 }
265
clipRect(JNIEnv * env,jobject,SkCanvas * canvas,float left,float top,float right,float bottom,int op)266 static jboolean clipRect(JNIEnv* env, jobject, SkCanvas* canvas,
267 float left, float top, float right, float bottom,
268 int op) {
269 SkRect rect;
270 rect.set(SkFloatToScalar(left), SkFloatToScalar(top),
271 SkFloatToScalar(right), SkFloatToScalar(bottom));
272 return canvas->clipRect(rect, (SkRegion::Op)op);
273 }
274
clipPath(JNIEnv * env,jobject,SkCanvas * canvas,SkPath * path,int op)275 static jboolean clipPath(JNIEnv* env, jobject, SkCanvas* canvas,
276 SkPath* path, int op) {
277 return canvas->clipPath(*path, (SkRegion::Op)op);
278 }
279
clipRegion(JNIEnv * env,jobject,SkCanvas * canvas,SkRegion * deviceRgn,int op)280 static jboolean clipRegion(JNIEnv* env, jobject, SkCanvas* canvas,
281 SkRegion* deviceRgn, int op) {
282 return canvas->clipRegion(*deviceRgn, (SkRegion::Op)op);
283 }
284
setDrawFilter(JNIEnv * env,jobject,SkCanvas * canvas,SkDrawFilter * filter)285 static void setDrawFilter(JNIEnv* env, jobject, SkCanvas* canvas,
286 SkDrawFilter* filter) {
287 canvas->setDrawFilter(filter);
288 }
289
quickReject__RectFI(JNIEnv * env,jobject,SkCanvas * canvas,jobject rect,int edgetype)290 static jboolean quickReject__RectFI(JNIEnv* env, jobject, SkCanvas* canvas,
291 jobject rect, int edgetype) {
292 SkRect rect_;
293 GraphicsJNI::jrectf_to_rect(env, rect, &rect_);
294 return canvas->quickReject(rect_, (SkCanvas::EdgeType)edgetype);
295 }
296
quickReject__PathI(JNIEnv * env,jobject,SkCanvas * canvas,SkPath * path,int edgetype)297 static jboolean quickReject__PathI(JNIEnv* env, jobject, SkCanvas* canvas,
298 SkPath* path, int edgetype) {
299 return canvas->quickReject(*path, (SkCanvas::EdgeType)edgetype);
300 }
301
quickReject__FFFFI(JNIEnv * env,jobject,SkCanvas * canvas,jfloat left,jfloat top,jfloat right,jfloat bottom,int edgetype)302 static jboolean quickReject__FFFFI(JNIEnv* env, jobject, SkCanvas* canvas,
303 jfloat left, jfloat top, jfloat right,
304 jfloat bottom, int edgetype) {
305 SkRect r;
306 r.set(SkFloatToScalar(left), SkFloatToScalar(top),
307 SkFloatToScalar(right), SkFloatToScalar(bottom));
308 return canvas->quickReject(r, (SkCanvas::EdgeType)edgetype);
309 }
310
drawRGB(JNIEnv * env,jobject,SkCanvas * canvas,jint r,jint g,jint b)311 static void drawRGB(JNIEnv* env, jobject, SkCanvas* canvas,
312 jint r, jint g, jint b) {
313 canvas->drawARGB(0xFF, r, g, b);
314 }
315
drawARGB(JNIEnv * env,jobject,SkCanvas * canvas,jint a,jint r,jint g,jint b)316 static void drawARGB(JNIEnv* env, jobject, SkCanvas* canvas,
317 jint a, jint r, jint g, jint b) {
318 canvas->drawARGB(a, r, g, b);
319 }
320
drawColor__I(JNIEnv * env,jobject,SkCanvas * canvas,jint color)321 static void drawColor__I(JNIEnv* env, jobject, SkCanvas* canvas,
322 jint color) {
323 canvas->drawColor(color);
324 }
325
drawColor__II(JNIEnv * env,jobject,SkCanvas * canvas,jint color,SkPorterDuff::Mode mode)326 static void drawColor__II(JNIEnv* env, jobject, SkCanvas* canvas,
327 jint color, SkPorterDuff::Mode mode) {
328 canvas->drawColor(color, SkPorterDuff::ToXfermodeMode(mode));
329 }
330
drawPaint(JNIEnv * env,jobject,SkCanvas * canvas,SkPaint * paint)331 static void drawPaint(JNIEnv* env, jobject, SkCanvas* canvas,
332 SkPaint* paint) {
333 canvas->drawPaint(*paint);
334 }
335
doPoints(JNIEnv * env,jobject jcanvas,jfloatArray jptsArray,jint offset,jint count,jobject jpaint,SkCanvas::PointMode mode)336 static void doPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
337 jint offset, jint count, jobject jpaint,
338 SkCanvas::PointMode mode) {
339 NPE_CHECK_RETURN_VOID(env, jcanvas);
340 NPE_CHECK_RETURN_VOID(env, jptsArray);
341 NPE_CHECK_RETURN_VOID(env, jpaint);
342 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
343 const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint);
344
345 AutoJavaFloatArray autoPts(env, jptsArray);
346 float* floats = autoPts.ptr();
347 const int length = autoPts.length();
348
349 if ((offset | count) < 0 || offset + count > length) {
350 doThrowAIOOBE(env);
351 return;
352 }
353
354 // now convert the floats into SkPoints
355 count >>= 1; // now it is the number of points
356 SkAutoSTMalloc<32, SkPoint> storage(count);
357 SkPoint* pts = storage.get();
358 const float* src = floats + offset;
359 for (int i = 0; i < count; i++) {
360 pts[i].set(SkFloatToScalar(src[0]), SkFloatToScalar(src[1]));
361 src += 2;
362 }
363 canvas->drawPoints(mode, count, pts, paint);
364 }
365
drawPoints(JNIEnv * env,jobject jcanvas,jfloatArray jptsArray,jint offset,jint count,jobject jpaint)366 static void drawPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
367 jint offset, jint count, jobject jpaint) {
368 doPoints(env, jcanvas, jptsArray, offset, count, jpaint,
369 SkCanvas::kPoints_PointMode);
370 }
371
drawLines(JNIEnv * env,jobject jcanvas,jfloatArray jptsArray,jint offset,jint count,jobject jpaint)372 static void drawLines(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
373 jint offset, jint count, jobject jpaint) {
374 doPoints(env, jcanvas, jptsArray, offset, count, jpaint,
375 SkCanvas::kLines_PointMode);
376 }
377
drawPoint(JNIEnv * env,jobject jcanvas,float x,float y,jobject jpaint)378 static void drawPoint(JNIEnv* env, jobject jcanvas, float x, float y,
379 jobject jpaint) {
380 NPE_CHECK_RETURN_VOID(env, jcanvas);
381 NPE_CHECK_RETURN_VOID(env, jpaint);
382 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
383 const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint);
384
385 canvas->drawPoint(SkFloatToScalar(x), SkFloatToScalar(y), paint);
386 }
387
drawLine__FFFFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jfloat startX,jfloat startY,jfloat stopX,jfloat stopY,SkPaint * paint)388 static void drawLine__FFFFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
389 jfloat startX, jfloat startY, jfloat stopX,
390 jfloat stopY, SkPaint* paint) {
391 canvas->drawLine(SkFloatToScalar(startX), SkFloatToScalar(startY),
392 SkFloatToScalar(stopX), SkFloatToScalar(stopY),
393 *paint);
394 }
395
drawRect__RectFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jobject rect,SkPaint * paint)396 static void drawRect__RectFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
397 jobject rect, SkPaint* paint) {
398 SkRect rect_;
399 GraphicsJNI::jrectf_to_rect(env, rect, &rect_);
400 canvas->drawRect(rect_, *paint);
401 }
402
drawRect__FFFFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jfloat left,jfloat top,jfloat right,jfloat bottom,SkPaint * paint)403 static void drawRect__FFFFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
404 jfloat left, jfloat top, jfloat right,
405 jfloat bottom, SkPaint* paint) {
406 SkScalar left_ = SkFloatToScalar(left);
407 SkScalar top_ = SkFloatToScalar(top);
408 SkScalar right_ = SkFloatToScalar(right);
409 SkScalar bottom_ = SkFloatToScalar(bottom);
410 canvas->drawRectCoords(left_, top_, right_, bottom_, *paint);
411 }
412
drawOval(JNIEnv * env,jobject,SkCanvas * canvas,jobject joval,SkPaint * paint)413 static void drawOval(JNIEnv* env, jobject, SkCanvas* canvas, jobject joval,
414 SkPaint* paint) {
415 SkRect oval;
416 GraphicsJNI::jrectf_to_rect(env, joval, &oval);
417 canvas->drawOval(oval, *paint);
418 }
419
drawCircle(JNIEnv * env,jobject,SkCanvas * canvas,jfloat cx,jfloat cy,jfloat radius,SkPaint * paint)420 static void drawCircle(JNIEnv* env, jobject, SkCanvas* canvas, jfloat cx,
421 jfloat cy, jfloat radius, SkPaint* paint) {
422 canvas->drawCircle(SkFloatToScalar(cx), SkFloatToScalar(cy),
423 SkFloatToScalar(radius), *paint);
424 }
425
drawArc(JNIEnv * env,jobject,SkCanvas * canvas,jobject joval,jfloat startAngle,jfloat sweepAngle,jboolean useCenter,SkPaint * paint)426 static void drawArc(JNIEnv* env, jobject, SkCanvas* canvas, jobject joval,
427 jfloat startAngle, jfloat sweepAngle,
428 jboolean useCenter, SkPaint* paint) {
429 SkRect oval;
430 GraphicsJNI::jrectf_to_rect(env, joval, &oval);
431 canvas->drawArc(oval, SkFloatToScalar(startAngle),
432 SkFloatToScalar(sweepAngle), useCenter, *paint);
433 }
434
drawRoundRect(JNIEnv * env,jobject,SkCanvas * canvas,jobject jrect,jfloat rx,jfloat ry,SkPaint * paint)435 static void drawRoundRect(JNIEnv* env, jobject, SkCanvas* canvas,
436 jobject jrect, jfloat rx, jfloat ry,
437 SkPaint* paint) {
438 SkRect rect;
439 GraphicsJNI::jrectf_to_rect(env, jrect, &rect);
440 canvas->drawRoundRect(rect, SkFloatToScalar(rx), SkFloatToScalar(ry),
441 *paint);
442 }
443
drawPath(JNIEnv * env,jobject,SkCanvas * canvas,SkPath * path,SkPaint * paint)444 static void drawPath(JNIEnv* env, jobject, SkCanvas* canvas, SkPath* path,
445 SkPaint* paint) {
446 canvas->drawPath(*path, *paint);
447 }
448
drawPicture(JNIEnv * env,jobject,SkCanvas * canvas,SkPicture * picture)449 static void drawPicture(JNIEnv* env, jobject, SkCanvas* canvas,
450 SkPicture* picture) {
451 SkASSERT(canvas);
452 SkASSERT(picture);
453
454 #ifdef TIME_DRAW
455 SkMSec now = get_thread_msec(); //SkTime::GetMSecs();
456 #endif
457 canvas->drawPicture(*picture);
458 #ifdef TIME_DRAW
459 LOGD("---- picture playback %d ms\n", get_thread_msec() - now);
460 #endif
461 }
462
drawBitmap__BitmapFFPaint(JNIEnv * env,jobject jcanvas,SkCanvas * canvas,SkBitmap * bitmap,jfloat left,jfloat top,SkPaint * paint,jint canvasDensity,jint screenDensity,jint bitmapDensity)463 static void drawBitmap__BitmapFFPaint(JNIEnv* env, jobject jcanvas,
464 SkCanvas* canvas, SkBitmap* bitmap,
465 jfloat left, jfloat top,
466 SkPaint* paint, jint canvasDensity,
467 jint screenDensity, jint bitmapDensity) {
468 SkScalar left_ = SkFloatToScalar(left);
469 SkScalar top_ = SkFloatToScalar(top);
470
471 if (canvasDensity == bitmapDensity || canvasDensity == 0
472 || bitmapDensity == 0) {
473 if (screenDensity != 0 && screenDensity != bitmapDensity) {
474 SkPaint filteredPaint;
475 if (paint) {
476 filteredPaint = *paint;
477 }
478 filteredPaint.setFilterBitmap(true);
479 canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
480 } else {
481 canvas->drawBitmap(*bitmap, left_, top_, paint);
482 }
483 } else {
484 canvas->save();
485 SkScalar scale = SkFloatToScalar(canvasDensity / (float)bitmapDensity);
486 canvas->translate(left_, top_);
487 canvas->scale(scale, scale);
488
489 SkPaint filteredPaint;
490 if (paint) {
491 filteredPaint = *paint;
492 }
493 filteredPaint.setFilterBitmap(true);
494
495 canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
496
497 canvas->restore();
498 }
499 }
500
doDrawBitmap(JNIEnv * env,SkCanvas * canvas,SkBitmap * bitmap,jobject srcIRect,const SkRect & dst,SkPaint * paint,jint screenDensity,jint bitmapDensity)501 static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap,
502 jobject srcIRect, const SkRect& dst, SkPaint* paint,
503 jint screenDensity, jint bitmapDensity) {
504 SkIRect src, *srcPtr = NULL;
505
506 if (NULL != srcIRect) {
507 GraphicsJNI::jrect_to_irect(env, srcIRect, &src);
508 srcPtr = &src;
509 }
510
511 if (screenDensity != 0 && screenDensity != bitmapDensity) {
512 SkPaint filteredPaint;
513 if (paint) {
514 filteredPaint = *paint;
515 }
516 filteredPaint.setFilterBitmap(true);
517 canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
518 } else {
519 canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
520 }
521 }
522
drawBitmapRF(JNIEnv * env,jobject,SkCanvas * canvas,SkBitmap * bitmap,jobject srcIRect,jobject dstRectF,SkPaint * paint,jint screenDensity,jint bitmapDensity)523 static void drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas,
524 SkBitmap* bitmap, jobject srcIRect,
525 jobject dstRectF, SkPaint* paint,
526 jint screenDensity, jint bitmapDensity) {
527 SkRect dst;
528 GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst);
529 doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
530 screenDensity, bitmapDensity);
531 }
532
drawBitmapRR(JNIEnv * env,jobject,SkCanvas * canvas,SkBitmap * bitmap,jobject srcIRect,jobject dstRect,SkPaint * paint,jint screenDensity,jint bitmapDensity)533 static void drawBitmapRR(JNIEnv* env, jobject, SkCanvas* canvas,
534 SkBitmap* bitmap, jobject srcIRect,
535 jobject dstRect, SkPaint* paint,
536 jint screenDensity, jint bitmapDensity) {
537 SkRect dst;
538 GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
539 doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
540 screenDensity, bitmapDensity);
541 }
542
drawBitmapArray(JNIEnv * env,jobject,SkCanvas * canvas,jintArray jcolors,int offset,int stride,jfloat x,jfloat y,int width,int height,jboolean hasAlpha,SkPaint * paint)543 static void drawBitmapArray(JNIEnv* env, jobject, SkCanvas* canvas,
544 jintArray jcolors, int offset, int stride,
545 jfloat x, jfloat y, int width, int height,
546 jboolean hasAlpha, SkPaint* paint)
547 {
548 SkBitmap bitmap;
549
550 bitmap.setConfig(hasAlpha ? SkBitmap::kARGB_8888_Config :
551 SkBitmap::kRGB_565_Config, width, height);
552 if (!bitmap.allocPixels()) {
553 return;
554 }
555
556 if (!GraphicsJNI::SetPixels(env, jcolors, offset, stride,
557 0, 0, width, height, bitmap)) {
558 return;
559 }
560
561 canvas->drawBitmap(bitmap, SkFloatToScalar(x), SkFloatToScalar(y),
562 paint);
563 }
564
drawBitmapMatrix(JNIEnv * env,jobject,SkCanvas * canvas,const SkBitmap * bitmap,const SkMatrix * matrix,const SkPaint * paint)565 static void drawBitmapMatrix(JNIEnv* env, jobject, SkCanvas* canvas,
566 const SkBitmap* bitmap, const SkMatrix* matrix,
567 const SkPaint* paint) {
568 canvas->drawBitmapMatrix(*bitmap, *matrix, paint);
569 }
570
drawBitmapMesh(JNIEnv * env,jobject,SkCanvas * canvas,const SkBitmap * bitmap,int meshWidth,int meshHeight,jfloatArray jverts,int vertIndex,jintArray jcolors,int colorIndex,const SkPaint * paint)571 static void drawBitmapMesh(JNIEnv* env, jobject, SkCanvas* canvas,
572 const SkBitmap* bitmap, int meshWidth, int meshHeight,
573 jfloatArray jverts, int vertIndex, jintArray jcolors,
574 int colorIndex, const SkPaint* paint) {
575
576 const int ptCount = (meshWidth + 1) * (meshHeight + 1);
577 const int indexCount = meshWidth * meshHeight * 6;
578
579 AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1));
580 AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount);
581
582 /* Our temp storage holds 2 or 3 arrays.
583 texture points [ptCount * sizeof(SkPoint)]
584 optionally vertex points [ptCount * sizeof(SkPoint)] if we need a
585 copy to convert from float to fixed
586 indices [ptCount * sizeof(uint16_t)]
587 */
588 ssize_t storageSize = ptCount * sizeof(SkPoint); // texs[]
589 #ifdef SK_SCALAR_IS_FIXED
590 storageSize += ptCount * sizeof(SkPoint); // storage for verts
591 #endif
592 storageSize += indexCount * sizeof(uint16_t); // indices[]
593
594 SkAutoMalloc storage(storageSize);
595 SkPoint* texs = (SkPoint*)storage.get();
596 SkPoint* verts;
597 uint16_t* indices;
598 #ifdef SK_SCALAR_IS_FLOAT
599 verts = (SkPoint*)(vertA.ptr() + vertIndex);
600 indices = (uint16_t*)(texs + ptCount);
601 #else
602 verts = texs + ptCount;
603 indices = (uint16_t*)(verts + ptCount);
604 // convert floats to fixed
605 {
606 const float* src = vertA.ptr() + vertIndex;
607 for (int i = 0; i < ptCount; i++) {
608 verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
609 src += 2;
610 }
611 }
612 #endif
613
614 // cons up texture coordinates and indices
615 {
616 const SkScalar w = SkIntToScalar(bitmap->width());
617 const SkScalar h = SkIntToScalar(bitmap->height());
618 const SkScalar dx = w / meshWidth;
619 const SkScalar dy = h / meshHeight;
620
621 SkPoint* texsPtr = texs;
622 SkScalar y = 0;
623 for (int i = 0; i <= meshHeight; i++) {
624 if (i == meshHeight) {
625 y = h; // to ensure numerically we hit h exactly
626 }
627 SkScalar x = 0;
628 for (int j = 0; j < meshWidth; j++) {
629 texsPtr->set(x, y);
630 texsPtr += 1;
631 x += dx;
632 }
633 texsPtr->set(w, y);
634 texsPtr += 1;
635 y += dy;
636 }
637 SkASSERT(texsPtr - texs == ptCount);
638 }
639
640 // cons up indices
641 {
642 uint16_t* indexPtr = indices;
643 int index = 0;
644 for (int i = 0; i < meshHeight; i++) {
645 for (int j = 0; j < meshWidth; j++) {
646 // lower-left triangle
647 *indexPtr++ = index;
648 *indexPtr++ = index + meshWidth + 1;
649 *indexPtr++ = index + meshWidth + 2;
650 // upper-right triangle
651 *indexPtr++ = index;
652 *indexPtr++ = index + meshWidth + 2;
653 *indexPtr++ = index + 1;
654 // bump to the next cell
655 index += 1;
656 }
657 // bump to the next row
658 index += 1;
659 }
660 SkASSERT(indexPtr - indices == indexCount);
661 SkASSERT((char*)indexPtr - (char*)storage.get() == storageSize);
662 }
663
664 // double-check that we have legal indices
665 #ifdef SK_DEBUG
666 {
667 for (int i = 0; i < indexCount; i++) {
668 SkASSERT((unsigned)indices[i] < (unsigned)ptCount);
669 }
670 }
671 #endif
672
673 // cons-up a shader for the bitmap
674 SkPaint tmpPaint;
675 if (paint) {
676 tmpPaint = *paint;
677 }
678 SkShader* shader = SkShader::CreateBitmapShader(*bitmap,
679 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
680 tmpPaint.setShader(shader)->safeUnref();
681
682 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, verts,
683 texs, (const SkColor*)colorA.ptr(), NULL, indices,
684 indexCount, tmpPaint);
685 }
686
drawVertices(JNIEnv * env,jobject,SkCanvas * canvas,SkCanvas::VertexMode mode,int vertexCount,jfloatArray jverts,int vertIndex,jfloatArray jtexs,int texIndex,jintArray jcolors,int colorIndex,jshortArray jindices,int indexIndex,int indexCount,const SkPaint * paint)687 static void drawVertices(JNIEnv* env, jobject, SkCanvas* canvas,
688 SkCanvas::VertexMode mode, int vertexCount,
689 jfloatArray jverts, int vertIndex,
690 jfloatArray jtexs, int texIndex,
691 jintArray jcolors, int colorIndex,
692 jshortArray jindices, int indexIndex,
693 int indexCount, const SkPaint* paint) {
694
695 AutoJavaFloatArray vertA(env, jverts, vertIndex + vertexCount);
696 AutoJavaFloatArray texA(env, jtexs, texIndex + vertexCount);
697 AutoJavaIntArray colorA(env, jcolors, colorIndex + vertexCount);
698 AutoJavaShortArray indexA(env, jindices, indexIndex + indexCount);
699
700 const int ptCount = vertexCount >> 1;
701
702 SkPoint* verts;
703 SkPoint* texs = NULL;
704 #ifdef SK_SCALAR_IS_FLOAT
705 verts = (SkPoint*)(vertA.ptr() + vertIndex);
706 if (jtexs != NULL) {
707 texs = (SkPoint*)(texA.ptr() + texIndex);
708 }
709 #else
710 int count = ptCount; // for verts
711 if (jtexs != NULL) {
712 count += ptCount; // += for texs
713 }
714 SkAutoMalloc storage(count * sizeof(SkPoint));
715 verts = (SkPoint*)storage.get();
716 const float* src = vertA.ptr() + vertIndex;
717 for (int i = 0; i < ptCount; i++) {
718 verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
719 src += 2;
720 }
721 if (jtexs != NULL) {
722 texs = verts + ptCount;
723 src = texA.ptr() + texIndex;
724 for (int i = 0; i < ptCount; i++) {
725 texs[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
726 src += 2;
727 }
728 }
729 #endif
730
731 const SkColor* colors = NULL;
732 const uint16_t* indices = NULL;
733 if (jcolors != NULL) {
734 colors = (const SkColor*)(colorA.ptr() + colorIndex);
735 }
736 if (jindices != NULL) {
737 indices = (const uint16_t*)(indexA.ptr() + indexIndex);
738 }
739
740 canvas->drawVertices(mode, ptCount, verts, texs, colors, NULL,
741 indices, indexCount, *paint);
742 }
743
drawText___CIIFFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jcharArray text,int index,int count,jfloat x,jfloat y,SkPaint * paint)744 static void drawText___CIIFFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
745 jcharArray text, int index, int count,
746 jfloat x, jfloat y, SkPaint* paint) {
747 jchar* textArray = env->GetCharArrayElements(text, NULL);
748 jsize textCount = env->GetArrayLength(text);
749 SkScalar x_ = SkFloatToScalar(x);
750 SkScalar y_ = SkFloatToScalar(y);
751 canvas->drawText(textArray + index, count << 1, x_, y_, *paint);
752 env->ReleaseCharArrayElements(text, textArray, 0);
753 }
754
drawText__StringIIFFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jstring text,int start,int end,jfloat x,jfloat y,SkPaint * paint)755 static void drawText__StringIIFFPaint(JNIEnv* env, jobject,
756 SkCanvas* canvas, jstring text, int start, int end,
757 jfloat x, jfloat y, SkPaint* paint) {
758 const void* text_ = env->GetStringChars(text, NULL);
759 SkScalar x_ = SkFloatToScalar(x);
760 SkScalar y_ = SkFloatToScalar(y);
761 canvas->drawText((const uint16_t*)text_ + start, (end - start) << 1,
762 x_, y_, *paint);
763 env->ReleaseStringChars(text, (const jchar*) text_);
764 }
765
drawString(JNIEnv * env,jobject canvas,jstring text,jfloat x,jfloat y,jobject paint)766 static void drawString(JNIEnv* env, jobject canvas, jstring text,
767 jfloat x, jfloat y, jobject paint) {
768 NPE_CHECK_RETURN_VOID(env, canvas);
769 NPE_CHECK_RETURN_VOID(env, paint);
770 NPE_CHECK_RETURN_VOID(env, text);
771 size_t count = env->GetStringLength(text);
772 if (0 == count) {
773 return;
774 }
775 const jchar* text_ = env->GetStringChars(text, NULL);
776 SkCanvas* c = GraphicsJNI::getNativeCanvas(env, canvas);
777 c->drawText(text_, count << 1, SkFloatToScalar(x), SkFloatToScalar(y),
778 *GraphicsJNI::getNativePaint(env, paint));
779 env->ReleaseStringChars(text, text_);
780 }
781
drawPosText___CII_FPaint(JNIEnv * env,jobject,SkCanvas * canvas,jcharArray text,int index,int count,jfloatArray pos,SkPaint * paint)782 static void drawPosText___CII_FPaint(JNIEnv* env, jobject, SkCanvas* canvas,
783 jcharArray text, int index, int count,
784 jfloatArray pos, SkPaint* paint) {
785 jchar* textArray = text ? env->GetCharArrayElements(text, NULL) : NULL;
786 jsize textCount = text ? env->GetArrayLength(text) : NULL;
787 float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
788 int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
789 SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
790 int indx;
791 for (indx = 0; indx < posCount; indx++) {
792 posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]);
793 posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]);
794 }
795 canvas->drawPosText(textArray + index, count << 1, posPtr, *paint);
796 if (text) {
797 env->ReleaseCharArrayElements(text, textArray, 0);
798 }
799 if (pos) {
800 env->ReleaseFloatArrayElements(pos, posArray, 0);
801 }
802 delete[] posPtr;
803 }
804
drawPosText__String_FPaint(JNIEnv * env,jobject,SkCanvas * canvas,jstring text,jfloatArray pos,SkPaint * paint)805 static void drawPosText__String_FPaint(JNIEnv* env, jobject,
806 SkCanvas* canvas, jstring text,
807 jfloatArray pos, SkPaint* paint) {
808 const void* text_ = text ? env->GetStringChars(text, NULL) : NULL;
809 int byteLength = text ? env->GetStringLength(text) : 0;
810 float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
811 int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
812 SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
813
814 for (int indx = 0; indx < posCount; indx++) {
815 posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]);
816 posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]);
817 }
818 canvas->drawPosText(text_, byteLength << 1, posPtr, *paint);
819 if (text) {
820 env->ReleaseStringChars(text, (const jchar*) text_);
821 }
822 if (pos) {
823 env->ReleaseFloatArrayElements(pos, posArray, 0);
824 }
825 delete[] posPtr;
826 }
827
drawTextOnPath___CIIPathFFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jcharArray text,int index,int count,SkPath * path,jfloat hOffset,jfloat vOffset,SkPaint * paint)828 static void drawTextOnPath___CIIPathFFPaint(JNIEnv* env, jobject,
829 SkCanvas* canvas, jcharArray text, int index, int count,
830 SkPath* path, jfloat hOffset, jfloat vOffset, SkPaint* paint) {
831
832 jchar* textArray = env->GetCharArrayElements(text, NULL);
833 canvas->drawTextOnPathHV(textArray + index, count << 1, *path,
834 SkFloatToScalar(hOffset), SkFloatToScalar(vOffset), *paint);
835 env->ReleaseCharArrayElements(text, textArray, 0);
836 }
837
drawTextOnPath__StringPathFFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jstring text,SkPath * path,jfloat hOffset,jfloat vOffset,SkPaint * paint)838 static void drawTextOnPath__StringPathFFPaint(JNIEnv* env, jobject,
839 SkCanvas* canvas, jstring text, SkPath* path,
840 jfloat hOffset, jfloat vOffset, SkPaint* paint) {
841 const jchar* text_ = env->GetStringChars(text, NULL);
842 int byteLength = env->GetStringLength(text) << 1;
843 canvas->drawTextOnPathHV(text_, byteLength, *path,
844 SkFloatToScalar(hOffset), SkFloatToScalar(vOffset), *paint);
845 env->ReleaseStringChars(text, text_);
846 }
847
getClipBounds(JNIEnv * env,jobject,SkCanvas * canvas,jobject bounds)848 static bool getClipBounds(JNIEnv* env, jobject, SkCanvas* canvas,
849 jobject bounds) {
850 SkRect r;
851 SkIRect ir;
852 bool result = canvas->getClipBounds(&r, SkCanvas::kBW_EdgeType);
853
854 r.round(&ir);
855 (void)GraphicsJNI::irect_to_jrect(ir, env, bounds);
856 return result;
857 }
858
getCTM(JNIEnv * env,jobject,SkCanvas * canvas,SkMatrix * matrix)859 static void getCTM(JNIEnv* env, jobject, SkCanvas* canvas,
860 SkMatrix* matrix) {
861 *matrix = canvas->getTotalMatrix();
862 }
863 };
864
865 ///////////////////////////////////////////////////////////////////////////////
866
867 static JNINativeMethod gCanvasMethods[] = {
868 {"finalizer", "(I)V", (void*) SkCanvasGlue::finalizer},
869 {"initRaster","(I)I", (void*) SkCanvasGlue::initRaster},
870 {"initGL","()I", (void*) SkCanvasGlue::initGL},
871 {"isOpaque","()Z", (void*) SkCanvasGlue::isOpaque},
872 {"getWidth","()I", (void*) SkCanvasGlue::getWidth},
873 {"getHeight","()I", (void*) SkCanvasGlue::getHeight},
874 {"native_setBitmap","(II)V", (void*) SkCanvasGlue::setBitmap},
875 {"nativeSetViewport", "(III)V", (void*) SkCanvasGlue::setViewport},
876 {"save","()I", (void*) SkCanvasGlue::saveAll},
877 {"save","(I)I", (void*) SkCanvasGlue::save},
878 {"native_saveLayer","(ILandroid/graphics/RectF;II)I",
879 (void*) SkCanvasGlue::saveLayer},
880 {"native_saveLayer","(IFFFFII)I", (void*) SkCanvasGlue::saveLayer4F},
881 {"native_saveLayerAlpha","(ILandroid/graphics/RectF;II)I",
882 (void*) SkCanvasGlue::saveLayerAlpha},
883 {"native_saveLayerAlpha","(IFFFFII)I",
884 (void*) SkCanvasGlue::saveLayerAlpha4F},
885 {"restore","()V", (void*) SkCanvasGlue::restore},
886 {"getSaveCount","()I", (void*) SkCanvasGlue::getSaveCount},
887 {"restoreToCount","(I)V", (void*) SkCanvasGlue::restoreToCount},
888 {"translate","(FF)V", (void*) SkCanvasGlue::translate},
889 {"scale","(FF)V", (void*) SkCanvasGlue::scale__FF},
890 {"rotate","(F)V", (void*) SkCanvasGlue::rotate__F},
891 {"skew","(FF)V", (void*) SkCanvasGlue::skew__FF},
892 {"native_concat","(II)V", (void*) SkCanvasGlue::concat},
893 {"native_setMatrix","(II)V", (void*) SkCanvasGlue::setMatrix},
894 {"clipRect","(FFFF)Z", (void*) SkCanvasGlue::clipRect_FFFF},
895 {"clipRect","(IIII)Z", (void*) SkCanvasGlue::clipRect_IIII},
896 {"clipRect","(Landroid/graphics/RectF;)Z",
897 (void*) SkCanvasGlue::clipRect_RectF},
898 {"clipRect","(Landroid/graphics/Rect;)Z",
899 (void*) SkCanvasGlue::clipRect_Rect},
900 {"native_clipRect","(IFFFFI)Z", (void*) SkCanvasGlue::clipRect},
901 {"native_clipPath","(III)Z", (void*) SkCanvasGlue::clipPath},
902 {"native_clipRegion","(III)Z", (void*) SkCanvasGlue::clipRegion},
903 {"nativeSetDrawFilter", "(II)V", (void*) SkCanvasGlue::setDrawFilter},
904 {"native_getClipBounds","(ILandroid/graphics/Rect;)Z",
905 (void*) SkCanvasGlue::getClipBounds},
906 {"native_getCTM", "(II)V", (void*)SkCanvasGlue::getCTM},
907 {"native_quickReject","(ILandroid/graphics/RectF;I)Z",
908 (void*) SkCanvasGlue::quickReject__RectFI},
909 {"native_quickReject","(III)Z", (void*) SkCanvasGlue::quickReject__PathI},
910 {"native_quickReject","(IFFFFI)Z", (void*)SkCanvasGlue::quickReject__FFFFI},
911 {"native_drawRGB","(IIII)V", (void*) SkCanvasGlue::drawRGB},
912 {"native_drawARGB","(IIIII)V", (void*) SkCanvasGlue::drawARGB},
913 {"native_drawColor","(II)V", (void*) SkCanvasGlue::drawColor__I},
914 {"native_drawColor","(III)V", (void*) SkCanvasGlue::drawColor__II},
915 {"native_drawPaint","(II)V", (void*) SkCanvasGlue::drawPaint},
916 {"drawPoint", "(FFLandroid/graphics/Paint;)V",
917 (void*) SkCanvasGlue::drawPoint},
918 {"drawPoints", "([FIILandroid/graphics/Paint;)V",
919 (void*) SkCanvasGlue::drawPoints},
920 {"drawLines", "([FIILandroid/graphics/Paint;)V",
921 (void*) SkCanvasGlue::drawLines},
922 {"native_drawLine","(IFFFFI)V", (void*) SkCanvasGlue::drawLine__FFFFPaint},
923 {"native_drawRect","(ILandroid/graphics/RectF;I)V",
924 (void*) SkCanvasGlue::drawRect__RectFPaint},
925 {"native_drawRect","(IFFFFI)V", (void*) SkCanvasGlue::drawRect__FFFFPaint},
926 {"native_drawOval","(ILandroid/graphics/RectF;I)V",
927 (void*) SkCanvasGlue::drawOval},
928 {"native_drawCircle","(IFFFI)V", (void*) SkCanvasGlue::drawCircle},
929 {"native_drawArc","(ILandroid/graphics/RectF;FFZI)V",
930 (void*) SkCanvasGlue::drawArc},
931 {"native_drawRoundRect","(ILandroid/graphics/RectF;FFI)V",
932 (void*) SkCanvasGlue::drawRoundRect},
933 {"native_drawPath","(III)V", (void*) SkCanvasGlue::drawPath},
934 {"native_drawBitmap","(IIFFIIII)V",
935 (void*) SkCanvasGlue::drawBitmap__BitmapFFPaint},
936 {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;III)V",
937 (void*) SkCanvasGlue::drawBitmapRF},
938 {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;III)V",
939 (void*) SkCanvasGlue::drawBitmapRR},
940 {"native_drawBitmap", "(I[IIIFFIIZI)V",
941 (void*)SkCanvasGlue::drawBitmapArray},
942
943 {"nativeDrawBitmapMatrix", "(IIII)V",
944 (void*)SkCanvasGlue::drawBitmapMatrix},
945 {"nativeDrawBitmapMesh", "(IIII[FI[III)V",
946 (void*)SkCanvasGlue::drawBitmapMesh},
947 {"nativeDrawVertices", "(III[FI[FI[II[SIII)V",
948 (void*)SkCanvasGlue::drawVertices},
949 {"native_drawText","(I[CIIFFI)V",
950 (void*) SkCanvasGlue::drawText___CIIFFPaint},
951 {"native_drawText","(ILjava/lang/String;IIFFI)V",
952 (void*) SkCanvasGlue::drawText__StringIIFFPaint},
953 {"drawText","(Ljava/lang/String;FFLandroid/graphics/Paint;)V",
954 (void*) SkCanvasGlue::drawString},
955 {"native_drawPosText","(I[CII[FI)V",
956 (void*) SkCanvasGlue::drawPosText___CII_FPaint},
957 {"native_drawPosText","(ILjava/lang/String;[FI)V",
958 (void*) SkCanvasGlue::drawPosText__String_FPaint},
959 {"native_drawTextOnPath","(I[CIIIFFI)V",
960 (void*) SkCanvasGlue::drawTextOnPath___CIIPathFFPaint},
961 {"native_drawTextOnPath","(ILjava/lang/String;IFFI)V",
962 (void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint},
963 {"native_drawPicture", "(II)V", (void*) SkCanvasGlue::drawPicture},
964
965 {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches}
966 };
967
968 #include <android_runtime/AndroidRuntime.h>
969
970 #define REG(env, name, array) \
971 result = android::AndroidRuntime::registerNativeMethods(env, name, array, \
972 SK_ARRAY_COUNT(array)); \
973 if (result < 0) return result
974
register_android_graphics_Canvas(JNIEnv * env)975 int register_android_graphics_Canvas(JNIEnv* env) {
976 int result;
977
978 REG(env, "android/graphics/Canvas", gCanvasMethods);
979
980 return result;
981 }
982
983 }
984