android_graphics_Canvas.cpp revision 8872b38ef403cc2c44aca07d392f5e9426fd7f54
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"
198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include <android_runtime/AndroidRuntime.h>
208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "Canvas.h"
228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "SkGraphics.h"
238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "SkPorterDuff.h"
248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "TypefaceImpl.h"
258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include <minikin/Layout.h>
278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "MinikinSkia.h"
288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "MinikinUtils.h"
298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergernamespace android {
318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergernamespace CanvasJNI {
338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic Canvas* get_canvas(jlong canvasHandle) {
358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return reinterpret_cast<Canvas*>(canvasHandle);
368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void finalizer(JNIEnv* env, jobject clazz, jlong canvasHandle) {
398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    delete get_canvas(canvasHandle);
408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// Native wrapper constructor used by Canvas(Bitmap)
438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jlong initRaster(JNIEnv* env, jobject, jlong bitmapHandle) {
448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return reinterpret_cast<jlong>(Canvas::create_canvas(bitmap));
468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// Set the given bitmap as the new draw target (wrapped in a new SkCanvas),
498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// optionally copying canvas matrix & clip state.
508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                      jboolean copyState) {
528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->setBitmap(bitmap, copyState);
548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean isOpaque(JNIEnv*, jobject, jlong canvasHandle) {
578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return get_canvas(canvasHandle)->isOpaque() ? JNI_TRUE : JNI_FALSE;
588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint getWidth(JNIEnv*, jobject, jlong canvasHandle) {
618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->width());
628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint getHeight(JNIEnv*, jobject, jlong canvasHandle) {
658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->height());
668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint getSaveCount(JNIEnv*, jobject, jlong canvasHandle) {
698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->getSaveCount());
708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint save(JNIEnv*, jobject, jlong canvasHandle, jint flagsHandle) {
738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->save(flags));
758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint saveLayer(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t,
788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                      jfloat r, jfloat b, jlong paintHandle, jint flagsHandle) {
798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint  = reinterpret_cast<SkPaint*>(paintHandle);
808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->saveLayer(l, t, r, b, paint, flags));
828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint saveLayerAlpha(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t,
858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jfloat r, jfloat b, jint alpha, jint flagsHandle) {
868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return static_cast<jint>(get_canvas(canvasHandle)->saveLayerAlpha(l, t, r, b, alpha, flags));
888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void restore(JNIEnv* env, jobject, jlong canvasHandle) {
918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (canvas->getSaveCount() <= 1) {  // cannot restore anymore
938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        doThrowISE(env, "Underflow in restore");
948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    canvas->restore();
978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void restoreToCount(JNIEnv* env, jobject, jlong canvasHandle, jint restoreCount) {
1008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
1018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (restoreCount < 1 || restoreCount > canvas->getSaveCount()) {
1028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        doThrowIAE(env, "Underflow in restoreToCount");
1038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
1048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
1058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    canvas->restoreToCount(restoreCount);
1068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void getCTM(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) {
1098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
1108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->getMatrix(matrix);
1118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void setMatrix(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) {
1148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
1158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->setMatrix(matrix ? *matrix : SkMatrix::I());
1168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void concat(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) {
1198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
1208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->concat(*matrix);
1218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void rotate(JNIEnv*, jobject, jlong canvasHandle, jfloat degrees) {
1248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->rotate(degrees);
1258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void scale(JNIEnv*, jobject, jlong canvasHandle, jfloat sx, jfloat sy) {
1288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->scale(sx, sy);
1298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void skew(JNIEnv*, jobject, jlong canvasHandle, jfloat sx, jfloat sy) {
1328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->skew(sx, sy);
1338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void translate(JNIEnv*, jobject, jlong canvasHandle, jfloat dx, jfloat dy) {
1368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->translate(dx, dy);
1378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean getClipBounds(JNIEnv* env, jobject, jlong canvasHandle, jobject bounds) {
1408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkRect   r;
1418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkIRect ir;
1428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool result = get_canvas(canvasHandle)->getClipBounds(&r);
1438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (!result) {
1458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        r.setEmpty();
1468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
1478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    r.round(&ir);
1488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    (void)GraphicsJNI::irect_to_jrect(ir, env, bounds);
1508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return result ? JNI_TRUE : JNI_FALSE;
1518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean quickRejectRect(JNIEnv* env, jobject, jlong canvasHandle,
1548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jfloat left, jfloat top, jfloat right, jfloat bottom) {
1558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool result = get_canvas(canvasHandle)->quickRejectRect(left, top, right, bottom);
1568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return result ? JNI_TRUE : JNI_FALSE;
1578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean quickRejectPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle) {
1608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
1618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool result = get_canvas(canvasHandle)->quickRejectPath(*path);
1628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return result ? JNI_TRUE : JNI_FALSE;
1638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean clipRect(JNIEnv*, jobject, jlong canvasHandle, jfloat l, jfloat t,
1668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jfloat r, jfloat b, jint opHandle) {
1678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
1688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool emptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b, op);
1698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return emptyClip ? JNI_FALSE : JNI_TRUE;
1708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean clipPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle,
1738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jint opHandle) {
1748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
1758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
1768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool emptyClip = get_canvas(canvasHandle)->clipPath(path, op);
1778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return emptyClip ? JNI_FALSE : JNI_TRUE;
1788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean clipRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong deviceRgnHandle,
1818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint opHandle) {
1828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkRegion* deviceRgn = reinterpret_cast<SkRegion*>(deviceRgnHandle);
1838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
1848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    bool emptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, op);
1858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return emptyClip ? JNI_FALSE : JNI_TRUE;
1868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawColor(JNIEnv* env, jobject, jlong canvasHandle, jint color, jint modeHandle) {
1898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger     SkPorterDuff::Mode mode = static_cast<SkPorterDuff::Mode>(modeHandle);
1908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger     get_canvas(canvasHandle)->drawColor(color, SkPorterDuff::ToXfermodeMode(mode));
1918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPaint(JNIEnv* env, jobject, jlong canvasHandle, jlong paintHandle) {
1948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
1958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPaint(*paint);
1968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
1978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPoint(JNIEnv*, jobject, jlong canvasHandle, jfloat x, jfloat y,
1998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                      jlong paintHandle) {
2008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
2018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPoint(x, y, *paint);
2028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPoints(JNIEnv* env, jobject, jlong canvasHandle, jfloatArray jptsArray,
2058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jint offset, jint count, jlong paintHandle) {
2068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    NPE_CHECK_RETURN_VOID(env, jptsArray);
2078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray autoPts(env, jptsArray);
2088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    float* floats = autoPts.ptr();
2098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int length = autoPts.length();
2108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if ((offset | count) < 0 || offset + count > length) {
2128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        doThrowAIOOBE(env);
2138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
2148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
2158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
2178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPoints(floats + offset, count, *paint);
2188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawLine(JNIEnv* env, jobject, jlong canvasHandle, jfloat startX, jfloat startY,
2218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jfloat stopX, jfloat stopY, jlong paintHandle) {
2228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
2238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawLine(startX, startY, stopX, stopY, *paint);
2248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawLines(JNIEnv* env, jobject, jlong canvasHandle, jfloatArray jptsArray,
2278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                      jint offset, jint count, jlong paintHandle) {
2288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    NPE_CHECK_RETURN_VOID(env, jptsArray);
2298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray autoPts(env, jptsArray);
2308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    float* floats = autoPts.ptr();
2318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int length = autoPts.length();
2328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if ((offset | count) < 0 || offset + count > length) {
2348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        doThrowAIOOBE(env);
2358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
2368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
2378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
2398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawLines(floats + offset, count, *paint);
2408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
2438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jfloat right, jfloat bottom, jlong paintHandle) {
2448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
2458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawRect(left, top, right, bottom, *paint);
2468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawRoundRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
2498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                          jfloat right, jfloat bottom, jfloat rx, jfloat ry, jlong paintHandle) {
2508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
2518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawRoundRect(left, top, right, bottom, rx, ry, *paint);
2528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawCircle(JNIEnv* env, jobject, jlong canvasHandle, jfloat cx, jfloat cy,
2558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jfloat radius, jlong paintHandle) {
2568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
2578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawCircle(cx, cy, radius, *paint);
2588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawOval(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
2618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jfloat right, jfloat bottom, jlong paintHandle) {
2628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
2638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawOval(left, top, right, bottom, *paint);
2648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawArc(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
2678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                    jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle,
2688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                    jboolean useCenter, jlong paintHandle) {
2698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
2708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawArc(left, top, right, bottom, startAngle, sweepAngle,
2718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       useCenter, *paint);
2728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle,
2758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                     jlong paintHandle) {
2768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
2778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
2788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPath(*path, *paint);
2798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
2808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawVertices(JNIEnv* env, jobject, jlong canvasHandle,
2828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jint modeHandle, jint vertexCount,
2838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jfloatArray jverts, jint vertIndex,
2848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jfloatArray jtexs, jint texIndex,
2858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jintArray jcolors, jint colorIndex,
2868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jshortArray jindices, jint indexIndex,
2878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                         jint indexCount, jlong paintHandle) {
2888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray  vertA(env, jverts, vertIndex + vertexCount);
2898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray  texA(env, jtexs, texIndex + vertexCount);
2908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaIntArray    colorA(env, jcolors, colorIndex + vertexCount);
2918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaShortArray  indexA(env, jindices, indexIndex + indexCount);
2928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const float* verts = vertA.ptr() + vertIndex;
2948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const float* texs = texA.ptr() + vertIndex;
2958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int* colors = NULL;
2968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const uint16_t* indices = NULL;
2978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
2988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (jcolors != NULL) {
2998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        colors = colorA.ptr() + colorIndex;
3008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
3018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (jindices != NULL) {
3028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        indices = (const uint16_t*)(indexA.ptr() + indexIndex);
3038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
3048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkCanvas::VertexMode mode = static_cast<SkCanvas::VertexMode>(modeHandle);
3068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
3078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawVertices(mode, vertexCount, verts, texs, colors,
3088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                           indices, indexCount, *paint);
3098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmap(JNIEnv* env, jobject jcanvas, jlong canvasHandle, jlong bitmapHandle,
3128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jfloat left, jfloat top, jlong paintHandle, jint canvasDensity,
3138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                       jint screenDensity, jint bitmapDensity) {
3148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
3158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
3168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
3178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (canvasDensity == bitmapDensity || canvasDensity == 0 || bitmapDensity == 0) {
3198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        if (screenDensity != 0 && screenDensity != bitmapDensity) {
3208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            SkPaint filteredPaint;
3218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            if (paint) {
3228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                filteredPaint = *paint;
3238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            }
3248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
3258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            canvas->drawBitmap(*bitmap, left, top, &filteredPaint);
3268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        } else {
3278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            canvas->drawBitmap(*bitmap, left, top, paint);
3288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
3298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    } else {
3308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->save(SkCanvas::kMatrixClip_SaveFlag);
3318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        SkScalar scale = canvasDensity / (float)bitmapDensity;
3328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->translate(left, top);
3338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->scale(scale, scale);
3348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        SkPaint filteredPaint;
3368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        if (paint) {
3378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            filteredPaint = *paint;
3388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
3398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
3408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
3428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->restore();
3438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
3448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmapMatrix(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
3478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                             jlong matrixHandle, jlong paintHandle) {
3488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
3498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
3508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
3518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawBitmap(*bitmap, *matrix, paint);
3528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmapRect(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
3558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           float srcLeft, float srcTop, float srcRight, float srcBottom,
3568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           float dstLeft, float dstTop, float dstRight, float dstBottom,
3578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jlong paintHandle, jint screenDensity, jint bitmapDensity) {
3588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas = get_canvas(canvasHandle);
3598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
3608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
3618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (screenDensity != 0 && screenDensity != bitmapDensity) {
3638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        SkPaint filteredPaint;
3648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        if (paint) {
3658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            filteredPaint = *paint;
3668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
3678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
3688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->drawBitmap(*bitmap, srcLeft, srcTop, srcRight, srcBottom,
3698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           dstLeft, dstTop, dstRight, dstBottom, &filteredPaint);
3708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    } else {
3718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        canvas->drawBitmap(*bitmap, srcLeft, srcTop, srcRight, srcBottom,
3728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           dstLeft, dstTop, dstRight, dstBottom, paint);
3738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
3748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmapArray(JNIEnv* env, jobject, jlong canvasHandle,
3778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                            jintArray jcolors, jint offset, jint stride,
3788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                            jfloat x, jfloat y, jint width, jint height,
3798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                            jboolean hasAlpha, jlong paintHandle) {
3808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    // Note: If hasAlpha is false, kRGB_565_SkColorType will be used, which will
3818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    // correct the alphaType to kOpaque_SkAlphaType.
3828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkImageInfo info = SkImageInfo::Make(width, height,
3838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType,
3848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           kPremul_SkAlphaType);
3858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkBitmap bitmap;
3868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (!bitmap.allocPixels(info)) {
3878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
3888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
3898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (!GraphicsJNI::SetPixels(env, jcolors, offset, stride, 0, 0, width, height, bitmap)) {
3918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        return;
3928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
3938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
3958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawBitmap(bitmap, x, y, paint);
3968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
3978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
3988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
3998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint meshWidth, jint meshHeight, jfloatArray jverts,
4008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint vertIndex, jintArray jcolors, jint colorIndex, jlong paintHandle) {
4018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int ptCount = (meshWidth + 1) * (meshHeight + 1);
4028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1));
4038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount);
4048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
4068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
4078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawBitmapMesh(*bitmap, meshWidth, meshHeight,
4088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                             vertA.ptr(), colorA.ptr(), paint);
4098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
4128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                          jint index, jint count, jfloat x, jfloat y, jint bidiFlags,
4138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                          jlong paintHandle, jlong typefaceHandle) {
4148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
4158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
4168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jchar* jchars = env->GetCharArrayElements(text, NULL);
4178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawText(jchars + index, 0, count, count, x, y,
4188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       bidiFlags, *paint, typeface);
4198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
4208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring text,
4238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jint start, jint end, jfloat x, jfloat y, jint bidiFlags,
4248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           jlong paintHandle, jlong typefaceHandle) {
4258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
4268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
4278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int count = end - start;
4288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const jchar* jchars = env->GetStringChars(text, NULL);
4298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawText(jchars + start, 0, count, count, x, y,
4308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       bidiFlags, *paint, typeface);
4318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseStringChars(text, jchars);
4328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, jint index,
4358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                             jint count, jint contextIndex, jint contextCount, jfloat x, jfloat y,
4368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                             jboolean isRtl, jlong paintHandle, jlong typefaceHandle) {
4378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
4388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
4398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
4418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jchar* jchars = env->GetCharArrayElements(text, NULL);
4428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawText(jchars + contextIndex, index - contextIndex, count,
4438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       contextCount, x, y, bidiFlags, *paint, typeface);
4448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
4458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextRunString(JNIEnv* env, jobject obj, jlong canvasHandle, jstring text,
4488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                              jint start, jint end, jint contextStart, jint contextEnd,
4498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                              jfloat x, jfloat y, jboolean isRtl, jlong paintHandle,
4508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                              jlong typefaceHandle) {
4518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
4528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
4538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
4558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jint count = end - start;
4568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jint contextCount = contextEnd - contextStart;
4578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const jchar* jchars = env->GetStringChars(text, NULL);
4588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawText(jchars + contextStart, start - contextStart, count,
4598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                       contextCount, x, y, bidiFlags, *paint, typeface);
4608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseStringChars(text, jchars);
4618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPosTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
4648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                             jint index, jint count, jfloatArray pos, jlong paintHandle) {
4658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
4668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jchar* jchars = text ? env->GetCharArrayElements(text, NULL) : NULL;
4678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
4688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
4698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPosText(jchars + index, posArray, count << 1, posCount, *paint);
4718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (text) {
4738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        env->ReleaseCharArrayElements(text, jchars, 0);
4748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (pos) {
4768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        env->ReleaseFloatArrayElements(pos, posArray, 0);
4778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPosTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring text,
4828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                              jfloatArray pos, jlong paintHandle) {
4838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
4848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const jchar* jchars = text ? env->GetStringChars(text, NULL) : NULL;
4858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    int byteLength = text ? env->GetStringLength(text) : 0;
4868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
4878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
4888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->drawPosText(jchars , posArray, byteLength << 1, posCount, *paint);
4908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (text) {
4928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        env->ReleaseStringChars(text, jchars);
4938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    if (pos) {
4958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        env->ReleaseFloatArrayElements(pos, posArray, 0);
4968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
4978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
4988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
4998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerclass DrawTextOnPathFunctor {
5008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerpublic:
5018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    DrawTextOnPathFunctor(const Layout& layout, Canvas* canvas, float hOffset,
5028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                float vOffset, const SkPaint& paint, const SkPath& path)
5038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            : layout(layout), canvas(canvas), hOffset(hOffset), vOffset(vOffset),
5048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                paint(paint), path(path) {
5058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
5068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    void operator()(size_t start, size_t end) {
5078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        uint16_t glyphs[1];
5088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        for (size_t i = start; i < end; i++) {
5098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            glyphs[0] = layout.getGlyphId(i);
5108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            float x = hOffset + layout.getX(i);
5118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            float y = vOffset + layout.getY(i);
5128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            canvas->drawTextOnPath(glyphs, 1, path, x, y, paint);
5138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
5148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    }
5158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerprivate:
5168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const Layout& layout;
5178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Canvas* canvas;
5188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    float hOffset;
5198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    float vOffset;
5208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPaint& paint;
5218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const SkPath& path;
5228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger};
5238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextOnPath(Canvas* canvas, const uint16_t* text, int count, int bidiFlags,
5258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           const SkPath& path, float hOffset, float vOffset,
5268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                           const SkPaint& paint, TypefaceImpl* typeface) {
5278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint paintCopy(paint);
5288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Layout layout;
5298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    std::string css = MinikinUtils::setLayoutProperties(&layout, &paintCopy, bidiFlags, typeface);
5308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    layout.doLayout(text, 0, count, count, css);
5318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    hOffset += MinikinUtils::hOffsetForTextAlign(&paintCopy, layout, path);
5328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    // Set align to left for drawing, as we don't want individual
5348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    // glyphs centered or right-aligned; the offset above takes
5358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    // care of all alignment.
5368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    paintCopy.setTextAlign(SkPaint::kLeft_Align);
5378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    DrawTextOnPathFunctor f(layout, canvas, hOffset, vOffset, paintCopy, path);
5398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    MinikinUtils::forFontRun(layout, &paintCopy, f);
5408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
5438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jint index, jint count, jlong pathHandle, jfloat hOffset,
5448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jfloat vOffset, jint bidiFlags, jlong paintHandle,
5458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                jlong typefaceHandle) {
5468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
5478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
5488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
5498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    jchar* jchars = env->GetCharArrayElements(text, NULL);
5518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    drawTextOnPath(get_canvas(canvasHandle), jchars + index, count, bidiFlags, *path,
5538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                   hOffset, vOffset, *paint, typeface);
5548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseCharArrayElements(text, jchars, 0);
5568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextOnPathString(JNIEnv* env, jobject, jlong canvasHandle, jstring text,
5598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                 jlong pathHandle, jfloat hOffset, jfloat vOffset,
5608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                                 jint bidiFlags, jlong paintHandle, jlong typefaceHandle) {
5618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
5628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
5638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
5648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    const jchar* jchars = env->GetStringChars(text, NULL);
5668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    int count = env->GetStringLength(text);
5678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    drawTextOnPath(get_canvas(canvasHandle), jchars, count, bidiFlags, *path,
5698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger                   hOffset, vOffset, *paint, typeface);
5708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    env->ReleaseStringChars(text, jchars);
5728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void setDrawFilter(JNIEnv* env, jobject, jlong canvasHandle, jlong filterHandle) {
5758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    get_canvas(canvasHandle)->setDrawFilter(reinterpret_cast<SkDrawFilter*>(filterHandle));
5768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void freeCaches(JNIEnv* env, jobject) {
5798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkGraphics::PurgeFontCache();
5808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void freeTextLayoutCaches(JNIEnv* env, jobject) {
5838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    Layout::purgeCaches();
5848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
5858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}; // namespace CanvasJNI
5878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
5888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic JNINativeMethod gMethods[] = {
5898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"finalizer", "(J)V", (void*) CanvasJNI::finalizer},
5908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"initRaster", "(J)J", (void*) CanvasJNI::initRaster},
5918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_setBitmap", "(JJZ)V", (void*) CanvasJNI::setBitmap},
5928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_isOpaque","(J)Z", (void*) CanvasJNI::isOpaque},
5938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_getWidth","(J)I", (void*) CanvasJNI::getWidth},
5948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_getHeight","(J)I", (void*) CanvasJNI::getHeight},
5958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_save","(JI)I", (void*) CanvasJNI::save},
5968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_saveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer},
5978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_saveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha},
5988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_getSaveCount","(J)I", (void*) CanvasJNI::getSaveCount},
5998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_restore","(J)V", (void*) CanvasJNI::restore},
6008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_restoreToCount","(JI)V", (void*) CanvasJNI::restoreToCount},
6018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_getCTM", "(JJ)V", (void*)CanvasJNI::getCTM},
6028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_setMatrix","(JJ)V", (void*) CanvasJNI::setMatrix},
6038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_concat","(JJ)V", (void*) CanvasJNI::concat},
6048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_rotate","(JF)V", (void*) CanvasJNI::rotate},
6058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_scale","(JFF)V", (void*) CanvasJNI::scale},
6068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_skew","(JFF)V", (void*) CanvasJNI::skew},
6078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_translate","(JFF)V", (void*) CanvasJNI::translate},
6088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_getClipBounds","(JLandroid/graphics/Rect;)Z", (void*) CanvasJNI::getClipBounds},
6098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_quickReject","(JJ)Z", (void*) CanvasJNI::quickRejectPath},
6108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_quickReject","(JFFFF)Z", (void*)CanvasJNI::quickRejectRect},
6118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_clipRect","(JFFFFI)Z", (void*) CanvasJNI::clipRect},
6128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_clipPath","(JJI)Z", (void*) CanvasJNI::clipPath},
6138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_clipRegion","(JJI)Z", (void*) CanvasJNI::clipRegion},
6148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawColor","(JII)V", (void*) CanvasJNI::drawColor},
6158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawPaint","(JJ)V", (void*) CanvasJNI::drawPaint},
6168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawPoint", "(JFFJ)V", (void*) CanvasJNI::drawPoint},
6178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawPoints", "(J[FIIJ)V", (void*) CanvasJNI::drawPoints},
6188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawLine", "(JFFFFJ)V", (void*) CanvasJNI::drawLine},
6198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawLines", "(J[FIIJ)V", (void*) CanvasJNI::drawLines},
6208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawRect","(JFFFFJ)V", (void*) CanvasJNI::drawRect},
6218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawRoundRect","(JFFFFFFJ)V", (void*) CanvasJNI::drawRoundRect},
6228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawCircle","(JFFFJ)V", (void*) CanvasJNI::drawCircle},
6238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawOval","(JFFFFJ)V", (void*) CanvasJNI::drawOval},
6248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawArc","(JFFFFFFZJ)V", (void*) CanvasJNI::drawArc},
6258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawPath","(JJJ)V", (void*) CanvasJNI::drawPath},
6268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"nativeDrawVertices", "(JII[FI[FI[II[SIIJ)V", (void*)CanvasJNI::drawVertices},
6278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawBitmap","(JJFFJIII)V", (void*) CanvasJNI::drawBitmap},
6288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"nativeDrawBitmapMatrix", "(JJJJ)V", (void*)CanvasJNI::drawBitmapMatrix},
6298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawBitmap","(JJFFFFFFFFJII)V", (void*) CanvasJNI::drawBitmapRect},
6308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawBitmap", "(J[IIIFFIIZJ)V", (void*)CanvasJNI::drawBitmapArray},
6318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"nativeDrawBitmapMesh", "(JJII[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh},
6328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawText","(J[CIIFFIJJ)V", (void*) CanvasJNI::drawTextChars},
6338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawText","(JLjava/lang/String;IIFFIJJ)V", (void*) CanvasJNI::drawTextString},
6348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawTextRun","(J[CIIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunChars},
6358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawTextRun","(JLjava/lang/String;IIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunString},
6368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawTextOnPath","(J[CIIJFFIJJ)V", (void*) CanvasJNI::drawTextOnPathChars},
6378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"native_drawTextOnPath","(JLjava/lang/String;JFFIJJ)V", (void*) CanvasJNI::drawTextOnPathString},
6388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"nativeSetDrawFilter", "(JJ)V", (void*) CanvasJNI::setDrawFilter},
6398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"freeCaches", "()V", (void*) CanvasJNI::freeCaches},
6408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    {"freeTextLayoutCaches", "()V", (void*) CanvasJNI::freeTextLayoutCaches}
6418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger};
6428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
6438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerint register_android_graphics_Canvas(JNIEnv* env) {
6448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return AndroidRuntime::registerNativeMethods(env, "android/graphics/Canvas", gMethods, NELEM(gMethods));
6458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}
6468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
6478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}; // namespace android
648