blob: feba1e652bc84da60d0506ba37623b22df720830 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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"
Mike Reedcaf0df12009-04-27 14:32:05 -040023#include "SkGraphics.h"
24#include "SkImageRef_GlobalPool.h"
Mike Reed47c0d4e2009-06-22 22:53:52 -040025#include "SkPorterDuff.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026#include "SkShader.h"
27#include "SkTemplates.h"
28
Doug Feltf7cb1f72010-07-01 16:20:43 -070029#include "TextLayout.h"
Fabrice Di Megliofcf2be12011-04-05 17:02:36 -070030#include "TextLayoutCache.h"
Doug Feltf7cb1f72010-07-01 16:20:43 -070031
Doug Feltf47d7402010-04-21 16:01:52 -070032#include "unicode/ubidi.h"
Doug Felt0c702b82010-05-14 10:55:42 -070033#include "unicode/ushape.h"
34
Doug Felt0c702b82010-05-14 10:55:42 -070035#include <utils/Log.h>
Doug Feltf47d7402010-04-21 16:01:52 -070036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037#define TIME_DRAWx
38
39static uint32_t get_thread_msec() {
40#if defined(HAVE_POSIX_CLOCKS)
41 struct timespec tm;
42
43 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm);
44
45 return tm.tv_sec * 1000LL + tm.tv_nsec / 1000000;
46#else
47 struct timeval tv;
48
49 gettimeofday(&tv, NULL);
50 return tv.tv_sec * 1000LL + tv.tv_usec / 1000;
51#endif
52}
53
54namespace android {
55
56class SkCanvasGlue {
57public:
58
59 static void finalizer(JNIEnv* env, jobject clazz, SkCanvas* canvas) {
60 canvas->unref();
61 }
62
63 static SkCanvas* initRaster(JNIEnv* env, jobject, SkBitmap* bitmap) {
64 return bitmap ? new SkCanvas(*bitmap) : new SkCanvas;
65 }
66
Mike Reedcaf0df12009-04-27 14:32:05 -040067 static void freeCaches(JNIEnv* env, jobject) {
68 // these are called in no particular order
Mike Reedcaf0df12009-04-27 14:32:05 -040069 SkImageRef_GlobalPool::SetRAMUsed(0);
70 SkGraphics::SetFontCacheUsed(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 }
72
73 static jboolean isOpaque(JNIEnv* env, jobject jcanvas) {
74 NPE_CHECK_RETURN_ZERO(env, jcanvas);
75 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 return canvas->getDevice()->accessBitmap(false).isOpaque();
77 }
78
79 static int getWidth(JNIEnv* env, jobject jcanvas) {
80 NPE_CHECK_RETURN_ZERO(env, jcanvas);
81 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
82 return canvas->getDevice()->accessBitmap(false).width();
83 }
84
85 static int getHeight(JNIEnv* env, jobject jcanvas) {
86 NPE_CHECK_RETURN_ZERO(env, jcanvas);
87 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
88 return canvas->getDevice()->accessBitmap(false).height();
89 }
90
Romain Guy0965a322011-08-01 17:39:21 -070091 static void setBitmap(JNIEnv* env, jobject, SkCanvas* canvas, SkBitmap* bitmap) {
92 if (bitmap) {
93 canvas->setBitmapDevice(*bitmap);
94 } else {
95 canvas->setDevice(NULL);
96 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 }
98
99 static int saveAll(JNIEnv* env, jobject jcanvas) {
100 NPE_CHECK_RETURN_ZERO(env, jcanvas);
101 return GraphicsJNI::getNativeCanvas(env, jcanvas)->save();
102 }
103
104 static int save(JNIEnv* env, jobject jcanvas, SkCanvas::SaveFlags flags) {
105 NPE_CHECK_RETURN_ZERO(env, jcanvas);
106 return GraphicsJNI::getNativeCanvas(env, jcanvas)->save(flags);
107 }
108
109 static int saveLayer(JNIEnv* env, jobject, SkCanvas* canvas, jobject bounds,
110 SkPaint* paint, int flags) {
111 SkRect* bounds_ = NULL;
112 SkRect storage;
113 if (bounds != NULL) {
114 GraphicsJNI::jrectf_to_rect(env, bounds, &storage);
115 bounds_ = &storage;
116 }
117 return canvas->saveLayer(bounds_, paint, (SkCanvas::SaveFlags)flags);
118 }
119
120 static int saveLayer4F(JNIEnv* env, jobject, SkCanvas* canvas,
121 jfloat l, jfloat t, jfloat r, jfloat b,
122 SkPaint* paint, int flags) {
123 SkRect bounds;
124 bounds.set(SkFloatToScalar(l), SkFloatToScalar(t), SkFloatToScalar(r),
125 SkFloatToScalar(b));
126 return canvas->saveLayer(&bounds, paint, (SkCanvas::SaveFlags)flags);
127 }
128
129 static int saveLayerAlpha(JNIEnv* env, jobject, SkCanvas* canvas,
130 jobject bounds, int alpha, int flags) {
131 SkRect* bounds_ = NULL;
132 SkRect storage;
133 if (bounds != NULL) {
134 GraphicsJNI::jrectf_to_rect(env, bounds, &storage);
135 bounds_ = &storage;
136 }
137 return canvas->saveLayerAlpha(bounds_, alpha,
138 (SkCanvas::SaveFlags)flags);
139 }
140
141 static int saveLayerAlpha4F(JNIEnv* env, jobject, SkCanvas* canvas,
142 jfloat l, jfloat t, jfloat r, jfloat b,
143 int alpha, int flags) {
144 SkRect bounds;
145 bounds.set(SkFloatToScalar(l), SkFloatToScalar(t), SkFloatToScalar(r),
146 SkFloatToScalar(b));
147 return canvas->saveLayerAlpha(&bounds, alpha,
148 (SkCanvas::SaveFlags)flags);
149 }
150
151 static void restore(JNIEnv* env, jobject jcanvas) {
152 NPE_CHECK_RETURN_VOID(env, jcanvas);
153 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
154 if (canvas->getSaveCount() <= 1) { // cannot restore anymore
155 doThrowISE(env, "Underflow in restore");
156 return;
157 }
158 canvas->restore();
159 }
160
161 static int getSaveCount(JNIEnv* env, jobject jcanvas) {
162 NPE_CHECK_RETURN_ZERO(env, jcanvas);
163 return GraphicsJNI::getNativeCanvas(env, jcanvas)->getSaveCount();
164 }
165
166 static void restoreToCount(JNIEnv* env, jobject jcanvas, int restoreCount) {
167 NPE_CHECK_RETURN_VOID(env, jcanvas);
168 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
169 if (restoreCount < 1) {
170 doThrowIAE(env, "Underflow in restoreToCount");
171 return;
172 }
173 canvas->restoreToCount(restoreCount);
174 }
175
176 static void translate(JNIEnv* env, jobject jcanvas, jfloat dx, jfloat dy) {
177 NPE_CHECK_RETURN_VOID(env, jcanvas);
178 SkScalar dx_ = SkFloatToScalar(dx);
179 SkScalar dy_ = SkFloatToScalar(dy);
180 (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->translate(dx_, dy_);
181 }
182
183 static void scale__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) {
184 NPE_CHECK_RETURN_VOID(env, jcanvas);
185 SkScalar sx_ = SkFloatToScalar(sx);
186 SkScalar sy_ = SkFloatToScalar(sy);
187 (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->scale(sx_, sy_);
188 }
189
190 static void rotate__F(JNIEnv* env, jobject jcanvas, jfloat degrees) {
191 NPE_CHECK_RETURN_VOID(env, jcanvas);
192 SkScalar degrees_ = SkFloatToScalar(degrees);
193 (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->rotate(degrees_);
194 }
195
196 static void skew__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) {
197 NPE_CHECK_RETURN_VOID(env, jcanvas);
198 SkScalar sx_ = SkFloatToScalar(sx);
199 SkScalar sy_ = SkFloatToScalar(sy);
200 (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->skew(sx_, sy_);
201 }
202
203 static void concat(JNIEnv* env, jobject, SkCanvas* canvas,
204 const SkMatrix* matrix) {
205 canvas->concat(*matrix);
206 }
207
208 static void setMatrix(JNIEnv* env, jobject, SkCanvas* canvas,
209 const SkMatrix* matrix) {
210 if (NULL == matrix) {
211 canvas->resetMatrix();
212 } else {
213 canvas->setMatrix(*matrix);
214 }
215 }
216
217 static jboolean clipRect_FFFF(JNIEnv* env, jobject jcanvas, jfloat left,
218 jfloat top, jfloat right, jfloat bottom) {
219 NPE_CHECK_RETURN_ZERO(env, jcanvas);
220 SkRect r;
221 r.set(SkFloatToScalar(left), SkFloatToScalar(top),
222 SkFloatToScalar(right), SkFloatToScalar(bottom));
223 SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
224 return c->clipRect(r);
225 }
226
227 static jboolean clipRect_IIII(JNIEnv* env, jobject jcanvas, jint left,
228 jint top, jint right, jint bottom) {
229 NPE_CHECK_RETURN_ZERO(env, jcanvas);
230 SkRect r;
231 r.set(SkIntToScalar(left), SkIntToScalar(top),
232 SkIntToScalar(right), SkIntToScalar(bottom));
233 return GraphicsJNI::getNativeCanvas(env, jcanvas)->clipRect(r);
234 }
235
236 static jboolean clipRect_RectF(JNIEnv* env, jobject jcanvas, jobject rectf) {
237 NPE_CHECK_RETURN_ZERO(env, jcanvas);
238 NPE_CHECK_RETURN_ZERO(env, rectf);
239 SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
240 SkRect tmp;
241 return c->clipRect(*GraphicsJNI::jrectf_to_rect(env, rectf, &tmp));
242 }
243
244 static jboolean clipRect_Rect(JNIEnv* env, jobject jcanvas, jobject rect) {
245 NPE_CHECK_RETURN_ZERO(env, jcanvas);
246 NPE_CHECK_RETURN_ZERO(env, rect);
247 SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
248 SkRect tmp;
249 return c->clipRect(*GraphicsJNI::jrect_to_rect(env, rect, &tmp));
250 }
251
252 static jboolean clipRect(JNIEnv* env, jobject, SkCanvas* canvas,
253 float left, float top, float right, float bottom,
254 int op) {
255 SkRect rect;
256 rect.set(SkFloatToScalar(left), SkFloatToScalar(top),
257 SkFloatToScalar(right), SkFloatToScalar(bottom));
258 return canvas->clipRect(rect, (SkRegion::Op)op);
259 }
260
261 static jboolean clipPath(JNIEnv* env, jobject, SkCanvas* canvas,
262 SkPath* path, int op) {
263 return canvas->clipPath(*path, (SkRegion::Op)op);
264 }
265
266 static jboolean clipRegion(JNIEnv* env, jobject, SkCanvas* canvas,
267 SkRegion* deviceRgn, int op) {
268 return canvas->clipRegion(*deviceRgn, (SkRegion::Op)op);
269 }
270
271 static void setDrawFilter(JNIEnv* env, jobject, SkCanvas* canvas,
272 SkDrawFilter* filter) {
273 canvas->setDrawFilter(filter);
274 }
275
276 static jboolean quickReject__RectFI(JNIEnv* env, jobject, SkCanvas* canvas,
277 jobject rect, int edgetype) {
278 SkRect rect_;
279 GraphicsJNI::jrectf_to_rect(env, rect, &rect_);
280 return canvas->quickReject(rect_, (SkCanvas::EdgeType)edgetype);
281 }
282
283 static jboolean quickReject__PathI(JNIEnv* env, jobject, SkCanvas* canvas,
284 SkPath* path, int edgetype) {
285 return canvas->quickReject(*path, (SkCanvas::EdgeType)edgetype);
286 }
287
288 static jboolean quickReject__FFFFI(JNIEnv* env, jobject, SkCanvas* canvas,
289 jfloat left, jfloat top, jfloat right,
290 jfloat bottom, int edgetype) {
291 SkRect r;
292 r.set(SkFloatToScalar(left), SkFloatToScalar(top),
293 SkFloatToScalar(right), SkFloatToScalar(bottom));
294 return canvas->quickReject(r, (SkCanvas::EdgeType)edgetype);
295 }
296
297 static void drawRGB(JNIEnv* env, jobject, SkCanvas* canvas,
298 jint r, jint g, jint b) {
299 canvas->drawARGB(0xFF, r, g, b);
300 }
301
302 static void drawARGB(JNIEnv* env, jobject, SkCanvas* canvas,
303 jint a, jint r, jint g, jint b) {
304 canvas->drawARGB(a, r, g, b);
305 }
306
307 static void drawColor__I(JNIEnv* env, jobject, SkCanvas* canvas,
308 jint color) {
309 canvas->drawColor(color);
310 }
311
312 static void drawColor__II(JNIEnv* env, jobject, SkCanvas* canvas,
313 jint color, SkPorterDuff::Mode mode) {
Mike Reed47c0d4e2009-06-22 22:53:52 -0400314 canvas->drawColor(color, SkPorterDuff::ToXfermodeMode(mode));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 }
316
317 static void drawPaint(JNIEnv* env, jobject, SkCanvas* canvas,
318 SkPaint* paint) {
319 canvas->drawPaint(*paint);
320 }
321
322 static void doPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
323 jint offset, jint count, jobject jpaint,
324 SkCanvas::PointMode mode) {
325 NPE_CHECK_RETURN_VOID(env, jcanvas);
326 NPE_CHECK_RETURN_VOID(env, jptsArray);
327 NPE_CHECK_RETURN_VOID(env, jpaint);
328 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
329 const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint);
330
331 AutoJavaFloatArray autoPts(env, jptsArray);
332 float* floats = autoPts.ptr();
333 const int length = autoPts.length();
334
335 if ((offset | count) < 0 || offset + count > length) {
336 doThrowAIOOBE(env);
337 return;
338 }
339
340 // now convert the floats into SkPoints
341 count >>= 1; // now it is the number of points
342 SkAutoSTMalloc<32, SkPoint> storage(count);
343 SkPoint* pts = storage.get();
344 const float* src = floats + offset;
345 for (int i = 0; i < count; i++) {
346 pts[i].set(SkFloatToScalar(src[0]), SkFloatToScalar(src[1]));
347 src += 2;
348 }
349 canvas->drawPoints(mode, count, pts, paint);
350 }
351
352 static void drawPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
353 jint offset, jint count, jobject jpaint) {
354 doPoints(env, jcanvas, jptsArray, offset, count, jpaint,
355 SkCanvas::kPoints_PointMode);
356 }
357
358 static void drawLines(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
359 jint offset, jint count, jobject jpaint) {
360 doPoints(env, jcanvas, jptsArray, offset, count, jpaint,
361 SkCanvas::kLines_PointMode);
362 }
363
364 static void drawPoint(JNIEnv* env, jobject jcanvas, float x, float y,
365 jobject jpaint) {
366 NPE_CHECK_RETURN_VOID(env, jcanvas);
367 NPE_CHECK_RETURN_VOID(env, jpaint);
368 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
369 const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint);
370
371 canvas->drawPoint(SkFloatToScalar(x), SkFloatToScalar(y), paint);
372 }
373
374 static void drawLine__FFFFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
375 jfloat startX, jfloat startY, jfloat stopX,
376 jfloat stopY, SkPaint* paint) {
377 canvas->drawLine(SkFloatToScalar(startX), SkFloatToScalar(startY),
378 SkFloatToScalar(stopX), SkFloatToScalar(stopY),
379 *paint);
380 }
381
382 static void drawRect__RectFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
383 jobject rect, SkPaint* paint) {
384 SkRect rect_;
385 GraphicsJNI::jrectf_to_rect(env, rect, &rect_);
386 canvas->drawRect(rect_, *paint);
387 }
388
389 static void drawRect__FFFFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
390 jfloat left, jfloat top, jfloat right,
391 jfloat bottom, SkPaint* paint) {
392 SkScalar left_ = SkFloatToScalar(left);
393 SkScalar top_ = SkFloatToScalar(top);
394 SkScalar right_ = SkFloatToScalar(right);
395 SkScalar bottom_ = SkFloatToScalar(bottom);
396 canvas->drawRectCoords(left_, top_, right_, bottom_, *paint);
397 }
398
399 static void drawOval(JNIEnv* env, jobject, SkCanvas* canvas, jobject joval,
400 SkPaint* paint) {
401 SkRect oval;
402 GraphicsJNI::jrectf_to_rect(env, joval, &oval);
403 canvas->drawOval(oval, *paint);
404 }
405
406 static void drawCircle(JNIEnv* env, jobject, SkCanvas* canvas, jfloat cx,
407 jfloat cy, jfloat radius, SkPaint* paint) {
408 canvas->drawCircle(SkFloatToScalar(cx), SkFloatToScalar(cy),
409 SkFloatToScalar(radius), *paint);
410 }
411
412 static void drawArc(JNIEnv* env, jobject, SkCanvas* canvas, jobject joval,
413 jfloat startAngle, jfloat sweepAngle,
414 jboolean useCenter, SkPaint* paint) {
415 SkRect oval;
416 GraphicsJNI::jrectf_to_rect(env, joval, &oval);
417 canvas->drawArc(oval, SkFloatToScalar(startAngle),
418 SkFloatToScalar(sweepAngle), useCenter, *paint);
419 }
420
421 static void drawRoundRect(JNIEnv* env, jobject, SkCanvas* canvas,
422 jobject jrect, jfloat rx, jfloat ry,
423 SkPaint* paint) {
424 SkRect rect;
425 GraphicsJNI::jrectf_to_rect(env, jrect, &rect);
426 canvas->drawRoundRect(rect, SkFloatToScalar(rx), SkFloatToScalar(ry),
427 *paint);
428 }
429
430 static void drawPath(JNIEnv* env, jobject, SkCanvas* canvas, SkPath* path,
431 SkPaint* paint) {
432 canvas->drawPath(*path, *paint);
433 }
434
435 static void drawPicture(JNIEnv* env, jobject, SkCanvas* canvas,
436 SkPicture* picture) {
437 SkASSERT(canvas);
438 SkASSERT(picture);
439
440#ifdef TIME_DRAW
441 SkMSec now = get_thread_msec(); //SkTime::GetMSecs();
442#endif
443 canvas->drawPicture(*picture);
444#ifdef TIME_DRAW
445 LOGD("---- picture playback %d ms\n", get_thread_msec() - now);
446#endif
447 }
448
449 static void drawBitmap__BitmapFFPaint(JNIEnv* env, jobject jcanvas,
450 SkCanvas* canvas, SkBitmap* bitmap,
451 jfloat left, jfloat top,
Dianne Hackborn11ea3342009-07-22 21:48:55 -0700452 SkPaint* paint, jint canvasDensity,
Dianne Hackborn0d221012009-07-29 15:41:19 -0700453 jint screenDensity, jint bitmapDensity) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 SkScalar left_ = SkFloatToScalar(left);
455 SkScalar top_ = SkFloatToScalar(top);
456
Dianne Hackborn11ea3342009-07-22 21:48:55 -0700457 if (canvasDensity == bitmapDensity || canvasDensity == 0
458 || bitmapDensity == 0) {
Dianne Hackborn0d221012009-07-29 15:41:19 -0700459 if (screenDensity != 0 && screenDensity != bitmapDensity) {
460 SkPaint filteredPaint;
461 if (paint) {
462 filteredPaint = *paint;
463 }
464 filteredPaint.setFilterBitmap(true);
465 canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
466 } else {
467 canvas->drawBitmap(*bitmap, left_, top_, paint);
468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 } else {
470 canvas->save();
Dianne Hackborn11ea3342009-07-22 21:48:55 -0700471 SkScalar scale = SkFloatToScalar(canvasDensity / (float)bitmapDensity);
472 canvas->translate(left_, top_);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 canvas->scale(scale, scale);
474
475 SkPaint filteredPaint;
476 if (paint) {
477 filteredPaint = *paint;
478 }
479 filteredPaint.setFilterBitmap(true);
480
Dianne Hackborn11ea3342009-07-22 21:48:55 -0700481 canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482
483 canvas->restore();
484 }
485 }
486
487 static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap,
Dianne Hackborn0d221012009-07-29 15:41:19 -0700488 jobject srcIRect, const SkRect& dst, SkPaint* paint,
489 jint screenDensity, jint bitmapDensity) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 SkIRect src, *srcPtr = NULL;
491
492 if (NULL != srcIRect) {
493 GraphicsJNI::jrect_to_irect(env, srcIRect, &src);
494 srcPtr = &src;
495 }
Dianne Hackborn0d221012009-07-29 15:41:19 -0700496
497 if (screenDensity != 0 && screenDensity != bitmapDensity) {
498 SkPaint filteredPaint;
499 if (paint) {
500 filteredPaint = *paint;
501 }
502 filteredPaint.setFilterBitmap(true);
503 canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
504 } else {
505 canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 }
508
509 static void drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas,
510 SkBitmap* bitmap, jobject srcIRect,
Dianne Hackborn0d221012009-07-29 15:41:19 -0700511 jobject dstRectF, SkPaint* paint,
512 jint screenDensity, jint bitmapDensity) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 SkRect dst;
514 GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst);
Dianne Hackborn0d221012009-07-29 15:41:19 -0700515 doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
516 screenDensity, bitmapDensity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 }
518
519 static void drawBitmapRR(JNIEnv* env, jobject, SkCanvas* canvas,
520 SkBitmap* bitmap, jobject srcIRect,
Dianne Hackborn0d221012009-07-29 15:41:19 -0700521 jobject dstRect, SkPaint* paint,
522 jint screenDensity, jint bitmapDensity) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 SkRect dst;
524 GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
Dianne Hackborn0d221012009-07-29 15:41:19 -0700525 doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
526 screenDensity, bitmapDensity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 }
528
529 static void drawBitmapArray(JNIEnv* env, jobject, SkCanvas* canvas,
530 jintArray jcolors, int offset, int stride,
531 jfloat x, jfloat y, int width, int height,
532 jboolean hasAlpha, SkPaint* paint)
533 {
534 SkBitmap bitmap;
535
536 bitmap.setConfig(hasAlpha ? SkBitmap::kARGB_8888_Config :
537 SkBitmap::kRGB_565_Config, width, height);
538 if (!bitmap.allocPixels()) {
539 return;
540 }
541
542 if (!GraphicsJNI::SetPixels(env, jcolors, offset, stride,
543 0, 0, width, height, bitmap)) {
544 return;
545 }
546
547 canvas->drawBitmap(bitmap, SkFloatToScalar(x), SkFloatToScalar(y),
548 paint);
549 }
550
551 static void drawBitmapMatrix(JNIEnv* env, jobject, SkCanvas* canvas,
552 const SkBitmap* bitmap, const SkMatrix* matrix,
553 const SkPaint* paint) {
554 canvas->drawBitmapMatrix(*bitmap, *matrix, paint);
555 }
556
557 static void drawBitmapMesh(JNIEnv* env, jobject, SkCanvas* canvas,
558 const SkBitmap* bitmap, int meshWidth, int meshHeight,
559 jfloatArray jverts, int vertIndex, jintArray jcolors,
560 int colorIndex, const SkPaint* paint) {
561
562 const int ptCount = (meshWidth + 1) * (meshHeight + 1);
563 const int indexCount = meshWidth * meshHeight * 6;
564
565 AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1));
566 AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount);
567
568 /* Our temp storage holds 2 or 3 arrays.
569 texture points [ptCount * sizeof(SkPoint)]
570 optionally vertex points [ptCount * sizeof(SkPoint)] if we need a
571 copy to convert from float to fixed
572 indices [ptCount * sizeof(uint16_t)]
573 */
574 ssize_t storageSize = ptCount * sizeof(SkPoint); // texs[]
575#ifdef SK_SCALAR_IS_FIXED
576 storageSize += ptCount * sizeof(SkPoint); // storage for verts
577#endif
578 storageSize += indexCount * sizeof(uint16_t); // indices[]
579
580 SkAutoMalloc storage(storageSize);
581 SkPoint* texs = (SkPoint*)storage.get();
582 SkPoint* verts;
583 uint16_t* indices;
584#ifdef SK_SCALAR_IS_FLOAT
585 verts = (SkPoint*)(vertA.ptr() + vertIndex);
586 indices = (uint16_t*)(texs + ptCount);
587#else
588 verts = texs + ptCount;
589 indices = (uint16_t*)(verts + ptCount);
590 // convert floats to fixed
591 {
592 const float* src = vertA.ptr() + vertIndex;
593 for (int i = 0; i < ptCount; i++) {
594 verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
595 src += 2;
596 }
597 }
598#endif
599
600 // cons up texture coordinates and indices
601 {
602 const SkScalar w = SkIntToScalar(bitmap->width());
603 const SkScalar h = SkIntToScalar(bitmap->height());
604 const SkScalar dx = w / meshWidth;
605 const SkScalar dy = h / meshHeight;
606
607 SkPoint* texsPtr = texs;
608 SkScalar y = 0;
609 for (int i = 0; i <= meshHeight; i++) {
610 if (i == meshHeight) {
611 y = h; // to ensure numerically we hit h exactly
612 }
613 SkScalar x = 0;
614 for (int j = 0; j < meshWidth; j++) {
615 texsPtr->set(x, y);
616 texsPtr += 1;
617 x += dx;
618 }
619 texsPtr->set(w, y);
620 texsPtr += 1;
621 y += dy;
622 }
623 SkASSERT(texsPtr - texs == ptCount);
624 }
625
626 // cons up indices
627 {
628 uint16_t* indexPtr = indices;
629 int index = 0;
630 for (int i = 0; i < meshHeight; i++) {
631 for (int j = 0; j < meshWidth; j++) {
632 // lower-left triangle
633 *indexPtr++ = index;
634 *indexPtr++ = index + meshWidth + 1;
635 *indexPtr++ = index + meshWidth + 2;
636 // upper-right triangle
637 *indexPtr++ = index;
638 *indexPtr++ = index + meshWidth + 2;
639 *indexPtr++ = index + 1;
640 // bump to the next cell
641 index += 1;
642 }
643 // bump to the next row
644 index += 1;
645 }
646 SkASSERT(indexPtr - indices == indexCount);
647 SkASSERT((char*)indexPtr - (char*)storage.get() == storageSize);
648 }
649
650 // double-check that we have legal indices
651#ifdef SK_DEBUG
652 {
653 for (int i = 0; i < indexCount; i++) {
654 SkASSERT((unsigned)indices[i] < (unsigned)ptCount);
655 }
656 }
657#endif
658
659 // cons-up a shader for the bitmap
660 SkPaint tmpPaint;
661 if (paint) {
662 tmpPaint = *paint;
663 }
664 SkShader* shader = SkShader::CreateBitmapShader(*bitmap,
665 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
Derek Sollenberger6062c592011-02-22 13:55:04 -0500666 SkSafeUnref(tmpPaint.setShader(shader));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667
668 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, verts,
669 texs, (const SkColor*)colorA.ptr(), NULL, indices,
670 indexCount, tmpPaint);
671 }
672
673 static void drawVertices(JNIEnv* env, jobject, SkCanvas* canvas,
674 SkCanvas::VertexMode mode, int vertexCount,
675 jfloatArray jverts, int vertIndex,
676 jfloatArray jtexs, int texIndex,
677 jintArray jcolors, int colorIndex,
678 jshortArray jindices, int indexIndex,
679 int indexCount, const SkPaint* paint) {
680
681 AutoJavaFloatArray vertA(env, jverts, vertIndex + vertexCount);
682 AutoJavaFloatArray texA(env, jtexs, texIndex + vertexCount);
683 AutoJavaIntArray colorA(env, jcolors, colorIndex + vertexCount);
684 AutoJavaShortArray indexA(env, jindices, indexIndex + indexCount);
685
686 const int ptCount = vertexCount >> 1;
687
688 SkPoint* verts;
689 SkPoint* texs = NULL;
690#ifdef SK_SCALAR_IS_FLOAT
691 verts = (SkPoint*)(vertA.ptr() + vertIndex);
692 if (jtexs != NULL) {
693 texs = (SkPoint*)(texA.ptr() + texIndex);
694 }
695#else
696 int count = ptCount; // for verts
697 if (jtexs != NULL) {
698 count += ptCount; // += for texs
699 }
700 SkAutoMalloc storage(count * sizeof(SkPoint));
701 verts = (SkPoint*)storage.get();
702 const float* src = vertA.ptr() + vertIndex;
703 for (int i = 0; i < ptCount; i++) {
704 verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
705 src += 2;
706 }
707 if (jtexs != NULL) {
708 texs = verts + ptCount;
709 src = texA.ptr() + texIndex;
710 for (int i = 0; i < ptCount; i++) {
711 texs[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
712 src += 2;
713 }
714 }
715#endif
716
717 const SkColor* colors = NULL;
718 const uint16_t* indices = NULL;
719 if (jcolors != NULL) {
720 colors = (const SkColor*)(colorA.ptr() + colorIndex);
721 }
722 if (jindices != NULL) {
723 indices = (const uint16_t*)(indexA.ptr() + indexIndex);
724 }
725
726 canvas->drawVertices(mode, ptCount, verts, texs, colors, NULL,
727 indices, indexCount, *paint);
728 }
Doug Feltf47d7402010-04-21 16:01:52 -0700729
Doug Felt0c702b82010-05-14 10:55:42 -0700730
Doug Feltf47d7402010-04-21 16:01:52 -0700731 static void drawText___CIIFFIPaint(JNIEnv* env, jobject, SkCanvas* canvas,
732 jcharArray text, int index, int count,
733 jfloat x, jfloat y, int flags, SkPaint* paint) {
734 jchar* textArray = env->GetCharArrayElements(text, NULL);
Fabrice Di Megliob39d8972011-04-18 18:33:48 -0700735 drawTextWithGlyphs(canvas, textArray + index, 0, count, x, y, flags, paint);
Doug Feltf47d7402010-04-21 16:01:52 -0700736 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 }
Doug Felt0c702b82010-05-14 10:55:42 -0700738
Doug Feltf47d7402010-04-21 16:01:52 -0700739 static void drawText__StringIIFFIPaint(JNIEnv* env, jobject,
Doug Felt0c702b82010-05-14 10:55:42 -0700740 SkCanvas* canvas, jstring text,
Doug Feltf47d7402010-04-21 16:01:52 -0700741 int start, int end,
742 jfloat x, jfloat y, int flags, SkPaint* paint) {
743 const jchar* textArray = env->GetStringChars(text, NULL);
Fabrice Di Megliob39d8972011-04-18 18:33:48 -0700744 drawTextWithGlyphs(canvas, textArray, start, end, x, y, flags, paint);
Doug Feltf47d7402010-04-21 16:01:52 -0700745 env->ReleaseStringChars(text, textArray);
746 }
Doug Felt0c702b82010-05-14 10:55:42 -0700747
Fabrice Di Meglio689e5152011-04-13 16:07:37 -0700748 static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
749 int start, int end,
750 jfloat x, jfloat y, int flags, SkPaint* paint) {
751
752 jint count = end - start;
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700753 drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, flags, paint);
Fabrice Di Meglio689e5152011-04-13 16:07:37 -0700754 }
755
Fabrice Di Megliob39d8972011-04-18 18:33:48 -0700756 static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
757 int start, int count, int contextCount,
758 jfloat x, jfloat y, int flags, SkPaint* paint) {
759
Fabrice Di Meglioaf033ca2011-06-06 11:51:46 -0700760 sp<TextLayoutCacheValue> value;
761#if USE_TEXT_LAYOUT_CACHE
Fabrice Di Meglio5c863f72011-10-05 18:11:59 -0700762 value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count,
763 contextCount, flags);
Fabrice Di Megliob39d8972011-04-18 18:33:48 -0700764 if (value == NULL) {
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800765 LOGE("Cannot get TextLayoutCache value for text = '%s'",
766 String8(textArray + start, count).string());
Fabrice Di Megliob39d8972011-04-18 18:33:48 -0700767 return ;
768 }
Fabrice Di Meglioaf033ca2011-06-06 11:51:46 -0700769#else
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800770 value = new TextLayoutCacheValue(contextCount);
771 TextLayoutEngine::getInstance().computeValues(value.get(), paint,
772 reinterpret_cast<const UChar*>(textArray), start, count, contextCount, flags);
Fabrice Di Meglioaf033ca2011-06-06 11:51:46 -0700773#endif
Fabrice Di Meglio5c863f72011-10-05 18:11:59 -0700774 doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint);
Fabrice Di Megliob39d8972011-04-18 18:33:48 -0700775 }
776
Fabrice Di Megliofcf2be12011-04-05 17:02:36 -0700777 static void doDrawGlyphs(SkCanvas* canvas, const jchar* glyphArray, int index, int count,
778 jfloat x, jfloat y, int flags, SkPaint* paint) {
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800779 // TODO: need to suppress this code after the GL renderer is modified for not
780 // copying the paint
781
782 // Save old text encoding
783 SkPaint::TextEncoding oldEncoding = paint->getTextEncoding();
784 // Define Glyph encoding
785 paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
786
Fabrice Di Megliofcf2be12011-04-05 17:02:36 -0700787 canvas->drawText(glyphArray + index * 2, count * 2, x, y, *paint);
Fabrice Di Meglio9f82b582011-03-08 12:02:59 -0800788
789 // Get back old encoding
790 paint->setTextEncoding(oldEncoding);
Fabrice Di Megliofcf2be12011-04-05 17:02:36 -0700791 }
792
Doug Felt0c702b82010-05-14 10:55:42 -0700793 static void drawTextRun___CIIIIFFIPaint(
Doug Feltf47d7402010-04-21 16:01:52 -0700794 JNIEnv* env, jobject, SkCanvas* canvas, jcharArray text, int index,
Doug Felt0c702b82010-05-14 10:55:42 -0700795 int count, int contextIndex, int contextCount,
Doug Felt4beb8ff72010-06-09 13:53:24 -0700796 jfloat x, jfloat y, int dirFlags, SkPaint* paint) {
Doug Feltf47d7402010-04-21 16:01:52 -0700797
Doug Feltf47d7402010-04-21 16:01:52 -0700798 jchar* chars = env->GetCharArrayElements(text, NULL);
Fabrice Di Megliob39d8972011-04-18 18:33:48 -0700799 drawTextWithGlyphs(canvas, chars + contextIndex, index - contextIndex,
800 count, contextCount, x, y, dirFlags, paint);
Doug Feltf47d7402010-04-21 16:01:52 -0700801 env->ReleaseCharArrayElements(text, chars, JNI_ABORT);
802 }
803
Doug Felt0c702b82010-05-14 10:55:42 -0700804 static void drawTextRun__StringIIIIFFIPaint(
805 JNIEnv* env, jobject obj, SkCanvas* canvas, jstring text, jint start,
806 jint end, jint contextStart, jint contextEnd,
Doug Felt4beb8ff72010-06-09 13:53:24 -0700807 jfloat x, jfloat y, jint dirFlags, SkPaint* paint) {
Doug Feltf47d7402010-04-21 16:01:52 -0700808
Doug Felt0c702b82010-05-14 10:55:42 -0700809 jint count = end - start;
810 jint contextCount = contextEnd - contextStart;
Doug Feltf47d7402010-04-21 16:01:52 -0700811 const jchar* chars = env->GetStringChars(text, NULL);
Fabrice Di Megliob39d8972011-04-18 18:33:48 -0700812 drawTextWithGlyphs(canvas, chars + contextStart, start - contextStart,
813 count, contextCount, x, y, dirFlags, paint);
Doug Feltf47d7402010-04-21 16:01:52 -0700814 env->ReleaseStringChars(text, chars);
815 }
816
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 static void drawPosText___CII_FPaint(JNIEnv* env, jobject, SkCanvas* canvas,
818 jcharArray text, int index, int count,
819 jfloatArray pos, SkPaint* paint) {
820 jchar* textArray = text ? env->GetCharArrayElements(text, NULL) : NULL;
821 jsize textCount = text ? env->GetArrayLength(text) : NULL;
822 float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
823 int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
824 SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
825 int indx;
826 for (indx = 0; indx < posCount; indx++) {
827 posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]);
828 posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]);
829 }
Mike Reedad8b8f52009-05-01 08:24:01 -0400830 canvas->drawPosText(textArray + index, count << 1, posPtr, *paint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800831 if (text) {
832 env->ReleaseCharArrayElements(text, textArray, 0);
833 }
834 if (pos) {
835 env->ReleaseFloatArrayElements(pos, posArray, 0);
836 }
837 delete[] posPtr;
838 }
Doug Felt0c702b82010-05-14 10:55:42 -0700839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 static void drawPosText__String_FPaint(JNIEnv* env, jobject,
841 SkCanvas* canvas, jstring text,
Doug Felt4beb8ff72010-06-09 13:53:24 -0700842 jfloatArray pos,
843 SkPaint* paint) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 const void* text_ = text ? env->GetStringChars(text, NULL) : NULL;
845 int byteLength = text ? env->GetStringLength(text) : 0;
846 float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
847 int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
848 SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
849
850 for (int indx = 0; indx < posCount; indx++) {
851 posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]);
852 posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]);
853 }
854 canvas->drawPosText(text_, byteLength << 1, posPtr, *paint);
855 if (text) {
856 env->ReleaseStringChars(text, (const jchar*) text_);
857 }
858 if (pos) {
859 env->ReleaseFloatArrayElements(pos, posArray, 0);
860 }
861 delete[] posPtr;
862 }
Doug Felt0c702b82010-05-14 10:55:42 -0700863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 static void drawTextOnPath___CIIPathFFPaint(JNIEnv* env, jobject,
Doug Felt4beb8ff72010-06-09 13:53:24 -0700865 SkCanvas* canvas, jcharArray text, int index, int count,
866 SkPath* path, jfloat hOffset, jfloat vOffset, jint bidiFlags, SkPaint* paint) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867
868 jchar* textArray = env->GetCharArrayElements(text, NULL);
Romain Guy8f67eae2011-04-26 11:24:42 -0700869 TextLayout::drawTextOnPath(paint, textArray + index, count, bidiFlags, hOffset, vOffset,
Doug Feltf7cb1f72010-07-01 16:20:43 -0700870 path, canvas);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 env->ReleaseCharArrayElements(text, textArray, 0);
872 }
Doug Felt0c702b82010-05-14 10:55:42 -0700873
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874 static void drawTextOnPath__StringPathFFPaint(JNIEnv* env, jobject,
Doug Felt4beb8ff72010-06-09 13:53:24 -0700875 SkCanvas* canvas, jstring text, SkPath* path,
876 jfloat hOffset, jfloat vOffset, jint bidiFlags, SkPaint* paint) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 const jchar* text_ = env->GetStringChars(text, NULL);
Doug Felt4beb8ff72010-06-09 13:53:24 -0700878 int count = env->GetStringLength(text);
Doug Feltf7cb1f72010-07-01 16:20:43 -0700879 TextLayout::drawTextOnPath(paint, text_, count, bidiFlags, hOffset, vOffset,
880 path, canvas);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 env->ReleaseStringChars(text, text_);
882 }
Doug Felt0c702b82010-05-14 10:55:42 -0700883
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 static bool getClipBounds(JNIEnv* env, jobject, SkCanvas* canvas,
885 jobject bounds) {
886 SkRect r;
887 SkIRect ir;
888 bool result = canvas->getClipBounds(&r, SkCanvas::kBW_EdgeType);
889
890 r.round(&ir);
891 (void)GraphicsJNI::irect_to_jrect(ir, env, bounds);
892 return result;
893 }
894
895 static void getCTM(JNIEnv* env, jobject, SkCanvas* canvas,
896 SkMatrix* matrix) {
897 *matrix = canvas->getTotalMatrix();
898 }
899};
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900
901static JNINativeMethod gCanvasMethods[] = {
902 {"finalizer", "(I)V", (void*) SkCanvasGlue::finalizer},
903 {"initRaster","(I)I", (void*) SkCanvasGlue::initRaster},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 {"isOpaque","()Z", (void*) SkCanvasGlue::isOpaque},
905 {"getWidth","()I", (void*) SkCanvasGlue::getWidth},
906 {"getHeight","()I", (void*) SkCanvasGlue::getHeight},
907 {"native_setBitmap","(II)V", (void*) SkCanvasGlue::setBitmap},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 {"save","()I", (void*) SkCanvasGlue::saveAll},
909 {"save","(I)I", (void*) SkCanvasGlue::save},
910 {"native_saveLayer","(ILandroid/graphics/RectF;II)I",
911 (void*) SkCanvasGlue::saveLayer},
912 {"native_saveLayer","(IFFFFII)I", (void*) SkCanvasGlue::saveLayer4F},
913 {"native_saveLayerAlpha","(ILandroid/graphics/RectF;II)I",
914 (void*) SkCanvasGlue::saveLayerAlpha},
915 {"native_saveLayerAlpha","(IFFFFII)I",
916 (void*) SkCanvasGlue::saveLayerAlpha4F},
917 {"restore","()V", (void*) SkCanvasGlue::restore},
918 {"getSaveCount","()I", (void*) SkCanvasGlue::getSaveCount},
919 {"restoreToCount","(I)V", (void*) SkCanvasGlue::restoreToCount},
920 {"translate","(FF)V", (void*) SkCanvasGlue::translate},
921 {"scale","(FF)V", (void*) SkCanvasGlue::scale__FF},
922 {"rotate","(F)V", (void*) SkCanvasGlue::rotate__F},
923 {"skew","(FF)V", (void*) SkCanvasGlue::skew__FF},
924 {"native_concat","(II)V", (void*) SkCanvasGlue::concat},
925 {"native_setMatrix","(II)V", (void*) SkCanvasGlue::setMatrix},
926 {"clipRect","(FFFF)Z", (void*) SkCanvasGlue::clipRect_FFFF},
927 {"clipRect","(IIII)Z", (void*) SkCanvasGlue::clipRect_IIII},
928 {"clipRect","(Landroid/graphics/RectF;)Z",
929 (void*) SkCanvasGlue::clipRect_RectF},
930 {"clipRect","(Landroid/graphics/Rect;)Z",
931 (void*) SkCanvasGlue::clipRect_Rect},
932 {"native_clipRect","(IFFFFI)Z", (void*) SkCanvasGlue::clipRect},
933 {"native_clipPath","(III)Z", (void*) SkCanvasGlue::clipPath},
934 {"native_clipRegion","(III)Z", (void*) SkCanvasGlue::clipRegion},
935 {"nativeSetDrawFilter", "(II)V", (void*) SkCanvasGlue::setDrawFilter},
936 {"native_getClipBounds","(ILandroid/graphics/Rect;)Z",
937 (void*) SkCanvasGlue::getClipBounds},
938 {"native_getCTM", "(II)V", (void*)SkCanvasGlue::getCTM},
939 {"native_quickReject","(ILandroid/graphics/RectF;I)Z",
940 (void*) SkCanvasGlue::quickReject__RectFI},
941 {"native_quickReject","(III)Z", (void*) SkCanvasGlue::quickReject__PathI},
942 {"native_quickReject","(IFFFFI)Z", (void*)SkCanvasGlue::quickReject__FFFFI},
943 {"native_drawRGB","(IIII)V", (void*) SkCanvasGlue::drawRGB},
944 {"native_drawARGB","(IIIII)V", (void*) SkCanvasGlue::drawARGB},
945 {"native_drawColor","(II)V", (void*) SkCanvasGlue::drawColor__I},
946 {"native_drawColor","(III)V", (void*) SkCanvasGlue::drawColor__II},
947 {"native_drawPaint","(II)V", (void*) SkCanvasGlue::drawPaint},
948 {"drawPoint", "(FFLandroid/graphics/Paint;)V",
949 (void*) SkCanvasGlue::drawPoint},
950 {"drawPoints", "([FIILandroid/graphics/Paint;)V",
951 (void*) SkCanvasGlue::drawPoints},
952 {"drawLines", "([FIILandroid/graphics/Paint;)V",
953 (void*) SkCanvasGlue::drawLines},
954 {"native_drawLine","(IFFFFI)V", (void*) SkCanvasGlue::drawLine__FFFFPaint},
955 {"native_drawRect","(ILandroid/graphics/RectF;I)V",
956 (void*) SkCanvasGlue::drawRect__RectFPaint},
957 {"native_drawRect","(IFFFFI)V", (void*) SkCanvasGlue::drawRect__FFFFPaint},
958 {"native_drawOval","(ILandroid/graphics/RectF;I)V",
959 (void*) SkCanvasGlue::drawOval},
960 {"native_drawCircle","(IFFFI)V", (void*) SkCanvasGlue::drawCircle},
961 {"native_drawArc","(ILandroid/graphics/RectF;FFZI)V",
962 (void*) SkCanvasGlue::drawArc},
963 {"native_drawRoundRect","(ILandroid/graphics/RectF;FFI)V",
964 (void*) SkCanvasGlue::drawRoundRect},
965 {"native_drawPath","(III)V", (void*) SkCanvasGlue::drawPath},
Dianne Hackborn0d221012009-07-29 15:41:19 -0700966 {"native_drawBitmap","(IIFFIIII)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 (void*) SkCanvasGlue::drawBitmap__BitmapFFPaint},
Dianne Hackborn0d221012009-07-29 15:41:19 -0700968 {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;III)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 (void*) SkCanvasGlue::drawBitmapRF},
Dianne Hackborn0d221012009-07-29 15:41:19 -0700970 {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;III)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 (void*) SkCanvasGlue::drawBitmapRR},
972 {"native_drawBitmap", "(I[IIIFFIIZI)V",
973 (void*)SkCanvasGlue::drawBitmapArray},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 {"nativeDrawBitmapMatrix", "(IIII)V",
975 (void*)SkCanvasGlue::drawBitmapMatrix},
976 {"nativeDrawBitmapMesh", "(IIII[FI[III)V",
977 (void*)SkCanvasGlue::drawBitmapMesh},
978 {"nativeDrawVertices", "(III[FI[FI[II[SIII)V",
979 (void*)SkCanvasGlue::drawVertices},
Doug Feltf47d7402010-04-21 16:01:52 -0700980 {"native_drawText","(I[CIIFFII)V",
981 (void*) SkCanvasGlue::drawText___CIIFFIPaint},
982 {"native_drawText","(ILjava/lang/String;IIFFII)V",
983 (void*) SkCanvasGlue::drawText__StringIIFFIPaint},
Doug Felt0c702b82010-05-14 10:55:42 -0700984 {"native_drawTextRun","(I[CIIIIFFII)V",
985 (void*) SkCanvasGlue::drawTextRun___CIIIIFFIPaint},
986 {"native_drawTextRun","(ILjava/lang/String;IIIIFFII)V",
987 (void*) SkCanvasGlue::drawTextRun__StringIIIIFFIPaint},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 {"native_drawPosText","(I[CII[FI)V",
989 (void*) SkCanvasGlue::drawPosText___CII_FPaint},
990 {"native_drawPosText","(ILjava/lang/String;[FI)V",
991 (void*) SkCanvasGlue::drawPosText__String_FPaint},
Doug Felt4beb8ff72010-06-09 13:53:24 -0700992 {"native_drawTextOnPath","(I[CIIIFFII)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 (void*) SkCanvasGlue::drawTextOnPath___CIIPathFFPaint},
Doug Felt4beb8ff72010-06-09 13:53:24 -0700994 {"native_drawTextOnPath","(ILjava/lang/String;IFFII)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 (void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint},
996 {"native_drawPicture", "(II)V", (void*) SkCanvasGlue::drawPicture},
997
Mike Reedcaf0df12009-04-27 14:32:05 -0400998 {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999};
1000
Mike Reedc04851f2009-10-28 15:09:45 -04001001///////////////////////////////////////////////////////////////////////////////
1002
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003#include <android_runtime/AndroidRuntime.h>
1004
1005#define REG(env, name, array) \
1006 result = android::AndroidRuntime::registerNativeMethods(env, name, array, \
1007 SK_ARRAY_COUNT(array)); \
1008 if (result < 0) return result
1009
1010int register_android_graphics_Canvas(JNIEnv* env) {
1011 int result;
1012
1013 REG(env, "android/graphics/Canvas", gCanvasMethods);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014
1015 return result;
1016}
1017
1018}