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 "SkGraphics.h"
24 #include "SkImageRef_GlobalPool.h"
25 #include "SkPorterDuff.h"
26 #include "SkShader.h"
27 #include "SkTemplates.h"
28
29 #include "TextLayout.h"
30 #include "TextLayoutCache.h"
31
32 #include "unicode/ubidi.h"
33 #include "unicode/ushape.h"
34
35 #include <utils/Log.h>
36
37 #define TIME_DRAWx
38
get_thread_msec()39 static 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
54 namespace android {
55
56 class SkCanvasGlue {
57 public:
58
finalizer(JNIEnv * env,jobject clazz,SkCanvas * canvas)59 static void finalizer(JNIEnv* env, jobject clazz, SkCanvas* canvas) {
60 canvas->unref();
61 }
62
initRaster(JNIEnv * env,jobject,SkBitmap * bitmap)63 static SkCanvas* initRaster(JNIEnv* env, jobject, SkBitmap* bitmap) {
64 return bitmap ? new SkCanvas(*bitmap) : new SkCanvas;
65 }
66
freeCaches(JNIEnv * env,jobject)67 static void freeCaches(JNIEnv* env, jobject) {
68 // these are called in no particular order
69 SkImageRef_GlobalPool::SetRAMUsed(0);
70 SkGraphics::SetFontCacheUsed(0);
71 }
72
isOpaque(JNIEnv * env,jobject jcanvas)73 static jboolean isOpaque(JNIEnv* env, jobject jcanvas) {
74 NPE_CHECK_RETURN_ZERO(env, jcanvas);
75 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
76 return canvas->getDevice()->accessBitmap(false).isOpaque();
77 }
78
getWidth(JNIEnv * env,jobject jcanvas)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
getHeight(JNIEnv * env,jobject jcanvas)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
setBitmap(JNIEnv * env,jobject,SkCanvas * canvas,SkBitmap * bitmap)91 static void setBitmap(JNIEnv* env, jobject, SkCanvas* canvas, SkBitmap* bitmap) {
92 if (bitmap) {
93 canvas->setBitmapDevice(*bitmap);
94 } else {
95 canvas->setDevice(NULL);
96 }
97 }
98
saveAll(JNIEnv * env,jobject jcanvas)99 static int saveAll(JNIEnv* env, jobject jcanvas) {
100 NPE_CHECK_RETURN_ZERO(env, jcanvas);
101 return GraphicsJNI::getNativeCanvas(env, jcanvas)->save();
102 }
103
save(JNIEnv * env,jobject jcanvas,SkCanvas::SaveFlags flags)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
saveLayer(JNIEnv * env,jobject,SkCanvas * canvas,jobject bounds,SkPaint * paint,int flags)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
saveLayer4F(JNIEnv * env,jobject,SkCanvas * canvas,jfloat l,jfloat t,jfloat r,jfloat b,SkPaint * paint,int flags)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
saveLayerAlpha(JNIEnv * env,jobject,SkCanvas * canvas,jobject bounds,int alpha,int flags)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
saveLayerAlpha4F(JNIEnv * env,jobject,SkCanvas * canvas,jfloat l,jfloat t,jfloat r,jfloat b,int alpha,int flags)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
restore(JNIEnv * env,jobject jcanvas)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
getSaveCount(JNIEnv * env,jobject jcanvas)161 static int getSaveCount(JNIEnv* env, jobject jcanvas) {
162 NPE_CHECK_RETURN_ZERO(env, jcanvas);
163 return GraphicsJNI::getNativeCanvas(env, jcanvas)->getSaveCount();
164 }
165
restoreToCount(JNIEnv * env,jobject jcanvas,int restoreCount)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
translate(JNIEnv * env,jobject jcanvas,jfloat dx,jfloat dy)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
scale__FF(JNIEnv * env,jobject jcanvas,jfloat sx,jfloat sy)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
rotate__F(JNIEnv * env,jobject jcanvas,jfloat degrees)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
skew__FF(JNIEnv * env,jobject jcanvas,jfloat sx,jfloat sy)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
concat(JNIEnv * env,jobject,SkCanvas * canvas,const SkMatrix * matrix)203 static void concat(JNIEnv* env, jobject, SkCanvas* canvas,
204 const SkMatrix* matrix) {
205 canvas->concat(*matrix);
206 }
207
setMatrix(JNIEnv * env,jobject,SkCanvas * canvas,const SkMatrix * matrix)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
clipRect_FFFF(JNIEnv * env,jobject jcanvas,jfloat left,jfloat top,jfloat right,jfloat bottom)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
clipRect_IIII(JNIEnv * env,jobject jcanvas,jint left,jint top,jint right,jint bottom)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
clipRect_RectF(JNIEnv * env,jobject jcanvas,jobject rectf)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
clipRect_Rect(JNIEnv * env,jobject jcanvas,jobject rect)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
clipRect(JNIEnv * env,jobject,SkCanvas * canvas,float left,float top,float right,float bottom,int op)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
clipPath(JNIEnv * env,jobject,SkCanvas * canvas,SkPath * path,int op)261 static jboolean clipPath(JNIEnv* env, jobject, SkCanvas* canvas,
262 SkPath* path, int op) {
263 return canvas->clipPath(*path, (SkRegion::Op)op);
264 }
265
clipRegion(JNIEnv * env,jobject,SkCanvas * canvas,SkRegion * deviceRgn,int op)266 static jboolean clipRegion(JNIEnv* env, jobject, SkCanvas* canvas,
267 SkRegion* deviceRgn, int op) {
268 return canvas->clipRegion(*deviceRgn, (SkRegion::Op)op);
269 }
270
setDrawFilter(JNIEnv * env,jobject,SkCanvas * canvas,SkDrawFilter * filter)271 static void setDrawFilter(JNIEnv* env, jobject, SkCanvas* canvas,
272 SkDrawFilter* filter) {
273 canvas->setDrawFilter(filter);
274 }
275
quickReject__RectFI(JNIEnv * env,jobject,SkCanvas * canvas,jobject rect,int edgetype)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
quickReject__PathI(JNIEnv * env,jobject,SkCanvas * canvas,SkPath * path,int edgetype)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
quickReject__FFFFI(JNIEnv * env,jobject,SkCanvas * canvas,jfloat left,jfloat top,jfloat right,jfloat bottom,int edgetype)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
drawRGB(JNIEnv * env,jobject,SkCanvas * canvas,jint r,jint g,jint b)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
drawARGB(JNIEnv * env,jobject,SkCanvas * canvas,jint a,jint r,jint g,jint b)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
drawColor__I(JNIEnv * env,jobject,SkCanvas * canvas,jint color)307 static void drawColor__I(JNIEnv* env, jobject, SkCanvas* canvas,
308 jint color) {
309 canvas->drawColor(color);
310 }
311
drawColor__II(JNIEnv * env,jobject,SkCanvas * canvas,jint color,SkPorterDuff::Mode mode)312 static void drawColor__II(JNIEnv* env, jobject, SkCanvas* canvas,
313 jint color, SkPorterDuff::Mode mode) {
314 canvas->drawColor(color, SkPorterDuff::ToXfermodeMode(mode));
315 }
316
drawPaint(JNIEnv * env,jobject,SkCanvas * canvas,SkPaint * paint)317 static void drawPaint(JNIEnv* env, jobject, SkCanvas* canvas,
318 SkPaint* paint) {
319 canvas->drawPaint(*paint);
320 }
321
doPoints(JNIEnv * env,jobject jcanvas,jfloatArray jptsArray,jint offset,jint count,jobject jpaint,SkCanvas::PointMode mode)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
drawPoints(JNIEnv * env,jobject jcanvas,jfloatArray jptsArray,jint offset,jint count,jobject jpaint)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
drawLines(JNIEnv * env,jobject jcanvas,jfloatArray jptsArray,jint offset,jint count,jobject jpaint)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
drawPoint(JNIEnv * env,jobject jcanvas,float x,float y,jobject jpaint)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
drawLine__FFFFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jfloat startX,jfloat startY,jfloat stopX,jfloat stopY,SkPaint * paint)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
drawRect__RectFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jobject rect,SkPaint * paint)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
drawRect__FFFFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jfloat left,jfloat top,jfloat right,jfloat bottom,SkPaint * paint)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
drawOval(JNIEnv * env,jobject,SkCanvas * canvas,jobject joval,SkPaint * paint)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
drawCircle(JNIEnv * env,jobject,SkCanvas * canvas,jfloat cx,jfloat cy,jfloat radius,SkPaint * paint)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
drawArc(JNIEnv * env,jobject,SkCanvas * canvas,jobject joval,jfloat startAngle,jfloat sweepAngle,jboolean useCenter,SkPaint * paint)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
drawRoundRect(JNIEnv * env,jobject,SkCanvas * canvas,jobject jrect,jfloat rx,jfloat ry,SkPaint * paint)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
drawPath(JNIEnv * env,jobject,SkCanvas * canvas,SkPath * path,SkPaint * paint)430 static void drawPath(JNIEnv* env, jobject, SkCanvas* canvas, SkPath* path,
431 SkPaint* paint) {
432 canvas->drawPath(*path, *paint);
433 }
434
drawPicture(JNIEnv * env,jobject,SkCanvas * canvas,SkPicture * picture)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
drawBitmap__BitmapFFPaint(JNIEnv * env,jobject jcanvas,SkCanvas * canvas,SkBitmap * bitmap,jfloat left,jfloat top,SkPaint * paint,jint canvasDensity,jint screenDensity,jint bitmapDensity)449 static void drawBitmap__BitmapFFPaint(JNIEnv* env, jobject jcanvas,
450 SkCanvas* canvas, SkBitmap* bitmap,
451 jfloat left, jfloat top,
452 SkPaint* paint, jint canvasDensity,
453 jint screenDensity, jint bitmapDensity) {
454 SkScalar left_ = SkFloatToScalar(left);
455 SkScalar top_ = SkFloatToScalar(top);
456
457 if (canvasDensity == bitmapDensity || canvasDensity == 0
458 || bitmapDensity == 0) {
459 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 }
469 } else {
470 canvas->save();
471 SkScalar scale = SkFloatToScalar(canvasDensity / (float)bitmapDensity);
472 canvas->translate(left_, top_);
473 canvas->scale(scale, scale);
474
475 SkPaint filteredPaint;
476 if (paint) {
477 filteredPaint = *paint;
478 }
479 filteredPaint.setFilterBitmap(true);
480
481 canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
482
483 canvas->restore();
484 }
485 }
486
doDrawBitmap(JNIEnv * env,SkCanvas * canvas,SkBitmap * bitmap,jobject srcIRect,const SkRect & dst,SkPaint * paint,jint screenDensity,jint bitmapDensity)487 static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap,
488 jobject srcIRect, const SkRect& dst, SkPaint* paint,
489 jint screenDensity, jint bitmapDensity) {
490 SkIRect src, *srcPtr = NULL;
491
492 if (NULL != srcIRect) {
493 GraphicsJNI::jrect_to_irect(env, srcIRect, &src);
494 srcPtr = &src;
495 }
496
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 }
507 }
508
drawBitmapRF(JNIEnv * env,jobject,SkCanvas * canvas,SkBitmap * bitmap,jobject srcIRect,jobject dstRectF,SkPaint * paint,jint screenDensity,jint bitmapDensity)509 static void drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas,
510 SkBitmap* bitmap, jobject srcIRect,
511 jobject dstRectF, SkPaint* paint,
512 jint screenDensity, jint bitmapDensity) {
513 SkRect dst;
514 GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst);
515 doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
516 screenDensity, bitmapDensity);
517 }
518
drawBitmapRR(JNIEnv * env,jobject,SkCanvas * canvas,SkBitmap * bitmap,jobject srcIRect,jobject dstRect,SkPaint * paint,jint screenDensity,jint bitmapDensity)519 static void drawBitmapRR(JNIEnv* env, jobject, SkCanvas* canvas,
520 SkBitmap* bitmap, jobject srcIRect,
521 jobject dstRect, SkPaint* paint,
522 jint screenDensity, jint bitmapDensity) {
523 SkRect dst;
524 GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
525 doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
526 screenDensity, bitmapDensity);
527 }
528
drawBitmapArray(JNIEnv * env,jobject,SkCanvas * canvas,jintArray jcolors,int offset,int stride,jfloat x,jfloat y,int width,int height,jboolean hasAlpha,SkPaint * paint)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
drawBitmapMatrix(JNIEnv * env,jobject,SkCanvas * canvas,const SkBitmap * bitmap,const SkMatrix * matrix,const SkPaint * paint)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
drawBitmapMesh(JNIEnv * env,jobject,SkCanvas * canvas,const SkBitmap * bitmap,int meshWidth,int meshHeight,jfloatArray jverts,int vertIndex,jintArray jcolors,int colorIndex,const SkPaint * paint)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);
666 SkSafeUnref(tmpPaint.setShader(shader));
667
668 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, verts,
669 texs, (const SkColor*)colorA.ptr(), NULL, indices,
670 indexCount, tmpPaint);
671 }
672
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)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 }
729
730
drawText___CIIFFIPaint(JNIEnv * env,jobject,SkCanvas * canvas,jcharArray text,int index,int count,jfloat x,jfloat y,int flags,SkPaint * paint)731 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);
735 #if RTL_USE_HARFBUZZ
736 drawTextWithGlyphs(canvas, textArray + index, 0, count, x, y, flags, paint);
737 #else
738 TextLayout::drawText(paint, textArray + index, count, flags, x, y, canvas);
739 #endif
740 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
741 }
742
drawText__StringIIFFIPaint(JNIEnv * env,jobject,SkCanvas * canvas,jstring text,int start,int end,jfloat x,jfloat y,int flags,SkPaint * paint)743 static void drawText__StringIIFFIPaint(JNIEnv* env, jobject,
744 SkCanvas* canvas, jstring text,
745 int start, int end,
746 jfloat x, jfloat y, int flags, SkPaint* paint) {
747 const jchar* textArray = env->GetStringChars(text, NULL);
748 #if RTL_USE_HARFBUZZ
749 drawTextWithGlyphs(canvas, textArray, start, end, x, y, flags, paint);
750 #else
751 TextLayout::drawText(paint, textArray + start, end - start, flags, x, y, canvas);
752 #endif
753 env->ReleaseStringChars(text, textArray);
754 }
755
drawTextWithGlyphs(SkCanvas * canvas,const jchar * textArray,int start,int end,jfloat x,jfloat y,int flags,SkPaint * paint)756 static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
757 int start, int end,
758 jfloat x, jfloat y, int flags, SkPaint* paint) {
759
760 jint count = end - start;
761 drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, flags, paint);
762 }
763
drawTextWithGlyphs(SkCanvas * canvas,const jchar * textArray,int start,int count,int contextCount,jfloat x,jfloat y,int flags,SkPaint * paint)764 static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
765 int start, int count, int contextCount,
766 jfloat x, jfloat y, int flags, SkPaint* paint) {
767
768 sp<TextLayoutCacheValue> value;
769 #if USE_TEXT_LAYOUT_CACHE
770 value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count,
771 contextCount, flags);
772 if (value == NULL) {
773 LOGE("Cannot get TextLayoutCache value");
774 return ;
775 }
776 #else
777 value = new TextLayoutCacheValue();
778 value->computeValues(paint, textArray, start, count, contextCount, flags);
779 #endif
780 doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint);
781 }
782
doDrawGlyphs(SkCanvas * canvas,const jchar * glyphArray,int index,int count,jfloat x,jfloat y,int flags,SkPaint * paint)783 static void doDrawGlyphs(SkCanvas* canvas, const jchar* glyphArray, int index, int count,
784 jfloat x, jfloat y, int flags, SkPaint* paint) {
785 // TODO: need to suppress this code after the GL renderer is modified for not
786 // copying the paint
787
788 // Save old text encoding
789 SkPaint::TextEncoding oldEncoding = paint->getTextEncoding();
790 // Define Glyph encoding
791 paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
792
793 canvas->drawText(glyphArray + index * 2, count * 2, x, y, *paint);
794
795 // Get back old encoding
796 paint->setTextEncoding(oldEncoding);
797 }
798
drawTextRun___CIIIIFFIPaint(JNIEnv * env,jobject,SkCanvas * canvas,jcharArray text,int index,int count,int contextIndex,int contextCount,jfloat x,jfloat y,int dirFlags,SkPaint * paint)799 static void drawTextRun___CIIIIFFIPaint(
800 JNIEnv* env, jobject, SkCanvas* canvas, jcharArray text, int index,
801 int count, int contextIndex, int contextCount,
802 jfloat x, jfloat y, int dirFlags, SkPaint* paint) {
803
804 jchar* chars = env->GetCharArrayElements(text, NULL);
805 #if RTL_USE_HARFBUZZ
806 drawTextWithGlyphs(canvas, chars + contextIndex, index - contextIndex,
807 count, contextCount, x, y, dirFlags, paint);
808 #else
809 TextLayout::drawTextRun(paint, chars + contextIndex, index - contextIndex,
810 count, contextCount, dirFlags, x, y, canvas);
811 #endif
812 env->ReleaseCharArrayElements(text, chars, JNI_ABORT);
813 }
814
drawTextRun__StringIIIIFFIPaint(JNIEnv * env,jobject obj,SkCanvas * canvas,jstring text,jint start,jint end,jint contextStart,jint contextEnd,jfloat x,jfloat y,jint dirFlags,SkPaint * paint)815 static void drawTextRun__StringIIIIFFIPaint(
816 JNIEnv* env, jobject obj, SkCanvas* canvas, jstring text, jint start,
817 jint end, jint contextStart, jint contextEnd,
818 jfloat x, jfloat y, jint dirFlags, SkPaint* paint) {
819
820 jint count = end - start;
821 jint contextCount = contextEnd - contextStart;
822 const jchar* chars = env->GetStringChars(text, NULL);
823 #if RTL_USE_HARFBUZZ
824 drawTextWithGlyphs(canvas, chars + contextStart, start - contextStart,
825 count, contextCount, x, y, dirFlags, paint);
826 #else
827 TextLayout::drawTextRun(paint, chars + contextStart, start - contextStart,
828 count, contextCount, dirFlags, x, y, canvas);
829 #endif
830 env->ReleaseStringChars(text, chars);
831 }
832
drawPosText___CII_FPaint(JNIEnv * env,jobject,SkCanvas * canvas,jcharArray text,int index,int count,jfloatArray pos,SkPaint * paint)833 static void drawPosText___CII_FPaint(JNIEnv* env, jobject, SkCanvas* canvas,
834 jcharArray text, int index, int count,
835 jfloatArray pos, SkPaint* paint) {
836 jchar* textArray = text ? env->GetCharArrayElements(text, NULL) : NULL;
837 jsize textCount = text ? env->GetArrayLength(text) : NULL;
838 float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
839 int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
840 SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
841 int indx;
842 for (indx = 0; indx < posCount; indx++) {
843 posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]);
844 posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]);
845 }
846 canvas->drawPosText(textArray + index, count << 1, posPtr, *paint);
847 if (text) {
848 env->ReleaseCharArrayElements(text, textArray, 0);
849 }
850 if (pos) {
851 env->ReleaseFloatArrayElements(pos, posArray, 0);
852 }
853 delete[] posPtr;
854 }
855
drawPosText__String_FPaint(JNIEnv * env,jobject,SkCanvas * canvas,jstring text,jfloatArray pos,SkPaint * paint)856 static void drawPosText__String_FPaint(JNIEnv* env, jobject,
857 SkCanvas* canvas, jstring text,
858 jfloatArray pos,
859 SkPaint* paint) {
860 const void* text_ = text ? env->GetStringChars(text, NULL) : NULL;
861 int byteLength = text ? env->GetStringLength(text) : 0;
862 float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
863 int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
864 SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
865
866 for (int indx = 0; indx < posCount; indx++) {
867 posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]);
868 posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]);
869 }
870 canvas->drawPosText(text_, byteLength << 1, posPtr, *paint);
871 if (text) {
872 env->ReleaseStringChars(text, (const jchar*) text_);
873 }
874 if (pos) {
875 env->ReleaseFloatArrayElements(pos, posArray, 0);
876 }
877 delete[] posPtr;
878 }
879
drawTextOnPath___CIIPathFFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jcharArray text,int index,int count,SkPath * path,jfloat hOffset,jfloat vOffset,jint bidiFlags,SkPaint * paint)880 static void drawTextOnPath___CIIPathFFPaint(JNIEnv* env, jobject,
881 SkCanvas* canvas, jcharArray text, int index, int count,
882 SkPath* path, jfloat hOffset, jfloat vOffset, jint bidiFlags, SkPaint* paint) {
883
884 jchar* textArray = env->GetCharArrayElements(text, NULL);
885 TextLayout::drawTextOnPath(paint, textArray + index, count, bidiFlags, hOffset, vOffset,
886 path, canvas);
887 env->ReleaseCharArrayElements(text, textArray, 0);
888 }
889
drawTextOnPath__StringPathFFPaint(JNIEnv * env,jobject,SkCanvas * canvas,jstring text,SkPath * path,jfloat hOffset,jfloat vOffset,jint bidiFlags,SkPaint * paint)890 static void drawTextOnPath__StringPathFFPaint(JNIEnv* env, jobject,
891 SkCanvas* canvas, jstring text, SkPath* path,
892 jfloat hOffset, jfloat vOffset, jint bidiFlags, SkPaint* paint) {
893 const jchar* text_ = env->GetStringChars(text, NULL);
894 int count = env->GetStringLength(text);
895 TextLayout::drawTextOnPath(paint, text_, count, bidiFlags, hOffset, vOffset,
896 path, canvas);
897 env->ReleaseStringChars(text, text_);
898 }
899
getClipBounds(JNIEnv * env,jobject,SkCanvas * canvas,jobject bounds)900 static bool getClipBounds(JNIEnv* env, jobject, SkCanvas* canvas,
901 jobject bounds) {
902 SkRect r;
903 SkIRect ir;
904 bool result = canvas->getClipBounds(&r, SkCanvas::kBW_EdgeType);
905
906 r.round(&ir);
907 (void)GraphicsJNI::irect_to_jrect(ir, env, bounds);
908 return result;
909 }
910
getCTM(JNIEnv * env,jobject,SkCanvas * canvas,SkMatrix * matrix)911 static void getCTM(JNIEnv* env, jobject, SkCanvas* canvas,
912 SkMatrix* matrix) {
913 *matrix = canvas->getTotalMatrix();
914 }
915 };
916
917 static JNINativeMethod gCanvasMethods[] = {
918 {"finalizer", "(I)V", (void*) SkCanvasGlue::finalizer},
919 {"initRaster","(I)I", (void*) SkCanvasGlue::initRaster},
920 {"isOpaque","()Z", (void*) SkCanvasGlue::isOpaque},
921 {"getWidth","()I", (void*) SkCanvasGlue::getWidth},
922 {"getHeight","()I", (void*) SkCanvasGlue::getHeight},
923 {"native_setBitmap","(II)V", (void*) SkCanvasGlue::setBitmap},
924 {"save","()I", (void*) SkCanvasGlue::saveAll},
925 {"save","(I)I", (void*) SkCanvasGlue::save},
926 {"native_saveLayer","(ILandroid/graphics/RectF;II)I",
927 (void*) SkCanvasGlue::saveLayer},
928 {"native_saveLayer","(IFFFFII)I", (void*) SkCanvasGlue::saveLayer4F},
929 {"native_saveLayerAlpha","(ILandroid/graphics/RectF;II)I",
930 (void*) SkCanvasGlue::saveLayerAlpha},
931 {"native_saveLayerAlpha","(IFFFFII)I",
932 (void*) SkCanvasGlue::saveLayerAlpha4F},
933 {"restore","()V", (void*) SkCanvasGlue::restore},
934 {"getSaveCount","()I", (void*) SkCanvasGlue::getSaveCount},
935 {"restoreToCount","(I)V", (void*) SkCanvasGlue::restoreToCount},
936 {"translate","(FF)V", (void*) SkCanvasGlue::translate},
937 {"scale","(FF)V", (void*) SkCanvasGlue::scale__FF},
938 {"rotate","(F)V", (void*) SkCanvasGlue::rotate__F},
939 {"skew","(FF)V", (void*) SkCanvasGlue::skew__FF},
940 {"native_concat","(II)V", (void*) SkCanvasGlue::concat},
941 {"native_setMatrix","(II)V", (void*) SkCanvasGlue::setMatrix},
942 {"clipRect","(FFFF)Z", (void*) SkCanvasGlue::clipRect_FFFF},
943 {"clipRect","(IIII)Z", (void*) SkCanvasGlue::clipRect_IIII},
944 {"clipRect","(Landroid/graphics/RectF;)Z",
945 (void*) SkCanvasGlue::clipRect_RectF},
946 {"clipRect","(Landroid/graphics/Rect;)Z",
947 (void*) SkCanvasGlue::clipRect_Rect},
948 {"native_clipRect","(IFFFFI)Z", (void*) SkCanvasGlue::clipRect},
949 {"native_clipPath","(III)Z", (void*) SkCanvasGlue::clipPath},
950 {"native_clipRegion","(III)Z", (void*) SkCanvasGlue::clipRegion},
951 {"nativeSetDrawFilter", "(II)V", (void*) SkCanvasGlue::setDrawFilter},
952 {"native_getClipBounds","(ILandroid/graphics/Rect;)Z",
953 (void*) SkCanvasGlue::getClipBounds},
954 {"native_getCTM", "(II)V", (void*)SkCanvasGlue::getCTM},
955 {"native_quickReject","(ILandroid/graphics/RectF;I)Z",
956 (void*) SkCanvasGlue::quickReject__RectFI},
957 {"native_quickReject","(III)Z", (void*) SkCanvasGlue::quickReject__PathI},
958 {"native_quickReject","(IFFFFI)Z", (void*)SkCanvasGlue::quickReject__FFFFI},
959 {"native_drawRGB","(IIII)V", (void*) SkCanvasGlue::drawRGB},
960 {"native_drawARGB","(IIIII)V", (void*) SkCanvasGlue::drawARGB},
961 {"native_drawColor","(II)V", (void*) SkCanvasGlue::drawColor__I},
962 {"native_drawColor","(III)V", (void*) SkCanvasGlue::drawColor__II},
963 {"native_drawPaint","(II)V", (void*) SkCanvasGlue::drawPaint},
964 {"drawPoint", "(FFLandroid/graphics/Paint;)V",
965 (void*) SkCanvasGlue::drawPoint},
966 {"drawPoints", "([FIILandroid/graphics/Paint;)V",
967 (void*) SkCanvasGlue::drawPoints},
968 {"drawLines", "([FIILandroid/graphics/Paint;)V",
969 (void*) SkCanvasGlue::drawLines},
970 {"native_drawLine","(IFFFFI)V", (void*) SkCanvasGlue::drawLine__FFFFPaint},
971 {"native_drawRect","(ILandroid/graphics/RectF;I)V",
972 (void*) SkCanvasGlue::drawRect__RectFPaint},
973 {"native_drawRect","(IFFFFI)V", (void*) SkCanvasGlue::drawRect__FFFFPaint},
974 {"native_drawOval","(ILandroid/graphics/RectF;I)V",
975 (void*) SkCanvasGlue::drawOval},
976 {"native_drawCircle","(IFFFI)V", (void*) SkCanvasGlue::drawCircle},
977 {"native_drawArc","(ILandroid/graphics/RectF;FFZI)V",
978 (void*) SkCanvasGlue::drawArc},
979 {"native_drawRoundRect","(ILandroid/graphics/RectF;FFI)V",
980 (void*) SkCanvasGlue::drawRoundRect},
981 {"native_drawPath","(III)V", (void*) SkCanvasGlue::drawPath},
982 {"native_drawBitmap","(IIFFIIII)V",
983 (void*) SkCanvasGlue::drawBitmap__BitmapFFPaint},
984 {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;III)V",
985 (void*) SkCanvasGlue::drawBitmapRF},
986 {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;III)V",
987 (void*) SkCanvasGlue::drawBitmapRR},
988 {"native_drawBitmap", "(I[IIIFFIIZI)V",
989 (void*)SkCanvasGlue::drawBitmapArray},
990 {"nativeDrawBitmapMatrix", "(IIII)V",
991 (void*)SkCanvasGlue::drawBitmapMatrix},
992 {"nativeDrawBitmapMesh", "(IIII[FI[III)V",
993 (void*)SkCanvasGlue::drawBitmapMesh},
994 {"nativeDrawVertices", "(III[FI[FI[II[SIII)V",
995 (void*)SkCanvasGlue::drawVertices},
996 {"native_drawText","(I[CIIFFII)V",
997 (void*) SkCanvasGlue::drawText___CIIFFIPaint},
998 {"native_drawText","(ILjava/lang/String;IIFFII)V",
999 (void*) SkCanvasGlue::drawText__StringIIFFIPaint},
1000 {"native_drawTextRun","(I[CIIIIFFII)V",
1001 (void*) SkCanvasGlue::drawTextRun___CIIIIFFIPaint},
1002 {"native_drawTextRun","(ILjava/lang/String;IIIIFFII)V",
1003 (void*) SkCanvasGlue::drawTextRun__StringIIIIFFIPaint},
1004 {"native_drawPosText","(I[CII[FI)V",
1005 (void*) SkCanvasGlue::drawPosText___CII_FPaint},
1006 {"native_drawPosText","(ILjava/lang/String;[FI)V",
1007 (void*) SkCanvasGlue::drawPosText__String_FPaint},
1008 {"native_drawTextOnPath","(I[CIIIFFII)V",
1009 (void*) SkCanvasGlue::drawTextOnPath___CIIPathFFPaint},
1010 {"native_drawTextOnPath","(ILjava/lang/String;IFFII)V",
1011 (void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint},
1012 {"native_drawPicture", "(II)V", (void*) SkCanvasGlue::drawPicture},
1013
1014 {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches}
1015 };
1016
1017 ///////////////////////////////////////////////////////////////////////////////
1018
1019 #include <android_runtime/AndroidRuntime.h>
1020
1021 #define REG(env, name, array) \
1022 result = android::AndroidRuntime::registerNativeMethods(env, name, array, \
1023 SK_ARRAY_COUNT(array)); \
1024 if (result < 0) return result
1025
register_android_graphics_Canvas(JNIEnv * env)1026 int register_android_graphics_Canvas(JNIEnv* env) {
1027 int result;
1028
1029 REG(env, "android/graphics/Canvas", gCanvasMethods);
1030
1031 return result;
1032 }
1033
1034 }
1035