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"
303318f8bf0cba473822a8ecc4bb632e6755be4226Mike Reed#include "SkRegion.h"
318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergernamespace android {
338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergernamespace CanvasJNI {
358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic Canvas* get_canvas(jlong canvasHandle) {
378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return reinterpret_cast<Canvas*>(canvasHandle);
388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
40775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhlerstatic void delete_canvas(Canvas* canvas) {
41775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler    delete canvas;
42775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler}
43775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler
44775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhlerstatic jlong getNativeFinalizer(JNIEnv* env, jobject clazz) {
45775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&delete_canvas));
468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// Native wrapper constructor used by Canvas(Bitmap)
49c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reckstatic jlong initRaster(JNIEnv* env, jobject, jobject jbitmap) {
503731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    SkBitmap bitmap;
51c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reck    if (jbitmap != NULL) {
523731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
53c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reck    }
543731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    return reinterpret_cast<jlong>(Canvas::create_canvas(bitmap));
558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// Set the given bitmap as the new draw target (wrapped in a new SkCanvas),
588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// optionally copying canvas matrix & clip state.
59c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reckstatic void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap) {
603731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    SkBitmap bitmap;
61c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reck    if (jbitmap != NULL) {
623731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
63c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reck    }
643731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    get_canvas(canvasHandle)->setBitmap(bitmap);
658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
67bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jboolean isOpaque(jlong canvasHandle) {
688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return get_canvas(canvasHandle)->isOpaque() ? JNI_TRUE : JNI_FALSE;
698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
71bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jint getWidth(jlong canvasHandle) {
728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->width());
738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
75bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jint getHeight(jlong canvasHandle) {
768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->height());
778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
79bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic void setHighContrastText(jlong canvasHandle, jboolean highContrastText) {
806578a989566e585eee053095dc80e2552e125db2Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
816578a989566e585eee053095dc80e2552e125db2Derek Sollenberger    canvas->setHighContrastText(highContrastText);
826578a989566e585eee053095dc80e2552e125db2Derek Sollenberger}
836578a989566e585eee053095dc80e2552e125db2Derek Sollenberger
84bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jint save(jlong canvasHandle, jint flagsHandle) {
85eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita    SaveFlags::Flags flags = static_cast<SaveFlags::Flags>(flagsHandle);
868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->save(flags));
878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
89bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jint saveLayer(jlong canvasHandle, jfloat l, jfloat t,
908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                      jfloat r, jfloat b, jlong paintHandle, jint flagsHandle) {
916ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint  = reinterpret_cast<Paint*>(paintHandle);
92eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita    SaveFlags::Flags flags = static_cast<SaveFlags::Flags>(flagsHandle);
938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->saveLayer(l, t, r, b, paint, flags));
948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
96bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jint saveLayerAlpha(jlong canvasHandle, jfloat l, jfloat t,
978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jfloat r, jfloat b, jint alpha, jint flagsHandle) {
98eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita    SaveFlags::Flags flags = static_cast<SaveFlags::Flags>(flagsHandle);
998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->saveLayerAlpha(l, t, r, b, alpha, flags));
1008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
102bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic bool restore(jlong canvasHandle) {
1038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
104bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik    if (canvas->getSaveCount() <= 1) {
105bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik        return false; // cannot restore anymore
1068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
1078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    canvas->restore();
108bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik    return true; // success
1098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
111bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic void restoreToCount(jlong canvasHandle, jint saveCount) {
1128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
113bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik    canvas->restoreToCount(saveCount);
1148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
116bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jint getSaveCount(jlong canvasHandle) {
117bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik    return static_cast<jint>(get_canvas(canvasHandle)->getSaveCount());
118bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik}
119bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik
120bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic void getMatrix(jlong canvasHandle, jlong matrixHandle) {
1218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
1228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->getMatrix(matrix);
1238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
125bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic void setMatrix(jlong canvasHandle, jlong matrixHandle) {
1268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
1278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->setMatrix(matrix ? *matrix : SkMatrix::I());
1288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
130bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic void concat(jlong canvasHandle, jlong matrixHandle) {
1318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
1328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->concat(*matrix);
1338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
135bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic void rotate(jlong canvasHandle, jfloat degrees) {
1368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->rotate(degrees);
1378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
139bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic void scale(jlong canvasHandle, jfloat sx, jfloat sy) {
1408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->scale(sx, sy);
1418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
143bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic void skew(jlong canvasHandle, jfloat sx, jfloat sy) {
1448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->skew(sx, sy);
1458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
147bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic void translate(jlong canvasHandle, jfloat dx, jfloat dy) {
1488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->translate(dx, dy);
1498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean getClipBounds(JNIEnv* env, jobject, jlong canvasHandle, jobject bounds) {
1528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkRect   r;
1538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkIRect ir;
1548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool result = get_canvas(canvasHandle)->getClipBounds(&r);
1558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (!result) {
1578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        r.setEmpty();
1588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
1598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    r.round(&ir);
1608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    (void)GraphicsJNI::irect_to_jrect(ir, env, bounds);
1628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return result ? JNI_TRUE : JNI_FALSE;
1638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
165bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jboolean quickRejectRect(jlong canvasHandle,
1668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jfloat left, jfloat top, jfloat right, jfloat bottom) {
1678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool result = get_canvas(canvasHandle)->quickRejectRect(left, top, right, bottom);
1688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return result ? JNI_TRUE : JNI_FALSE;
1698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
171bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jboolean quickRejectPath(jlong canvasHandle, jlong pathHandle) {
1728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
1738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool result = get_canvas(canvasHandle)->quickRejectPath(*path);
1748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return result ? JNI_TRUE : JNI_FALSE;
1758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1776e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed// SkRegion::Op and SkClipOp are numerically identical, so we can freely cast
1786e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed// from one to the other (though SkClipOp is destined to become a strict subset)
1796c67f1d04591f44bccb476d715a005ad5bbdf840Mike Reedstatic_assert(SkRegion::kDifference_Op == static_cast<SkRegion::Op>(SkClipOp::kDifference), "");
1806c67f1d04591f44bccb476d715a005ad5bbdf840Mike Reedstatic_assert(SkRegion::kIntersect_Op == static_cast<SkRegion::Op>(SkClipOp::kIntersect), "");
181a0a74d5f8ee1dbd04772ffb1775d045ce6b5934bMike Reedstatic_assert(SkRegion::kUnion_Op == static_cast<SkRegion::Op>(SkClipOp::kUnion_deprecated), "");
182a0a74d5f8ee1dbd04772ffb1775d045ce6b5934bMike Reedstatic_assert(SkRegion::kXOR_Op == static_cast<SkRegion::Op>(SkClipOp::kXOR_deprecated), "");
183a0a74d5f8ee1dbd04772ffb1775d045ce6b5934bMike Reedstatic_assert(SkRegion::kReverseDifference_Op == static_cast<SkRegion::Op>(SkClipOp::kReverseDifference_deprecated), "");
184a0a74d5f8ee1dbd04772ffb1775d045ce6b5934bMike Reedstatic_assert(SkRegion::kReplace_Op == static_cast<SkRegion::Op>(SkClipOp::kReplace_deprecated), "");
1856e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed
1866e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedstatic SkClipOp opHandleToClipOp(jint opHandle) {
1876e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // The opHandle is defined in Canvas.java to be Region::Op
1886e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    SkRegion::Op rgnOp = static_cast<SkRegion::Op>(opHandle);
1896e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed
1906e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // In the future, when we no longer support the wide range of ops (e.g. Union, Xor)
1916e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // this function can perform a range check and throw an unsupported-exception.
1926e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // e.g. if (rgnOp != kIntersect && rgnOp != kDifference) throw...
1936e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed
1946e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // Skia now takes a different type, SkClipOp, as the parameter to clipping calls
1956e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    // This type is binary compatible with SkRegion::Op, so a static_cast<> is safe.
1966e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    return static_cast<SkClipOp>(rgnOp);
1976e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed}
1986e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed
199bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jboolean clipRect(jlong canvasHandle, jfloat l, jfloat t,
2008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jfloat r, jfloat b, jint opHandle) {
2016e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    bool nonEmptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b,
2026e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed            opHandleToClipOp(opHandle));
2035ec6a2878b2ad933c5da6fe2341c854155acc24cChris Craik    return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
2048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
206bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic jboolean clipPath(jlong canvasHandle, jlong pathHandle,
2078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jint opHandle) {
2088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
2096e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed    bool nonEmptyClip = get_canvas(canvasHandle)->clipPath(path, opHandleToClipOp(opHandle));
2105ec6a2878b2ad933c5da6fe2341c854155acc24cChris Craik    return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
2118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawColor(JNIEnv* env, jobject, jlong canvasHandle, jint color, jint modeHandle) {
214260ab726486317496bc12a57d599ea96dcde3284Mike Reed    SkBlendMode mode = static_cast<SkBlendMode>(modeHandle);
2151526a458a30184609f19b05e7334da3cbde81dd1Chris Craik    get_canvas(canvasHandle)->drawColor(color, mode);
2168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPaint(JNIEnv* env, jobject, jlong canvasHandle, jlong paintHandle) {
2196ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPaint(*paint);
2218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPoint(JNIEnv*, jobject, jlong canvasHandle, jfloat x, jfloat y,
2248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                      jlong paintHandle) {
2256ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPoint(x, y, *paint);
2278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPoints(JNIEnv* env, jobject, jlong canvasHandle, jfloatArray jptsArray,
2308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jint offset, jint count, jlong paintHandle) {
2318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    NPE_CHECK_RETURN_VOID(env, jptsArray);
2328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray autoPts(env, jptsArray);
2338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    float* floats = autoPts.ptr();
2348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int length = autoPts.length();
2358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if ((offset | count) < 0 || offset + count > length) {
2378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        doThrowAIOOBE(env);
2388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
2398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
2408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2416ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPoints(floats + offset, count, *paint);
2438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawLine(JNIEnv* env, jobject, jlong canvasHandle, jfloat startX, jfloat startY,
2468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jfloat stopX, jfloat stopY, jlong paintHandle) {
2476ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawLine(startX, startY, stopX, stopY, *paint);
2498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawLines(JNIEnv* env, jobject, jlong canvasHandle, jfloatArray jptsArray,
2528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                      jint offset, jint count, jlong paintHandle) {
2538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    NPE_CHECK_RETURN_VOID(env, jptsArray);
2548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray autoPts(env, jptsArray);
2558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    float* floats = autoPts.ptr();
2568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int length = autoPts.length();
2578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if ((offset | count) < 0 || offset + count > length) {
2598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        doThrowAIOOBE(env);
2608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
2618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
2628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2636ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawLines(floats + offset, count, *paint);
2658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
2688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jfloat right, jfloat bottom, jlong paintHandle) {
2696ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawRect(left, top, right, bottom, *paint);
2718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
27394394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenbergerstatic void drawRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong regionHandle,
27494394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger                       jlong paintHandle) {
27594394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger    const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
27694394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
27794394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger    get_canvas(canvasHandle)->drawRegion(*region, *paint);
27894394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger}
27994394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger
2808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawRoundRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
2818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                          jfloat right, jfloat bottom, jfloat rx, jfloat ry, jlong paintHandle) {
2826ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawRoundRect(left, top, right, bottom, rx, ry, *paint);
2848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawCircle(JNIEnv* env, jobject, jlong canvasHandle, jfloat cx, jfloat cy,
2878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jfloat radius, jlong paintHandle) {
2886ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawCircle(cx, cy, radius, *paint);
2908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawOval(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
2938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jfloat right, jfloat bottom, jlong paintHandle) {
2946ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
2958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawOval(left, top, right, bottom, *paint);
2968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawArc(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
2998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                    jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle,
3008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                    jboolean useCenter, jlong paintHandle) {
3016ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawArc(left, top, right, bottom, startAngle, sweepAngle,
3038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       useCenter, *paint);
3048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle,
3078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jlong paintHandle) {
3088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
3096ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPath(*path, *paint);
3118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawVertices(JNIEnv* env, jobject, jlong canvasHandle,
3148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jint modeHandle, jint vertexCount,
3158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jfloatArray jverts, jint vertIndex,
3168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jfloatArray jtexs, jint texIndex,
3178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jintArray jcolors, jint colorIndex,
3188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jshortArray jindices, jint indexIndex,
3198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jint indexCount, jlong paintHandle) {
3208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray  vertA(env, jverts, vertIndex + vertexCount);
3218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray  texA(env, jtexs, texIndex + vertexCount);
3228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaIntArray    colorA(env, jcolors, colorIndex + vertexCount);
3238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaShortArray  indexA(env, jindices, indexIndex + indexCount);
3248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const float* verts = vertA.ptr() + vertIndex;
3268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const float* texs = texA.ptr() + vertIndex;
3278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int* colors = NULL;
3288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const uint16_t* indices = NULL;
3298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (jcolors != NULL) {
3318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        colors = colorA.ptr() + colorIndex;
3328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
3338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (jindices != NULL) {
3348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        indices = (const uint16_t*)(indexA.ptr() + indexIndex);
3358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
3368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkCanvas::VertexMode mode = static_cast<SkCanvas::VertexMode>(modeHandle);
3386ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawVertices(mode, vertexCount, verts, texs, colors,
3408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                           indices, indexCount, *paint);
3418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3434c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenbergerstatic void drawNinePatch(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
3444c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        jlong chunkHandle, jfloat left, jfloat top, jfloat right, jfloat bottom,
3454c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        jlong paintHandle, jint dstDensity, jint srcDensity) {
3464c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3474c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
3485fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv    Bitmap& bitmap = android::bitmap::toBitmap(env, bitmapHandle);
3494c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    const android::Res_png_9patch* chunk = reinterpret_cast<android::Res_png_9patch*>(chunkHandle);
3504c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3514c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3524c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    if (CC_LIKELY(dstDensity == srcDensity || dstDensity == 0 || srcDensity == 0)) {
3535fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv        canvas->drawNinePatch(bitmap, *chunk, left, top, right, bottom, paint);
3544c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    } else {
355eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita        canvas->save(SaveFlags::MatrixClip);
3564c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3574c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        SkScalar scale = dstDensity / (float)srcDensity;
3584c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        canvas->translate(left, top);
3594c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        canvas->scale(scale, scale);
3604c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3614c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        Paint filteredPaint;
3624c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        if (paint) {
3634c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger            filteredPaint = *paint;
3644c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        }
3654c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        filteredPaint.setFilterQuality(kLow_SkFilterQuality);
3664c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3675fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv        canvas->drawNinePatch(bitmap, *chunk, 0, 0, (right-left)/scale, (bottom-top)/scale,
3684c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger                &filteredPaint);
3694c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
3704c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        canvas->restore();
3714c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    }
3724c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger}
3734c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
374caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reckstatic void drawBitmap(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
3758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jfloat left, jfloat top, jlong paintHandle, jint canvasDensity,
3768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jint screenDensity, jint bitmapDensity) {
3778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
378aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
3796ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
3808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (canvasDensity == bitmapDensity || canvasDensity == 0 || bitmapDensity == 0) {
3828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        if (screenDensity != 0 && screenDensity != bitmapDensity) {
3836ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod            Paint filteredPaint;
3848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            if (paint) {
3858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                filteredPaint = *paint;
3868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            }
3872a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed            filteredPaint.setFilterQuality(kLow_SkFilterQuality);
3887c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck            canvas->drawBitmap(bitmap, left, top, &filteredPaint);
3898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        } else {
3907c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck            canvas->drawBitmap(bitmap, left, top, paint);
3918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
3928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    } else {
393eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita        canvas->save(SaveFlags::MatrixClip);
3948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        SkScalar scale = canvasDensity / (float)bitmapDensity;
3958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->translate(left, top);
3968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->scale(scale, scale);
3978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3986ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod        Paint filteredPaint;
3998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        if (paint) {
4008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            filteredPaint = *paint;
4018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
4022a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed        filteredPaint.setFilterQuality(kLow_SkFilterQuality);
4038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4047c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        canvas->drawBitmap(bitmap, 0, 0, &filteredPaint);
4058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->restore();
4068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4097c103a36f60b690e3fe83c40210e1cb0c76bba43John Reckstatic void drawBitmapMatrix(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
4108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                             jlong matrixHandle, jlong paintHandle) {
4118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
4126ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
413fc9999505a36c66892d7ccce85187936105f4f36sergeyv    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
4147c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck    get_canvas(canvasHandle)->drawBitmap(bitmap, *matrix, paint);
4158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4177c103a36f60b690e3fe83c40210e1cb0c76bba43John Reckstatic void drawBitmapRect(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
4188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           float srcLeft, float srcTop, float srcRight, float srcBottom,
4198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           float dstLeft, float dstTop, float dstRight, float dstBottom,
4208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jlong paintHandle, jint screenDensity, jint bitmapDensity) {
4218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
4226ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
4238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
424fc9999505a36c66892d7ccce85187936105f4f36sergeyv    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
4258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (screenDensity != 0 && screenDensity != bitmapDensity) {
4266ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod        Paint filteredPaint;
4278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        if (paint) {
4288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            filteredPaint = *paint;
4298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
4302a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed        filteredPaint.setFilterQuality(kLow_SkFilterQuality);
4317c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        canvas->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
4328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           dstLeft, dstTop, dstRight, dstBottom, &filteredPaint);
4338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    } else {
4347c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        canvas->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
4358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           dstLeft, dstTop, dstRight, dstBottom, paint);
4368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmapArray(JNIEnv* env, jobject, jlong canvasHandle,
4408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                            jintArray jcolors, jint offset, jint stride,
4418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                            jfloat x, jfloat y, jint width, jint height,
4428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                            jboolean hasAlpha, jlong paintHandle) {
4438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    // Note: If hasAlpha is false, kRGB_565_SkColorType will be used, which will
4448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    // correct the alphaType to kOpaque_SkAlphaType.
445253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy    SkImageInfo info = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType,
446253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy            GraphicsJNI::defaultColorSpace());
4478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkBitmap bitmap;
4483d4eed7f1aa99401dabe2e45b82f98fb4fc2d754Derek Sollenberger    bitmap.setInfo(info);
449c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    sk_sp<Bitmap> androidBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL);
450c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    if (!androidBitmap) {
4518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
4528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (!GraphicsJNI::SetPixels(env, jcolors, offset, stride, 0, 0, width, height, bitmap)) {
4558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
4568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4586ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
459aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    get_canvas(canvasHandle)->drawBitmap(*androidBitmap, x, y, paint);
4608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4627c103a36f60b690e3fe83c40210e1cb0c76bba43John Reckstatic void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
4638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint meshWidth, jint meshHeight, jfloatArray jverts,
4648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint vertIndex, jintArray jcolors, jint colorIndex, jlong paintHandle) {
4658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int ptCount = (meshWidth + 1) * (meshHeight + 1);
4668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1));
4678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount);
4688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4696ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
4705fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
4717c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck    get_canvas(canvasHandle)->drawBitmapMesh(bitmap, meshWidth, meshHeight,
4728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                             vertA.ptr(), colorA.ptr(), paint);
4738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
4768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                          jint index, jint count, jfloat x, jfloat y, jint bidiFlags,
4778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                          jlong paintHandle, jlong typefaceHandle) {
4786ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
479bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
4808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jchar* jchars = env->GetCharArrayElements(text, NULL);
481dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawText(jchars + index, 0, count, count, x, y,
4828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       bidiFlags, *paint, typeface);
4838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
4848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring text,
4878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint start, jint end, jfloat x, jfloat y, jint bidiFlags,
4888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jlong paintHandle, jlong typefaceHandle) {
4896ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
490bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
4918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int count = end - start;
4928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const jchar* jchars = env->GetStringChars(text, NULL);
493dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawText(jchars + start, 0, count, count, x, y,
4948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       bidiFlags, *paint, typeface);
4958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseStringChars(text, jchars);
4968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, jint index,
4998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                             jint count, jint contextIndex, jint contextCount, jfloat x, jfloat y,
5008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                             jboolean isRtl, jlong paintHandle, jlong typefaceHandle) {
5016ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
502bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
5038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
504ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    const int bidiFlags = isRtl ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR;
5058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jchar* jchars = env->GetCharArrayElements(text, NULL);
506dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawText(jchars + contextIndex, index - contextIndex, count,
5078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       contextCount, x, y, bidiFlags, *paint, typeface);
5088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
5098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextRunString(JNIEnv* env, jobject obj, jlong canvasHandle, jstring text,
5128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                              jint start, jint end, jint contextStart, jint contextEnd,
5138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                              jfloat x, jfloat y, jboolean isRtl, jlong paintHandle,
5148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                              jlong typefaceHandle) {
5156ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
516bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
5178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
518ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    int bidiFlags = isRtl ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR;
5198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jint count = end - start;
5208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jint contextCount = contextEnd - contextStart;
5218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const jchar* jchars = env->GetStringChars(text, NULL);
522dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawText(jchars + contextStart, start - contextStart, count,
5238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       contextCount, x, y, bidiFlags, *paint, typeface);
5248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseStringChars(text, jchars);
5258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
5288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jint index, jint count, jlong pathHandle, jfloat hOffset,
5298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jfloat vOffset, jint bidiFlags, jlong paintHandle,
5308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jlong typefaceHandle) {
5318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
5326ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
533bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
5348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jchar* jchars = env->GetCharArrayElements(text, NULL);
5368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
537dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawTextOnPath(jchars + index, count, bidiFlags, *path,
5388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                   hOffset, vOffset, *paint, typeface);
5398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseCharArrayElements(text, jchars, 0);
5418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextOnPathString(JNIEnv* env, jobject, jlong canvasHandle, jstring text,
5448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                 jlong pathHandle, jfloat hOffset, jfloat vOffset,
5458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                 jint bidiFlags, jlong paintHandle, jlong typefaceHandle) {
5468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
5476ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
548bad99183916ba2bac6659efc8a28273e344ba511sergeyv    Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle);
5498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const jchar* jchars = env->GetStringChars(text, NULL);
5518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    int count = env->GetStringLength(text);
5528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
553dccca44ffda4836b56a21da95a046c9708ffd49csergeyv    get_canvas(canvasHandle)->drawTextOnPath(jchars, count, bidiFlags, *path,
5548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                   hOffset, vOffset, *paint, typeface);
5558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseStringChars(text, jchars);
5578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
559bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craikstatic void setDrawFilter(jlong canvasHandle, jlong filterHandle) {
5608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->setDrawFilter(reinterpret_cast<SkDrawFilter*>(filterHandle));
5618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void freeCaches(JNIEnv* env, jobject) {
5648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkGraphics::PurgeFontCache();
5658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void freeTextLayoutCaches(JNIEnv* env, jobject) {
568ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    minikin::Layout::purgeCaches();
5698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}; // namespace CanvasJNI
5728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
57376f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = {
574caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nGetNativeFinalizer", "()J", (void*) CanvasJNI::getNativeFinalizer},
575caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nInitRaster", "(Landroid/graphics/Bitmap;)J", (void*) CanvasJNI::initRaster},
576caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nFreeCaches", "()V", (void*) CanvasJNI::freeCaches},
577caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nFreeTextLayoutCaches", "()V", (void*) CanvasJNI::freeTextLayoutCaches},
5785cb74bca88268a8b9025be2cce81e1b4f967d19dJohn Reck
5795cb74bca88268a8b9025be2cce81e1b4f967d19dJohn Reck    // ------------ @FastNative ----------------
580caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSetBitmap", "(JLandroid/graphics/Bitmap;)V", (void*) CanvasJNI::setBitmap},
581bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik    {"nGetClipBounds","(JLandroid/graphics/Rect;)Z", (void*) CanvasJNI::getClipBounds},
582bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik
583bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik    // ------------ @CriticalNative ----------------
584caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nIsOpaque","(J)Z", (void*) CanvasJNI::isOpaque},
585caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nGetWidth","(J)I", (void*) CanvasJNI::getWidth},
586caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nGetHeight","(J)I", (void*) CanvasJNI::getHeight},
587caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSetHighContrastText","(JZ)V", (void*) CanvasJNI::setHighContrastText},
588caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSave","(JI)I", (void*) CanvasJNI::save},
589caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSaveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer},
590caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nSaveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha},
591caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    {"nGetSaveCount","(J)I", (void*) CanvasJNI::getSaveCount},
592bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik    {"nRestore","(J)Z", (void*) CanvasJNI::restore},
593bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik    {"nRestoreToCount","(JI)V", (void*) CanvasJNI::restoreToCount},
594bfa0b29883d56edfc2ec217962290d3c94f9fc2aChris Craik    {"nGetMatrix", "(JJ)V", (void*)CanvasJNI::getMatrix</