android_graphics_Canvas.cpp revision 2a1ce8a4e5258b6599cb8e86864eb816d24d69b4
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 21849911a9c4315fc552faa38516c842b2541b1909John Reck#include <Canvas.h> 22acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger#include "SkDrawFilter.h" 238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "SkGraphics.h" 246ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod#include "Paint.h" 258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "TypefaceImpl.h" 268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "MinikinUtils.h" 288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergernamespace android { 308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergernamespace CanvasJNI { 328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic Canvas* get_canvas(jlong canvasHandle) { 348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return reinterpret_cast<Canvas*>(canvasHandle); 358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void finalizer(JNIEnv* env, jobject clazz, jlong canvasHandle) { 388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger delete get_canvas(canvasHandle); 398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// Native wrapper constructor used by Canvas(Bitmap) 428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jlong initRaster(JNIEnv* env, jobject, jlong bitmapHandle) { 438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return reinterpret_cast<jlong>(Canvas::create_canvas(bitmap)); 458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// Set the given bitmap as the new draw target (wrapped in a new SkCanvas), 488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger// optionally copying canvas matrix & clip state. 498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle, 508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jboolean copyState) { 518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->setBitmap(bitmap, copyState); 538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean isOpaque(JNIEnv*, jobject, jlong canvasHandle) { 568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return get_canvas(canvasHandle)->isOpaque() ? JNI_TRUE : JNI_FALSE; 578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint getWidth(JNIEnv*, jobject, jlong canvasHandle) { 608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return static_cast<jint>(get_canvas(canvasHandle)->width()); 618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint getHeight(JNIEnv*, jobject, jlong canvasHandle) { 648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return static_cast<jint>(get_canvas(canvasHandle)->height()); 658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint getSaveCount(JNIEnv*, jobject, jlong canvasHandle) { 688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return static_cast<jint>(get_canvas(canvasHandle)->getSaveCount()); 698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint save(JNIEnv*, jobject, jlong canvasHandle, jint flagsHandle) { 728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle); 738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return static_cast<jint>(get_canvas(canvasHandle)->save(flags)); 748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint saveLayer(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t, 778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat r, jfloat b, jlong paintHandle, jint flagsHandle) { 786ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle); 808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return static_cast<jint>(get_canvas(canvasHandle)->saveLayer(l, t, r, b, paint, flags)); 818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jint saveLayerAlpha(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t, 848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat r, jfloat b, jint alpha, jint flagsHandle) { 858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle); 868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return static_cast<jint>(get_canvas(canvasHandle)->saveLayerAlpha(l, t, r, b, alpha, flags)); 878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void restore(JNIEnv* env, jobject, jlong canvasHandle) { 908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger Canvas* canvas = get_canvas(canvasHandle); 918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (canvas->getSaveCount() <= 1) { // cannot restore anymore 928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger doThrowISE(env, "Underflow in restore"); 938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return; 948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->restore(); 968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void restoreToCount(JNIEnv* env, jobject, jlong canvasHandle, jint restoreCount) { 998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger Canvas* canvas = get_canvas(canvasHandle); 1008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (restoreCount < 1 || restoreCount > canvas->getSaveCount()) { 1018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger doThrowIAE(env, "Underflow in restoreToCount"); 1028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return; 1038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 1048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->restoreToCount(restoreCount); 1058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void getCTM(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) { 1088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 1098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->getMatrix(matrix); 1108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void setMatrix(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) { 1138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 1148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->setMatrix(matrix ? *matrix : SkMatrix::I()); 1158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void concat(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) { 1188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 1198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->concat(*matrix); 1208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void rotate(JNIEnv*, jobject, jlong canvasHandle, jfloat degrees) { 1238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->rotate(degrees); 1248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void scale(JNIEnv*, jobject, jlong canvasHandle, jfloat sx, jfloat sy) { 1278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->scale(sx, sy); 1288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void skew(JNIEnv*, jobject, jlong canvasHandle, jfloat sx, jfloat sy) { 1318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->skew(sx, sy); 1328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void translate(JNIEnv*, jobject, jlong canvasHandle, jfloat dx, jfloat dy) { 1358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->translate(dx, dy); 1368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean getClipBounds(JNIEnv* env, jobject, jlong canvasHandle, jobject bounds) { 1398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkRect r; 1408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkIRect ir; 1418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger bool result = get_canvas(canvasHandle)->getClipBounds(&r); 1428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (!result) { 1448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger r.setEmpty(); 1458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 1468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger r.round(&ir); 1478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger (void)GraphicsJNI::irect_to_jrect(ir, env, bounds); 1498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return result ? JNI_TRUE : JNI_FALSE; 1508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean quickRejectRect(JNIEnv* env, jobject, jlong canvasHandle, 1538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat left, jfloat top, jfloat right, jfloat bottom) { 1548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger bool result = get_canvas(canvasHandle)->quickRejectRect(left, top, right, bottom); 1558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return result ? JNI_TRUE : JNI_FALSE; 1568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean quickRejectPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle) { 1598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkPath* path = reinterpret_cast<SkPath*>(pathHandle); 1608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger bool result = get_canvas(canvasHandle)->quickRejectPath(*path); 1618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return result ? JNI_TRUE : JNI_FALSE; 1628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean clipRect(JNIEnv*, jobject, jlong canvasHandle, jfloat l, jfloat t, 1658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat r, jfloat b, jint opHandle) { 1668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkRegion::Op op = static_cast<SkRegion::Op>(opHandle); 1678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger bool emptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b, op); 1688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return emptyClip ? JNI_FALSE : JNI_TRUE; 1698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean clipPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle, 1728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint opHandle) { 1738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkPath* path = reinterpret_cast<SkPath*>(pathHandle); 1748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkRegion::Op op = static_cast<SkRegion::Op>(opHandle); 1758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger bool emptyClip = get_canvas(canvasHandle)->clipPath(path, op); 1768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return emptyClip ? JNI_FALSE : JNI_TRUE; 1778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic jboolean clipRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong deviceRgnHandle, 1808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint opHandle) { 1818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkRegion* deviceRgn = reinterpret_cast<SkRegion*>(deviceRgnHandle); 1828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkRegion::Op op = static_cast<SkRegion::Op>(opHandle); 1838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger bool emptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, op); 1848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return emptyClip ? JNI_FALSE : JNI_TRUE; 1858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawColor(JNIEnv* env, jobject, jlong canvasHandle, jint color, jint modeHandle) { 1881526a458a30184609f19b05e7334da3cbde81dd1Chris Craik SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(modeHandle); 1891526a458a30184609f19b05e7334da3cbde81dd1Chris Craik get_canvas(canvasHandle)->drawColor(color, mode); 1908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPaint(JNIEnv* env, jobject, jlong canvasHandle, jlong paintHandle) { 1936ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 1948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawPaint(*paint); 1958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 1968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 1978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPoint(JNIEnv*, jobject, jlong canvasHandle, jfloat x, jfloat y, 1988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jlong paintHandle) { 1996ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawPoint(x, y, *paint); 2018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 2028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPoints(JNIEnv* env, jobject, jlong canvasHandle, jfloatArray jptsArray, 2048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint offset, jint count, jlong paintHandle) { 2058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger NPE_CHECK_RETURN_VOID(env, jptsArray); 2068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger AutoJavaFloatArray autoPts(env, jptsArray); 2078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger float* floats = autoPts.ptr(); 2088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const int length = autoPts.length(); 2098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if ((offset | count) < 0 || offset + count > length) { 2118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger doThrowAIOOBE(env); 2128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return; 2138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 2148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2156ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawPoints(floats + offset, count, *paint); 2178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 2188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawLine(JNIEnv* env, jobject, jlong canvasHandle, jfloat startX, jfloat startY, 2208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat stopX, jfloat stopY, jlong paintHandle) { 2216ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawLine(startX, startY, stopX, stopY, *paint); 2238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 2248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawLines(JNIEnv* env, jobject, jlong canvasHandle, jfloatArray jptsArray, 2268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint offset, jint count, jlong paintHandle) { 2278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger NPE_CHECK_RETURN_VOID(env, jptsArray); 2288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger AutoJavaFloatArray autoPts(env, jptsArray); 2298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger float* floats = autoPts.ptr(); 2308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const int length = autoPts.length(); 2318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if ((offset | count) < 0 || offset + count > length) { 2338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger doThrowAIOOBE(env); 2348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return; 2358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 2368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2376ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawLines(floats + offset, count, *paint); 2398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 2408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top, 2428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat right, jfloat bottom, jlong paintHandle) { 2436ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawRect(left, top, right, bottom, *paint); 2458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 2468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawRoundRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top, 2488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat right, jfloat bottom, jfloat rx, jfloat ry, jlong paintHandle) { 2496ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawRoundRect(left, top, right, bottom, rx, ry, *paint); 2518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 2528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawCircle(JNIEnv* env, jobject, jlong canvasHandle, jfloat cx, jfloat cy, 2548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat radius, jlong paintHandle) { 2556ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawCircle(cx, cy, radius, *paint); 2578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 2588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawOval(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top, 2608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat right, jfloat bottom, jlong paintHandle) { 2616ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawOval(left, top, right, bottom, *paint); 2638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 2648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawArc(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top, 2668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle, 2678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jboolean useCenter, jlong paintHandle) { 2686ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawArc(left, top, right, bottom, startAngle, sweepAngle, 2708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger useCenter, *paint); 2718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 2728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle, 2748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jlong paintHandle) { 2758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const SkPath* path = reinterpret_cast<SkPath*>(pathHandle); 2766ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawPath(*path, *paint); 2788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 2798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawVertices(JNIEnv* env, jobject, jlong canvasHandle, 2818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint modeHandle, jint vertexCount, 2828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloatArray jverts, jint vertIndex, 2838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloatArray jtexs, jint texIndex, 2848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jintArray jcolors, jint colorIndex, 2858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jshortArray jindices, jint indexIndex, 2868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint indexCount, jlong paintHandle) { 2878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger AutoJavaFloatArray vertA(env, jverts, vertIndex + vertexCount); 2888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger AutoJavaFloatArray texA(env, jtexs, texIndex + vertexCount); 2898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger AutoJavaIntArray colorA(env, jcolors, colorIndex + vertexCount); 2908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger AutoJavaShortArray indexA(env, jindices, indexIndex + indexCount); 2918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const float* verts = vertA.ptr() + vertIndex; 2938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const float* texs = texA.ptr() + vertIndex; 2948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const int* colors = NULL; 2958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const uint16_t* indices = NULL; 2968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 2978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (jcolors != NULL) { 2988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger colors = colorA.ptr() + colorIndex; 2998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 3008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (jindices != NULL) { 3018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger indices = (const uint16_t*)(indexA.ptr() + indexIndex); 3028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 3038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 3048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkCanvas::VertexMode mode = static_cast<SkCanvas::VertexMode>(modeHandle); 3056ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 3068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawVertices(mode, vertexCount, verts, texs, colors, 3078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger indices, indexCount, *paint); 3088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 3098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 3108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmap(JNIEnv* env, jobject jcanvas, jlong canvasHandle, jlong bitmapHandle, 3118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat left, jfloat top, jlong paintHandle, jint canvasDensity, 3128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint screenDensity, jint bitmapDensity) { 3138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger Canvas* canvas = get_canvas(canvasHandle); 3148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 3156ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 3168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 3178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (canvasDensity == bitmapDensity || canvasDensity == 0 || bitmapDensity == 0) { 3188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (screenDensity != 0 && screenDensity != bitmapDensity) { 3196ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint filteredPaint; 3208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (paint) { 3218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger filteredPaint = *paint; 3228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 3232a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed filteredPaint.setFilterQuality(kLow_SkFilterQuality); 3248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->drawBitmap(*bitmap, left, top, &filteredPaint); 3258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } else { 3268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->drawBitmap(*bitmap, left, top, paint); 3278872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 3288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } else { 3298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->save(SkCanvas::kMatrixClip_SaveFlag); 3308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkScalar scale = canvasDensity / (float)bitmapDensity; 3318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->translate(left, top); 3328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->scale(scale, scale); 3338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 3346ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint filteredPaint; 3358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (paint) { 3368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger filteredPaint = *paint; 3378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 3382a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed filteredPaint.setFilterQuality(kLow_SkFilterQuality); 3398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 3408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint); 3418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->restore(); 3428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 3438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 3448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 3458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmapMatrix(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle, 3468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jlong matrixHandle, jlong paintHandle) { 3478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 3488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 3496ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 3508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawBitmap(*bitmap, *matrix, paint); 3518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 3528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 3538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmapRect(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle, 3548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger float srcLeft, float srcTop, float srcRight, float srcBottom, 3558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger float dstLeft, float dstTop, float dstRight, float dstBottom, 3568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jlong paintHandle, jint screenDensity, jint bitmapDensity) { 3578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger Canvas* canvas = get_canvas(canvasHandle); 3588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 3596ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 3608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 3618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (screenDensity != 0 && screenDensity != bitmapDensity) { 3626ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint filteredPaint; 3638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger if (paint) { 3648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger filteredPaint = *paint; 3658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 3662a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed filteredPaint.setFilterQuality(kLow_SkFilterQuality); 3678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->drawBitmap(*bitmap, srcLeft, srcTop, srcRight, srcBottom, 3688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger dstLeft, dstTop, dstRight, dstBottom, &filteredPaint); 3698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } else { 3708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->drawBitmap(*bitmap, srcLeft, srcTop, srcRight, srcBottom, 3718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger dstLeft, dstTop, dstRight, dstBottom, paint); 3728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 3738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 3748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 3758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawBitmapArray(JNIEnv* env, jobject, jlong canvasHandle, 3768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jintArray jcolors, jint offset, jint stride, 3778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat x, jfloat y, jint width, jint height, 3788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jboolean hasAlpha, jlong paintHandle) { 3798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger // Note: If hasAlpha is false, kRGB_565_SkColorType will be used, which will 3808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger // correct the alphaType to kOpaque_SkAlphaType. 3818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkImageInfo info = SkImageInfo::Make(width, height, 3828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType, 3838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger kPremul_SkAlphaType); 3848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkBitmap bitmap; 3853d4eed7f1aa99401dabe2e45b82f98fb4fc2d754Derek Sollenberger bitmap.setInfo(info); 3863d4eed7f1aa99401dabe2e45b82f98fb4fc2d754Derek Sollenberger if (!GraphicsJNI::allocatePixels(env, &bitmap, NULL)) { 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 3946ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(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); 4066ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 4078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->drawBitmapMesh(*bitmap, meshWidth, meshHeight, 4088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger vertA.ptr(), colorA.ptr(), paint); 4098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 4108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 411acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenbergerclass DrawTextFunctor { 412acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenbergerpublic: 413acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger DrawTextFunctor(const Layout& layout, Canvas* canvas, uint16_t* glyphs, float* pos, 4148dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint& paint, float x, float y, MinikinRect& bounds, 4158dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float totalAdvance) 416acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger : layout(layout), canvas(canvas), glyphs(glyphs), pos(pos), paint(paint), 4178dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson x(x), y(y), bounds(bounds), totalAdvance(totalAdvance) { } 418acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 419acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger void operator()(size_t start, size_t end) { 420acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger if (canvas->drawTextAbsolutePos()) { 421acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger for (size_t i = start; i < end; i++) { 422acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger glyphs[i] = layout.getGlyphId(i); 423acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger pos[2 * i] = x + layout.getX(i); 424acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger pos[2 * i + 1] = y + layout.getY(i); 425acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger } 426acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger } else { 427acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger for (size_t i = start; i < end; i++) { 428acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger glyphs[i] = layout.getGlyphId(i); 429acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger pos[2 * i] = layout.getX(i); 430acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger pos[2 * i + 1] = layout.getY(i); 431acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger } 432acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger } 433acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 434acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger size_t glyphCount = end - start; 435acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger canvas->drawText(glyphs + start, pos + (2 * start), glyphCount, paint, x, y, 4368dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, 4378dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson totalAdvance); 438acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger } 439acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenbergerprivate: 440acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger const Layout& layout; 441acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger Canvas* canvas; 442acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger uint16_t* glyphs; 443acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger float* pos; 444acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger const SkPaint& paint; 445acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger float x; 446acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger float y; 447acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger MinikinRect& bounds; 4488dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float totalAdvance; 449acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger}; 450acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 451acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger// Same values used by Skia 452acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger#define kStdStrikeThru_Offset (-6.0f / 21.0f) 453acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger#define kStdUnderline_Offset (1.0f / 9.0f) 454acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger#define kStdUnderline_Thickness (1.0f / 18.0f) 455acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 456acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenbergervoid drawTextDecorations(Canvas* canvas, float x, float y, float length, const SkPaint& paint) { 457acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger uint32_t flags; 458acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger SkDrawFilter* drawFilter = canvas->getDrawFilter(); 459acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger if (drawFilter) { 460acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger SkPaint paintCopy(paint); 461acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger drawFilter->filter(&paintCopy, SkDrawFilter::kText_Type); 462acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger flags = paintCopy.getFlags(); 463acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger } else { 464acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger flags = paint.getFlags(); 465acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger } 466acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) { 467acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger SkScalar left = x; 468acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger SkScalar right = x + length; 469acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger float textSize = paint.getTextSize(); 470acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f); 471acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger if (flags & SkPaint::kUnderlineText_Flag) { 472acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger SkScalar top = y + textSize * kStdUnderline_Offset - 0.5f * strokeWidth; 473acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger SkScalar bottom = y + textSize * kStdUnderline_Offset + 0.5f * strokeWidth; 474acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger canvas->drawRect(left, top, right, bottom, paint); 475acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger } 476acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger if (flags & SkPaint::kStrikeThruText_Flag) { 477acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger SkScalar top = y + textSize * kStdStrikeThru_Offset - 0.5f * strokeWidth; 478acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger SkScalar bottom = y + textSize * kStdStrikeThru_Offset + 0.5f * strokeWidth; 479acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger canvas->drawRect(left, top, right, bottom, paint); 480acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger } 481acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger } 482acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger} 483acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 484acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenbergervoid drawText(Canvas* canvas, const uint16_t* text, int start, int count, int contextCount, 485acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger float x, float y, int bidiFlags, const Paint& origPaint, TypefaceImpl* typeface) { 486acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger // minikin may modify the original paint 487acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger Paint paint(origPaint); 488acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 489acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger Layout layout; 49063c5c78a72a21d57913e8601cc2a1ab72a424a02Behdad Esfahbod MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, start, count, contextCount); 491acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 492acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger size_t nGlyphs = layout.nGlyphs(); 493acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger uint16_t* glyphs = new uint16_t[nGlyphs]; 494acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger float* pos = new float[nGlyphs * 2]; 495acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 496acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger x += MinikinUtils::xOffsetForTextAlign(&paint, layout); 497acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 498acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger MinikinRect bounds; 499acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger layout.getBounds(&bounds); 5008dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson if (!canvas->drawTextAbsolutePos()) { 5018dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson bounds.offset(x, y); 5028dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } 503acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 5048dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson DrawTextFunctor f(layout, canvas, glyphs, pos, paint, x, y, bounds, layout.getAdvance()); 505acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger MinikinUtils::forFontRun(layout, &paint, f); 506acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 507acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger drawTextDecorations(canvas, x, y, layout.getAdvance(), paint); 508acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 509acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger delete[] glyphs; 510acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger delete[] pos; 511acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger} 512acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger 5138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, 5148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint index, jint count, jfloat x, jfloat y, jint bidiFlags, 5158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jlong paintHandle, jlong typefaceHandle) { 5166ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 5178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 5188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jchar* jchars = env->GetCharArrayElements(text, NULL); 519acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger drawText(get_canvas(canvasHandle), jchars + index, 0, count, count, x, y, 5208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger bidiFlags, *paint, typeface); 5218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger env->ReleaseCharArrayElements(text, jchars, JNI_ABORT); 5228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 5238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 5248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring text, 5258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint start, jint end, jfloat x, jfloat y, jint bidiFlags, 5268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jlong paintHandle, jlong typefaceHandle) { 5276ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 5288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 5298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const int count = end - start; 5308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const jchar* jchars = env->GetStringChars(text, NULL); 531acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger drawText(get_canvas(canvasHandle), jchars + start, 0, count, count, x, y, 5328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger bidiFlags, *paint, typeface); 5338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger env->ReleaseStringChars(text, jchars); 5348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 5358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 5368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, jint index, 5378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint count, jint contextIndex, jint contextCount, jfloat x, jfloat y, 5388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jboolean isRtl, jlong paintHandle, jlong typefaceHandle) { 5396ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 5408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 5418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 5428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; 5438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jchar* jchars = env->GetCharArrayElements(text, NULL); 544acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger drawText(get_canvas(canvasHandle), jchars + contextIndex, index - contextIndex, count, 5458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger contextCount, x, y, bidiFlags, *paint, typeface); 5468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger env->ReleaseCharArrayElements(text, jchars, JNI_ABORT); 5478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 5488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 5498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextRunString(JNIEnv* env, jobject obj, jlong canvasHandle, jstring text, 5508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint start, jint end, jint contextStart, jint contextEnd, 5518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat x, jfloat y, jboolean isRtl, jlong paintHandle, 5528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jlong typefaceHandle) { 5536ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 5548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 5558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 5568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; 5578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint count = end - start; 5588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint contextCount = contextEnd - contextStart; 5598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const jchar* jchars = env->GetStringChars(text, NULL); 560acb4099deff72c2c631f7110a405a3331d3e8b27Derek Sollenberger drawText(get_canvas(canvasHandle), jchars + contextStart, start - contextStart, count, 5618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger contextCount, x, y, bidiFlags, *paint, typeface); 5628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger env->ReleaseStringChars(text, jchars); 5638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 5648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 5658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerclass DrawTextOnPathFunctor { 5668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerpublic: 5678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger DrawTextOnPathFunctor(const Layout& layout, Canvas* canvas, float hOffset, 5686ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod float vOffset, const Paint& paint, const SkPath& path) 5698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger : layout(layout), canvas(canvas), hOffset(hOffset), vOffset(vOffset), 5708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger paint(paint), path(path) { 5718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 5728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger void operator()(size_t start, size_t end) { 5738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger uint16_t glyphs[1]; 5748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger for (size_t i = start; i < end; i++) { 5758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger glyphs[0] = layout.getGlyphId(i); 5768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger float x = hOffset + layout.getX(i); 5778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger float y = vOffset + layout.getY(i); 5788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger canvas->drawTextOnPath(glyphs, 1, path, x, y, paint); 5798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 5808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger } 5818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerprivate: 5828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const Layout& layout; 5838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger Canvas* canvas; 5848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger float hOffset; 5858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger float vOffset; 5866ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint& paint; 5878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const SkPath& path; 5888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}; 5898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 5908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextOnPath(Canvas* canvas, const uint16_t* text, int count, int bidiFlags, 5918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const SkPath& path, float hOffset, float vOffset, 5926ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint& paint, TypefaceImpl* typeface) { 5936ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint paintCopy(paint); 5948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger Layout layout; 59563c5c78a72a21d57913e8601cc2a1ab72a424a02Behdad Esfahbod MinikinUtils::doLayout(&layout, &paintCopy, bidiFlags, typeface, text, 0, count, count); 5968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger hOffset += MinikinUtils::hOffsetForTextAlign(&paintCopy, layout, path); 5978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 5988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger // Set align to left for drawing, as we don't want individual 5998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger // glyphs centered or right-aligned; the offset above takes 6008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger // care of all alignment. 6016ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod paintCopy.setTextAlign(Paint::kLeft_Align); 6028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger DrawTextOnPathFunctor f(layout, canvas, hOffset, vOffset, paintCopy, path); 6048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger MinikinUtils::forFontRun(layout, &paintCopy, f); 6058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 6068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, 6088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint index, jint count, jlong pathHandle, jfloat hOffset, 6098872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jfloat vOffset, jint bidiFlags, jlong paintHandle, 6108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jlong typefaceHandle) { 6118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkPath* path = reinterpret_cast<SkPath*>(pathHandle); 6126ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 6138872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 6148872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6158872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jchar* jchars = env->GetCharArrayElements(text, NULL); 6168872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger drawTextOnPath(get_canvas(canvasHandle), jchars + index, count, bidiFlags, *path, 6188872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger hOffset, vOffset, *paint, typeface); 6198872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6208872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger env->ReleaseCharArrayElements(text, jchars, 0); 6218872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 6228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6238872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void drawTextOnPathString(JNIEnv* env, jobject, jlong canvasHandle, jstring text, 6248872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jlong pathHandle, jfloat hOffset, jfloat vOffset, 6258872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger jint bidiFlags, jlong paintHandle, jlong typefaceHandle) { 6268872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkPath* path = reinterpret_cast<SkPath*>(pathHandle); 6276ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 6288872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 6298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger const jchar* jchars = env->GetStringChars(text, NULL); 6318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger int count = env->GetStringLength(text); 6328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger drawTextOnPath(get_canvas(canvasHandle), jchars, count, bidiFlags, *path, 6348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger hOffset, vOffset, *paint, typeface); 6358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger env->ReleaseStringChars(text, jchars); 6378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 6388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void setDrawFilter(JNIEnv* env, jobject, jlong canvasHandle, jlong filterHandle) { 6408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger get_canvas(canvasHandle)->setDrawFilter(reinterpret_cast<SkDrawFilter*>(filterHandle)); 6418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 6428872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void freeCaches(JNIEnv* env, jobject) { 6448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger SkGraphics::PurgeFontCache(); 6458872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 6468872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6478872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic void freeTextLayoutCaches(JNIEnv* env, jobject) { 6488872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger Layout::purgeCaches(); 6498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 6508872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6518872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}; // namespace CanvasJNI 6528872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 6538872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerstatic JNINativeMethod gMethods[] = { 6548872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"finalizer", "(J)V", (void*) CanvasJNI::finalizer}, 6558872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"initRaster", "(J)J", (void*) CanvasJNI::initRaster}, 6568872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_setBitmap", "(JJZ)V", (void*) CanvasJNI::setBitmap}, 6578872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_isOpaque","(J)Z", (void*) CanvasJNI::isOpaque}, 6588872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_getWidth","(J)I", (void*) CanvasJNI::getWidth}, 6598872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_getHeight","(J)I", (void*) CanvasJNI::getHeight}, 6608872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_save","(JI)I", (void*) CanvasJNI::save}, 6618872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_saveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer}, 6628872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_saveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha}, 6638872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_getSaveCount","(J)I", (void*) CanvasJNI::getSaveCount}, 6648872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_restore","(J)V", (void*) CanvasJNI::restore}, 6658872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_restoreToCount","(JI)V", (void*) CanvasJNI::restoreToCount}, 6668872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_getCTM", "(JJ)V", (void*)CanvasJNI::getCTM}, 6678872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_setMatrix","(JJ)V", (void*) CanvasJNI::setMatrix}, 6688872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_concat","(JJ)V", (void*) CanvasJNI::concat}, 6698872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_rotate","(JF)V", (void*) CanvasJNI::rotate}, 6708872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_scale","(JFF)V", (void*) CanvasJNI::scale}, 6718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_skew","(JFF)V", (void*) CanvasJNI::skew}, 6728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_translate","(JFF)V", (void*) CanvasJNI::translate}, 6738872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_getClipBounds","(JLandroid/graphics/Rect;)Z", (void*) CanvasJNI::getClipBounds}, 6748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_quickReject","(JJ)Z", (void*) CanvasJNI::quickRejectPath}, 6758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_quickReject","(JFFFF)Z", (void*)CanvasJNI::quickRejectRect}, 6768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_clipRect","(JFFFFI)Z", (void*) CanvasJNI::clipRect}, 6778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_clipPath","(JJI)Z", (void*) CanvasJNI::clipPath}, 6788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_clipRegion","(JJI)Z", (void*) CanvasJNI::clipRegion}, 6798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawColor","(JII)V", (void*) CanvasJNI::drawColor}, 6808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawPaint","(JJ)V", (void*) CanvasJNI::drawPaint}, 6818872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawPoint", "(JFFJ)V", (void*) CanvasJNI::drawPoint}, 6828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawPoints", "(J[FIIJ)V", (void*) CanvasJNI::drawPoints}, 6838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawLine", "(JFFFFJ)V", (void*) CanvasJNI::drawLine}, 6848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawLines", "(J[FIIJ)V", (void*) CanvasJNI::drawLines}, 6858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawRect","(JFFFFJ)V", (void*) CanvasJNI::drawRect}, 6868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawRoundRect","(JFFFFFFJ)V", (void*) CanvasJNI::drawRoundRect}, 6878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawCircle","(JFFFJ)V", (void*) CanvasJNI::drawCircle}, 6888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawOval","(JFFFFJ)V", (void*) CanvasJNI::drawOval}, 6898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawArc","(JFFFFFFZJ)V", (void*) CanvasJNI::drawArc}, 6908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawPath","(JJJ)V", (void*) CanvasJNI::drawPath}, 6918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"nativeDrawVertices", "(JII[FI[FI[II[SIIJ)V", (void*)CanvasJNI::drawVertices}, 6928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawBitmap","(JJFFJIII)V", (void*) CanvasJNI::drawBitmap}, 6938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"nativeDrawBitmapMatrix", "(JJJJ)V", (void*)CanvasJNI::drawBitmapMatrix}, 6948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawBitmap","(JJFFFFFFFFJII)V", (void*) CanvasJNI::drawBitmapRect}, 6958872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawBitmap", "(J[IIIFFIIZJ)V", (void*)CanvasJNI::drawBitmapArray}, 6968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"nativeDrawBitmapMesh", "(JJII[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh}, 6978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawText","(J[CIIFFIJJ)V", (void*) CanvasJNI::drawTextChars}, 6988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawText","(JLjava/lang/String;IIFFIJJ)V", (void*) CanvasJNI::drawTextString}, 6998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawTextRun","(J[CIIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunChars}, 7008872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawTextRun","(JLjava/lang/String;IIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunString}, 7018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawTextOnPath","(J[CIIJFFIJJ)V", (void*) CanvasJNI::drawTextOnPathChars}, 7028872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"native_drawTextOnPath","(JLjava/lang/String;JFFIJJ)V", (void*) CanvasJNI::drawTextOnPathString}, 7038872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"nativeSetDrawFilter", "(JJ)V", (void*) CanvasJNI::setDrawFilter}, 7048872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"freeCaches", "()V", (void*) CanvasJNI::freeCaches}, 7058872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger {"freeTextLayoutCaches", "()V", (void*) CanvasJNI::freeTextLayoutCaches} 7068872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}; 7078872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 7088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergerint register_android_graphics_Canvas(JNIEnv* env) { 709ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return RegisterMethodsOrDie(env, "android/graphics/Canvas", gMethods, NELEM(gMethods)); 7108872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger} 7118872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger 7128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger}; // namespace android 713