android_graphics_Canvas.cpp revision 6e49c9f007c879f05b035c40c0ba543c00f9d0d0
18872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger/*
28872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger * Copyright (C) 2014 The Android Open Source Project
38872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger *
48872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger * Licensed under the Apache License, Version 2.0 (the "License");
58872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger * you may not use this file except in compliance with the License.
68872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger * You may obtain a copy of the License at
78872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger *
88872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger *      http://www.apache.org/licenses/LICENSE-2.0
98872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger *
108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger * Unless required by applicable law or agreed to in writing, software
118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger * distributed under the License is distributed on an "AS IS" BASIS,
128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger * See the License for the specific language governing permissions and
148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger * limitations under the License.
158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger */
168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "jni.h"
188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "GraphicsJNI.h"
19ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h"
208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
214c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger#include <androidfw/ResourceTypes.h>
22dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/Canvas.h>
23dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/Paint.h>
24bad99183916ba2bac6659efc8a28273e344ba511sergeyv#include <hwui/Typeface.h>
25dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <minikin/Layout.h>
264c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
274c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger#include "Bitmap.h"
28acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger#include "SkDrawFilter.h"
298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "SkGraphics.h"
308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergernamespace android {
328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergernamespace CanvasJNI {
348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic Canvas* get_canvas(jlong canvasHandle) {
368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return reinterpret_cast<Canvas*>(canvasHandle);
378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
39775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhlerstatic void delete_canvas(Canvas* canvas) {
40775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler    delete canvas;
41775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler}
42775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler
43775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhlerstatic jlong getNativeFinalizer(JNIEnv* env, jobject clazz) {
44775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&delete_canvas));
458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// Native wrapper constructor used by Canvas(Bitmap)
48c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reckstatic jlong initRaster(JNIEnv* env, jobject, jobject jbitmap) {
493731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    SkBitmap bitmap;
50c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reck    if (jbitmap != NULL) {
513731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
52c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reck    }
533731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    return reinterpret_cast<jlong>(Canvas::create_canvas(bitmap));
548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// Set the given bitmap as the new draw target (wrapped in a new SkCanvas),
578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// optionally copying canvas matrix & clip state.
58c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reckstatic void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap) {
593731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    SkBitmap bitmap;
60c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reck    if (jbitmap != NULL) {
613731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
62c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reck    }
633731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    get_canvas(canvasHandle)->setBitmap(bitmap);
648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean isOpaque(JNIEnv*, jobject, jlong canvasHandle) {
678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return get_canvas(canvasHandle)->isOpaque() ? JNI_TRUE : JNI_FALSE;
688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint getWidth(JNIEnv*, jobject, jlong canvasHandle) {
718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->width());
728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint getHeight(JNIEnv*, jobject, jlong canvasHandle) {
758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->height());
768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
786578a989566e585eee053095dc80e2552e125db2Derek Sollenbergerstatic void setHighContrastText(JNIEnv*, jobject, jlong canvasHandle, jboolean highContrastText) {
796578a989566e585eee053095dc80e2552e125db2Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
806578a989566e585eee053095dc80e2552e125db2Derek Sollenberger    canvas->setHighContrastText(highContrastText);
816578a989566e585eee053095dc80e2552e125db2Derek Sollenberger}
826578a989566e585eee053095dc80e2552e125db2Derek Sollenberger
838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint getSaveCount(JNIEnv*, jobject, jlong canvasHandle) {
848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->getSaveCount());
858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint save(JNIEnv*, jobject, jlong canvasHandle, jint flagsHandle) {
88eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita    SaveFlags::Flags flags = static_cast<SaveFlags::Flags>(flagsHandle);
898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->save(flags));
908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint saveLayer(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t,
938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                      jfloat r, jfloat b, jlong paintHandle, jint flagsHandle) {
946ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint  = reinterpret_cast<Paint*>(paintHandle);
95eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita    SaveFlags::Flags flags = static_cast<SaveFlags::Flags>(flagsHandle);
968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->saveLayer(l, t, r, b, paint, flags));
978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint saveLayerAlpha(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t,
1008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jfloat r, jfloat b, jint alpha, jint flagsHandle) {
101eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita    SaveFlags::Flags flags = static_cast<SaveFlags::Flags>(flagsHandle);
1028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->saveLayerAlpha(l, t, r, b, alpha, flags));
1038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1053891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craikstatic void restore(JNIEnv* env, jobject, jlong canvasHandle, jboolean throwOnUnderflow) {
1068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
1078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (canvas->getSaveCount() <= 1) {  // cannot restore anymore
1083891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        if (throwOnUnderflow) {
1093891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik            doThrowISE(env, "Underflow in restore - more restores than saves");
1103891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        }
1113891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        return; // compat behavior - return without throwing
1128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
1138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    canvas->restore();
1148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1163891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craikstatic void restoreToCount(JNIEnv* env, jobject, jlong canvasHandle, jint restoreCount,
1173891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        jboolean throwOnUnderflow) {
1188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
1198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (restoreCount < 1 || restoreCount > canvas->getSaveCount()) {
1203891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        if (throwOnUnderflow) {
1213891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik            doThrowIAE(env, "Underflow in restoreToCount - more restores than saves");
1223891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik            return;
1233891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        }
1243891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        restoreCount = 1; // compat behavior - restore as far as possible
1258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
1268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    canvas->restoreToCount(restoreCount);
1278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void getCTM(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) {
1308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
1318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->getMatrix(matrix);
1328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void setMatrix(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) {
1358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
1368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->setMatrix(matrix ? *matrix : SkMatrix::I());
1378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void concat(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) {
1408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
1418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->concat(*matrix);
1428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void rotate(JNIEnv*, jobject, jlong canvasHandle, jfloat degrees) {
1458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->rotate(degrees);
1468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void scale(JNIEnv*, jobject, jlong canvasHandle, jfloat sx, jfloat sy) {
1498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->scale(sx, sy);
1508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void skew(JNIEnv*, jobject, jlong canvasHandle, jfloat sx, jfloat sy) {
1538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->skew(sx, sy);
1548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void translate(JNIEnv*, jobject, jlong canvasHandle, jfloat dx, jfloat dy) {
1578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->translate(dx, dy);
1588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean getClipBounds(JNIEnv* env, jobject, jlong canvasHandle, jobject bounds) {
1618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkRect   r;
1628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkIRect ir;
1638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool result = get_canvas(canvasHandle)->getClipBounds(&r);
1648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (!result) {
1668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        r.setEmpty();
1678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
1688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    r.round(&ir);
1698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    (void)GraphicsJNI::irect_to_jrect(ir, env, bounds);
1718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return result ? JNI_TRUE : JNI_FALSE;
1728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean quickRejectRect(JNIEnv* env, jobject, jlong canvasHandle,
1758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jfloat left, jfloat top, jfloat right, jfloat bottom) {
1768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool result = get_canvas(canvasHandle)->quickRejectRect(left, top, right, bottom);
1778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return result ? JNI_TRUE : JNI_FALSE;
1788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean quickRejectPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle) {
1818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
1828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool result = get_canvas(canvasHandle)->quickRejectPath(*path);
1838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return result ? JNI_TRUE : JNI_FALSE;
1848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1866e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed// SkRegion::Op and SkClipOp are numerically identical, so we can freely cast
1876e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed// from one to the other (though SkClipOp is destined to become a strict subset)
1886e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedstatic_assert(SkRegion::kDifference_Op == static_cast<SkRegion::Op>(kDifference_SkClipOp), "");
1896e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedstatic_assert(SkRegion::kIntersect_Op == static_cast<SkRegion::Op>(kIntersect_SkClipOp), "");
1906e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedstatic_assert(SkRegion::kUnion_Op == static_cast<SkRegion::Op>(kUnion_SkClipOp), "");
1916e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedstatic_assert(SkRegion::kXOR_Op == static_cast<SkRegion::Op>(kXOR_SkClipOp), "");
1926e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedstatic_assert(SkRegion::kReverseDifference_Op == static_cast<SkRegion::Op>(kReverseDifference_SkClipOp), "");
1936e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedstatic_assert(SkRegion::kReplace_Op == static_cast<SkRegion::Op>(kReplace_SkClipOp), "");
1946e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed
1956e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedstatic SkClipOp opHandleToClipOp(jint opHandle) {
1966e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // The opHandle is defined in Canvas.java to be Region::Op
1976e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    SkRegion::Op rgnOp = static_cast<SkRegion::Op>(opHandle);
1986e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed
1996e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // In the future, when we no longer support the wide range of ops (e.g. Union, Xor)
2006e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // this function can perform a range check and throw an unsupported-exception.
2016e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // e.g. if (rgnOp != kIntersect && rgnOp != kDifference) throw...
2026e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed
2036e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // Skia now takes a different type, SkClipOp, as the parameter to clipping calls
2046e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // This type is binary compatible with SkRegion::Op, so a static_cast<> is safe.
2056e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    return static_cast<SkClipOp>(rgnOp);
2066e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed}
2076e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed
2088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean clipRect(JNIEnv*, jobject, jlong canvasHandle, jfloat l, jfloat t,
2098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jfloat r, jfloat b, jint opHandle) {
2106e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    bool nonEmptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b,
2116e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed            opHandleToClipOp(opHandle));
2125ec6a2878b2ad933c5da6fe2341c854155acc24cChris Craik    return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
2138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean clipPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle,
2168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jint opHandle) {
2178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
2186e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    bool nonEmptyClip = get_canvas(canvasHandle)->clipPath(path, opHandleToClipOp(opHandle));
2195ec6a2878b2ad933c5da6fe2341c854155acc24cChris Craik    return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
2208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean clipRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong deviceRgnHandle,
2238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint opHandle) {
2248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkRegion* deviceRgn = reinterpret_cast<SkRegion*>(deviceRgnHandle);
2256e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    bool nonEmptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, opHandleToClipOp(opHandle));
2265ec6a2878b2ad933c5da6fe2341c854155acc24cChris Craik    return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
2278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawColor(JNIEnv* env, jobject, jlong canvasHandle, jint color, jint modeHandle) {
230260ab726486317496bc12a57d599ea96dcde3284Mike Reed    SkBlendMode mode = static_cast<SkBlendMode>(modeHandle);
2311526a458a30184609f19b05e7334da3cbde81dd1Chris Craik    get_canvas(canvasHandle)->drawColor(color, mode);
2328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPaint(JNIEnv* env, jobject, jlong canvasHandle, jlong paintHandle) {
2356ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPaint(*paint);
2378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPoint(JNIEnv*, jobject, jlong canvasHandle, jfloat x, jfloat y,
2408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                      jlong paintHandle) {
2416ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPoint(x, y, *paint);
2438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPoints(JNIEnv* env, jobject, jlong canvasHandle, jfloatArray jptsArray,
2468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jint offset, jint count, jlong paintHandle) {
2478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    NPE_CHECK_RETURN_VOID(env, jptsArray);
2488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray autoPts(env, jptsArray);
2498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    float* floats = autoPts.ptr();
2508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int length = autoPts.length();
2518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if ((offset | count) < 0 || offset + count > length) {
2538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        doThrowAIOOBE(env);
2548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
2558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
2568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2576ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPoints(floats + offset, count, *paint);
2598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawLine(JNIEnv* env, jobject, jlong canvasHandle, jfloat startX, jfloat startY,
2628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jfloat stopX, jfloat stopY, jlong paintHandle) {
2636ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawLine(startX, startY, stopX, stopY, *paint);
2658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawLines(JNIEnv* env, jobject, jlong canvasHandle, jfloatArray jptsArray,
2688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                      jint offset, jint count, jlong paintHandle) {
2698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    NPE_CHECK_RETURN_VOID(env, jptsArray);
2708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray autoPts(env, jptsArray);
2718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    float* floats = autoPts.ptr();
2728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int length = autoPts.length();
2738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if ((offset | count) < 0 || offset + count > length) {
2758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        doThrowAIOOBE(env);
2768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
2778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
2788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2796ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawLines(floats + offset, count, *paint);
2818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
2848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jfloat right, jfloat bottom, jlong paintHandle) {
2856ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawRect(left, top, right, bottom, *paint);
2878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
28994394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenbergerstatic void drawRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong regionHandle,
29094394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger                       jlong paintHandle) {
29194394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger    const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
29294394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
29394394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger    get_canvas(canvasHandle)->drawRegion(*region, *paint);
29494394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger}
29594394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger
2968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawRoundRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
2978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                          jfloat right, jfloat bottom, jfloat rx, jfloat ry, jlong paintHandle) {
2986ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawRoundRect(left, top, right, bottom, rx, ry, *paint);
3008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawCircle(JNIEnv* env, jobject, jlong canvasHandle, jfloat cx, jfloat cy,
3038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jfloat radius, jlong paintHandle) {
3046ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawCircle(cx, cy, radius, *paint);
3068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawOval(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
3098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jfloat right, jfloat bottom, jlong paintHandle) {
3106ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawOval(left, top, right, bottom, *paint);
3128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawArc(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
3158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                    jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle,
3168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                    jboolean useCenter, jlong paintHandle) {
3176ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawArc(left, top, right, bottom, startAngle, sweepAngle,
3198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       useCenter, *paint);
3208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle,
3238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jlong paintHandle) {
3248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
3256ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPath(*path, *paint);
3278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawVertices(JNIEnv* env, jobject, jlong canvasHandle,
3308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jint modeHandle, jint vertexCount,
3318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jfloatArray jverts, jint vertIndex,
3328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jfloatArray jtexs, jint texIndex,
3338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jintArray jcolors, jint colorIndex,
3348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jshortArray jindices, jint indexIndex,
3358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jint indexCount, jlong paintHandle) {
3368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray  vertA(env, jverts, vertIndex + vertexCount);
3378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray  texA(env, jtexs, texIndex + vertexCount);
3388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaIntArray    colorA(env, jcolors, colorIndex + vertexCount);
3398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaShortArray  indexA(env, jindices, indexIndex + indexCount);
3408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const float* verts = vertA.ptr() + vertIndex;
3428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const float* texs = texA.ptr() + vertIndex;
3438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int* colors = NULL;
3448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const uint16_t* indices = NULL;
3458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (jcolors != NULL) {
3478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        colors = colorA.ptr() + colorIndex;
3488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
3498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (jindices != NULL) {
3508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        indices = (const uint16_t*)(indexA.ptr() + indexIndex);
3518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
3528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkCanvas::VertexMode mode = static_cast<SkCanvas::VertexMode>(modeHandle);
3546ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawVertices(mode, vertexCount, verts, texs, colors,
3568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                           indices, indexCount, *paint);
3578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3594c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenbergerstatic void drawNinePatch(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
3604c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        jlong chunkHandle, jfloat left, jfloat top, jfloat right, jfloat bottom,
3614c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        jlong paintHandle, jint dstDensity, jint srcDensity) {
3624c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3634c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
3645fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv    Bitmap& bitmap = android::bitmap::toBitmap(env, bitmapHandle);
3654c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    const android::Res_png_9patch* chunk = reinterpret_cast<android::Res_png_9patch*>(chunkHandle);
3664c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3674c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3684c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    if (CC_LIKELY(dstDensity == srcDensity || dstDensity == 0 || srcDensity == 0)) {
3695fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv        canvas->drawNinePatch(bitmap, *chunk, left, top, right, bottom, paint);
3704c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    } else {
371eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita        canvas->save(SaveFlags::MatrixClip);
3724c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3734c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        SkScalar scale = dstDensity / (float)srcDensity;
3744c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        canvas->translate(left, top);
3754c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        canvas->scale(scale, scale);
3764c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3774c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        Paint filteredPaint;
3784c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        if (paint) {
3794c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger            filteredPaint = *paint;
3804c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        }
3814c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        filteredPaint.setFilterQuality(kLow_SkFilterQuality);
3824c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3835fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv        canvas->drawNinePatch(bitmap, *chunk, 0, 0, (right-left)/scale, (bottom-top)/scale,
3844c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger                &filteredPaint);
3854c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3864c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        canvas->restore();
3874c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    }
3884c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger}
3894c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
390caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reckstatic void drawBitmap(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
3918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jfloat left, jfloat top, jlong paintHandle, jint canvasDensity,
3928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jint screenDensity, jint bitmapDensity) {
3938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
394aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
3956ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (canvasDensity == bitmapDensity || canvasDensity == 0 || bitmapDensity == 0) {
3988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        if (screenDensity != 0 && screenDensity != bitmapDensity) {
3996ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod            Paint filteredPaint;
4008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            if (paint) {
4018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                filteredPaint = *paint;
4028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            }
4032a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed            filteredPaint.setFilterQuality(kLow_SkFilterQuality);
4047c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck            canvas->drawBitmap(bitmap, left, top, &filteredPaint);
4058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        } else {
4067c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck            canvas->drawBitmap(bitmap, left, top, paint);
4078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
4088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    } else {
409eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita        canvas->save(SaveFlags::MatrixClip);
4108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        SkScalar scale = canvasDensity / (float)bitmapDensity;
4118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->translate(left, top);
4128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->scale(scale, scale);
4138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4146ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod        Paint filteredPaint;
4158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        if (paint) {
4168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            filteredPaint = *paint;
4178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
4182a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed        filteredPaint.setFilterQuality(kLow_SkFilterQuality);
4198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4207c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        canvas->drawBitmap(bitmap, 0, 0, &filteredPaint);
4218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->restore();
4228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4257c103a36f60b690e3fe83c40210e1cb0c76bba43John Reckstatic void drawBitmapMatrix(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
4268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                             jlong matrixHandle, jlong paintHandle) {
4278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
4286ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
429fc9999505a36c66892d7ccce85187936105f4f36sergeyv    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
4307c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck    get_canvas(canvasHandle)->drawBitmap(bitmap, *matrix, paint);
4318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4337c103a36f60b690e3fe83c40210e1cb0c76bba43John Reckstatic void drawBitmapRect(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
4348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           float srcLeft, float srcTop, float srcRight, float srcBottom,
4358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           float dstLeft, float dstTop, float dstRight, float dstBottom,
4368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jlong paintHandle, jint screenDensity, jint bitmapDensity) {
4378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
4386ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
4398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
440fc9999505a36c66892d7ccce85187936105f4f36sergeyv    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
4418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (screenDensity != 0 && screenDensity != bitmapDensity) {
4426ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod        Paint filteredPaint;
4438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        if (paint) {
4448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            filteredPaint = *paint;
4458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
4462a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed        filteredPaint.setFilterQuality(kLow_SkFilterQuality);
4477c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        canvas->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
4488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           dstLeft, dstTop, dstRight, dstBottom, &filteredPaint);
4498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    } else {
4507c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        canvas->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
4518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           dstLeft, dstTop, dstRight, dstBottom, paint);
4528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmapArray(JNIEnv* env, jobject, jlong canvasHandle,
4568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                            jintArray jcolors, jint offset, jint stride,
4578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                            jfloat x, jfloat y, jint width, jint height,
4588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                            jboolean hasAlpha, jlong paintHandle) {
4598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    // Note: If hasAlpha is false, kRGB_565_SkColorType will be used, which will
4608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    // correct the alphaType to kOpaque_SkAlphaType.
461253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy    SkImageInfo info = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType,
462253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy            GraphicsJNI::defaultColorSpace());
4638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkBitmap bitmap;
4643d4eed7f1aa99401dabe2e45b82f98fb4fc2d754Derek Sollenberger    bitmap.setInfo(info);
465c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    sk_sp<Bitmap> androidBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL);
466c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    if (!androidBitmap) {
4678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
4688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (!GraphicsJNI::SetPixels(env, jcolors, offset, stride, 0, 0, width, height, bitmap)) {
4718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
4728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4746ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
475aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    get_canvas(canvasHandle)->drawBitmap(*androidBitmap, x, y, paint);
4768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4787c103a36f60b690e3fe83c40210e1cb0c76bba43John Reckstatic void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
4798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint meshWidth, jint meshHeight, jfloatArray jverts,
4808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint vertIndex, jintArray jcolors, jint colorIndex, jlong paintHandle) {
4818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int ptCount = (meshWidth + 1) * (meshHeight + 1);
4828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1));
4838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount);
4848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4856ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
4865fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
4877c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck    get_canvas(canvasHandle)->drawBitmapMesh(bitmap, meshWidth, meshHeight,
4888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                             vertA.ptr(), colorA.ptr(), paint);
4898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
4928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                          jint index, jint count, jfloat x, jfloat y, jint bidiFlags,
4938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                          jlong paintHandle, jlong typefaceHandle) {
4946ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
495bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
4968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jchar* jchars = env->GetCharArrayElements(text, NULL);
497dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawText(jchars + index, 0, count, count, x, y,
4988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       bidiFlags, *paint, typeface);
4998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
5008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring text,
5038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint start, jint end, jfloat x, jfloat y, jint bidiFlags,
5048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jlong paintHandle, jlong typefaceHandle) {
5056ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
506bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
5078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int count = end - start;
5088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const jchar* jchars = env->GetStringChars(text, NULL);
509dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawText(jchars + start, 0, count, count, x, y,
5108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       bidiFlags, *paint, typeface);
5118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseStringChars(text, jchars);
5128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, jint index,
5158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                             jint count, jint contextIndex, jint contextCount, jfloat x, jfloat y,
5168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                             jboolean isRtl, jlong paintHandle, jlong typefaceHandle) {
5176ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
518bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
5198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
520ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    const int bidiFlags = isRtl ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR;
5218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jchar* jchars = env->GetCharArrayElements(text, NULL);
522dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawText(jchars + contextIndex, index - contextIndex, count,
5238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       contextCount, x, y, bidiFlags, *paint, typeface);
5248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
5258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextRunString(JNIEnv* env, jobject obj, jlong canvasHandle, jstring text,
5288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                              jint start, jint end, jint contextStart, jint contextEnd,
5298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                              jfloat x, jfloat y, jboolean isRtl, jlong paintHandle,
5308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                              jlong typefaceHandle) {
5316ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
532bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
5338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
534ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    int bidiFlags = isRtl ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR;
5358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jint count = end - start;
5368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jint contextCount = contextEnd - contextStart;
5378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const jchar* jchars = env->GetStringChars(text, NULL);
538dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawText(jchars + contextStart, start - contextStart, count,
5398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       contextCount, x, y, bidiFlags, *paint, typeface);
5408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseStringChars(text, jchars);
5418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
5448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jint index, jint count, jlong pathHandle, jfloat hOffset,
5458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jfloat vOffset, jint bidiFlags, jlong paintHandle,
5468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jlong typefaceHandle) {
5478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
5486ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
549bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
5508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jchar* jchars = env->GetCharArrayElements(text, NULL);
5528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
553dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawTextOnPath(jchars + index, count, bidiFlags, *path,
5548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                   hOffset, vOffset, *paint, typeface);
5558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseCharArrayElements(text, jchars, 0);
5578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextOnPathString(JNIEnv* env, jobject, jlong canvasHandle, jstring text,
5608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                 jlong pathHandle, jfloat hOffset, jfloat vOffset,
5618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                 jint bidiFlags, jlong paintHandle, jlong typefaceHandle) {
5628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
5636ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
564bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
5658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const jchar* jchars = env->GetStringChars(text, NULL);
5678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    int count = env->GetStringLength(text);
5688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
569dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawTextOnPath(jchars, count, bidiFlags, *path,
5708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                   hOffset, vOffset, *paint, typeface);
5718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseStringChars(text, jchars);
5738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void setDrawFilter(JNIEnv* env, jobject, jlong canvasHandle, jlong filterHandle) {
5768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->setDrawFilter(reinterpret_cast<SkDrawFilter*>(filterHandle));
5778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void freeCaches(JNIEnv* env, jobject) {
5808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkGraphics::PurgeFontCache();
5818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void freeTextLayoutCaches(JNIEnv* env, jobject) {
584ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    minikin::Layout::purgeCaches();
5858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}; // namespace CanvasJNI
5888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
58976f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = {
590caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nGetNativeFinalizer", "()J", (void*) CanvasJNI::getNativeFinalizer},
591caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nInitRaster", "(Landroid/graphics/Bitmap;)J", (void*) CanvasJNI::initRaster},
592caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nFreeCaches", "()V", (void*) CanvasJNI::freeCaches},
593caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nFreeTextLayoutCaches", "()V", (void*) CanvasJNI::freeTextLayoutCaches},
5945cb74bca88268a8b9025be2cce81e1b4f967d19dJohn Reck
5955cb74bca88268a8b9025be2cce81e1b4f967d19dJohn Reck    // ------------ @FastNative ----------------
596caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSetBitmap", "(JLandroid/graphics/Bitmap;)V", (void*) CanvasJNI::setBitmap},
597caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nIsOpaque","(J)Z", (void*) CanvasJNI::isOpaque},
598caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nGetWidth","(J)I", (void*) CanvasJNI::getWidth},
599caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nGetHeight","(J)I", (void*) CanvasJNI::getHeight},
600caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSetHighContrastText","(JZ)V", (void*) CanvasJNI::setHighContrastText},
601caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSave","(JI)I", (void*) CanvasJNI::save},
602caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSaveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer},
603caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSaveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha},
604caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nGetSaveCount","(J)I", (void*) CanvasJNI::getSaveCount},
605caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nRestore","(JZ)V", (void*) CanvasJNI::restore},
606caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nRestoreToCount","(JIZ)V", (void*) CanvasJNI::restoreToCount},
607caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nGetCTM", "(JJ)V", (void*)CanvasJNI::getCTM},
608caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSetMatrix","(JJ)V", (void*) CanvasJNI::setMatrix},
609caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nConcat","(JJ)V", (void*) CanvasJNI::concat},
610caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nRotate","(JF)V", (void*) CanvasJNI::rotate},
611caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nScale","(JFF)V", (void*) CanvasJNI::scale},
612caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSkew","(JFF)V", (void*) CanvasJNI::skew},
613caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nTranslate","(JFF)V", (void*) CanvasJNI::translate},
614caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nGetClipBounds","(JLandroid/graphics/Rect;)Z", (void*) CanvasJNI::getClipBounds},
615caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nQuickReject","(JJ)Z", (void*) CanvasJNI::quickRejectPath},
616caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nQuickReject","(JFFFF)Z", (void*)CanvasJNI::quickRejectRect},
617caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nClipRect","(JFFFFI)Z", (void*) CanvasJNI::clipRect},
618caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nClipPath","(JJI)Z", (void*) CanvasJNI::clipPath},
619caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nClipRegion","(JJI)Z", (void*) CanvasJNI::clipRegion},
620caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSetDrawFilter", "(JJ)V", (void*) CanvasJNI::setDrawFilter},
621caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck};
622caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck
623caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck// If called from Canvas these are regular JNI
624caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck// If called from DisplayListCanvas they are @FastNative
625caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reckstatic const JNINativeMethod gDrawMethods[] = {
626caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawColor","(JII)V", (void*) CanvasJNI::drawColor},
627caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawPaint","(JJ)V", (void*) CanvasJNI::drawPaint},
628caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawPoint", "(JFFJ)V", (void*) CanvasJNI::drawPoint},
629caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawPoints", "(J[FIIJ)V", (void*) CanvasJNI::drawPoints},
630caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawLine", "(JFFFFJ)V", (void*) CanvasJNI::drawLine},
631caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawLines", "(J[FIIJ)V", (void*) CanvasJNI::drawLines},
632caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawRect","(JFFFFJ)V", (void*) CanvasJNI::drawRect},
633caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawRegion", "(JJJ)V", (void*) CanvasJNI::drawRegion },
634caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawRoundRect","(JFFFFFFJ)V", (void*) CanvasJNI::drawRoundRect},
635caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawCircle","(JFFFJ)V", (void*) CanvasJNI::drawCircle},
636caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawOval","(JFFFFJ)V", (void*) CanvasJNI::drawOval},
637caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawArc","(JFFFFFFZJ)V", (void*) CanvasJNI::drawArc},
638caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawPath","(JJJ)V", (void*) CanvasJNI::drawPath},
639caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawVertices", "(JII[FI[FI[II[SIIJ)V", (void*)CanvasJNI::drawVertices},
640caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawNinePatch", "(JJJFFFFJII)V", (void*)CanvasJNI::drawNinePatch},
641caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawBitmapMatrix", "(JLandroid/graphics/Bitmap;JJ)V", (void*)CanvasJNI::drawBitmapMatrix},
642caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawBitmapMesh", "(JLandroid/graphics/Bitmap;II[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh},
643caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawBitmap","(JLandroid/graphics/Bitmap;FFJIII)V", (void*) CanvasJNI::drawBitmap},
644caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawBitmap","(JLandroid/graphics/Bitmap;FFFFFFFFJII)V", (void*) CanvasJNI::drawBitmapRect},
645caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawBitmap", "(J[IIIFFIIZJ)V", (void*)CanvasJNI::drawBitmapArray},
646caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawText","(J[CIIFFIJJ)V", (void*) CanvasJNI::drawTextChars},
647caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawText","(JLjava/lang/String;IIFFIJJ)V", (void*) CanvasJNI::drawTextString},
648caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawTextRun","(J[CIIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunChars},
649caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawTextRun","(JLjava/lang/String;IIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunString},
650caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawTextOnPath","(J[CIIJFFIJJ)V", (void*) CanvasJNI::drawTextOnPathChars},
651caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nDrawTextOnPath","(JLjava/lang/String;JFFIJJ)V", (void*) CanvasJNI::drawTextOnPathString},
6528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger};
6538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
6548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerint register_android_graphics_Canvas(JNIEnv* env) {
655caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    int ret = 0;
656caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    ret |= RegisterMethodsOrDie(env, "android/graphics/Canvas", gMethods, NELEM(gMethods));
657caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    ret |= RegisterMethodsOrDie(env, "android/graphics/BaseCanvas", gDrawMethods, NELEM(gDrawMethods));
658caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    ret |= RegisterMethodsOrDie(env, "android/view/RecordingCanvas", gDrawMethods, NELEM(gDrawMethods));
659caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    return ret;
660caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck
6618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
6628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
6638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}; // namespace android
664