Canvas.cpp revision f47d7405bbcb25d7cdf89ebb059f41520fe9ab87
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006-2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "GraphicsJNI.h" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkCanvas.h" 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkDevice.h" 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkGLCanvas.h" 24caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed#include "SkGraphics.h" 25caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed#include "SkImageRef_GlobalPool.h" 2647c0d4eaa926d979c5ea366934750526c20af8ffMike Reed#include "SkPorterDuff.h" 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkShader.h" 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkTemplates.h" 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed#include "SkBoundaryPatch.h" 31c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed#include "SkMeshUtils.h" 32c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 33f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt#include "unicode/ubidi.h" 34f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define TIME_DRAWx 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic uint32_t get_thread_msec() { 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(HAVE_POSIX_CLOCKS) 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct timespec tm; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm); 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tm.tv_sec * 1000LL + tm.tv_nsec / 1000000; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct timeval tv; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gettimeofday(&tv, NULL); 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tv.tv_sec * 1000LL + tv.tv_usec / 1000; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass SkCanvasGlue { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 57f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt enum { 58f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt kDirection_LTR = 0, 59f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt kDirection_RTL = 1 60f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt }; 61f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 62f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt enum { 63f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt kDirection_Mask = 0x1 64f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt }; 65f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 66f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt enum { 67f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt kBidi_LTR = 0, 68f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt kBidi_RTL = 1, 69f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt kBidi_Default_LTR = 2, 70f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt kBidi_Default_RTL = 3, 71f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt kBidi_Force_LTR = 4, 72f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt kBidi_Force_RTL = 5 73f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt }; 74f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void finalizer(JNIEnv* env, jobject clazz, SkCanvas* canvas) { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->unref(); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static SkCanvas* initRaster(JNIEnv* env, jobject, SkBitmap* bitmap) { 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bitmap ? new SkCanvas(*bitmap) : new SkCanvas; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static SkCanvas* initGL(JNIEnv* env, jobject) { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new SkGLCanvas; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 87caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed static void freeCaches(JNIEnv* env, jobject) { 88caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed // these are called in no particular order 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkGLCanvas::DeleteAllTextures(); 90caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed SkImageRef_GlobalPool::SetRAMUsed(0); 91caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed SkGraphics::SetFontCacheUsed(0); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean isOpaque(JNIEnv* env, jobject jcanvas) { 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Currently we cannot support transparency in GL-based canvas' at 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project the view level. Therefore we cannot base our answer on the device's 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bitmap, but need to hard-code the answer. If we relax this 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project limitation in views, we can simplify the following code as well. 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Use the getViewport() call to find out if we're gl-based... 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (canvas->getViewport(NULL)) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // normal technique, rely on the device's bitmap for the answer 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->getDevice()->accessBitmap(false).isOpaque(); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int getWidth(JNIEnv* env, jobject jcanvas) { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->getDevice()->accessBitmap(false).width(); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int getHeight(JNIEnv* env, jobject jcanvas) { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->getDevice()->accessBitmap(false).height(); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void setViewport(JNIEnv* env, jobject, SkCanvas* canvas, 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int width, int height) { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->setViewport(width, height); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void setBitmap(JNIEnv* env, jobject, SkCanvas* canvas, 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkBitmap* bitmap) { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->setBitmapDevice(*bitmap); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int saveAll(JNIEnv* env, jobject jcanvas) { 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GraphicsJNI::getNativeCanvas(env, jcanvas)->save(); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int save(JNIEnv* env, jobject jcanvas, SkCanvas::SaveFlags flags) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GraphicsJNI::getNativeCanvas(env, jcanvas)->save(flags); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int saveLayer(JNIEnv* env, jobject, SkCanvas* canvas, jobject bounds, 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPaint* paint, int flags) { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect* bounds_ = NULL; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect storage; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bounds != NULL) { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, bounds, &storage); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds_ = &storage; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->saveLayer(bounds_, paint, (SkCanvas::SaveFlags)flags); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int saveLayer4F(JNIEnv* env, jobject, SkCanvas* canvas, 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat l, jfloat t, jfloat r, jfloat b, 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPaint* paint, int flags) { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect bounds; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds.set(SkFloatToScalar(l), SkFloatToScalar(t), SkFloatToScalar(r), 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(b)); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->saveLayer(&bounds, paint, (SkCanvas::SaveFlags)flags); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int saveLayerAlpha(JNIEnv* env, jobject, SkCanvas* canvas, 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject bounds, int alpha, int flags) { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect* bounds_ = NULL; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect storage; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bounds != NULL) { 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, bounds, &storage); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds_ = &storage; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->saveLayerAlpha(bounds_, alpha, 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (SkCanvas::SaveFlags)flags); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int saveLayerAlpha4F(JNIEnv* env, jobject, SkCanvas* canvas, 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat l, jfloat t, jfloat r, jfloat b, 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int alpha, int flags) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect bounds; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds.set(SkFloatToScalar(l), SkFloatToScalar(t), SkFloatToScalar(r), 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(b)); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->saveLayerAlpha(&bounds, alpha, 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (SkCanvas::SaveFlags)flags); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void restore(JNIEnv* env, jobject jcanvas) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (canvas->getSaveCount() <= 1) { // cannot restore anymore 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doThrowISE(env, "Underflow in restore"); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->restore(); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int getSaveCount(JNIEnv* env, jobject jcanvas) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GraphicsJNI::getNativeCanvas(env, jcanvas)->getSaveCount(); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void restoreToCount(JNIEnv* env, jobject jcanvas, int restoreCount) { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (restoreCount < 1) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doThrowIAE(env, "Underflow in restoreToCount"); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->restoreToCount(restoreCount); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void translate(JNIEnv* env, jobject jcanvas, jfloat dx, jfloat dy) { 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar dx_ = SkFloatToScalar(dx); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar dy_ = SkFloatToScalar(dy); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->translate(dx_, dy_); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void scale__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar sx_ = SkFloatToScalar(sx); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar sy_ = SkFloatToScalar(sy); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->scale(sx_, sy_); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void rotate__F(JNIEnv* env, jobject jcanvas, jfloat degrees) { 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar degrees_ = SkFloatToScalar(degrees); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->rotate(degrees_); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void skew__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar sx_ = SkFloatToScalar(sx); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar sy_ = SkFloatToScalar(sy); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->skew(sx_, sy_); 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void concat(JNIEnv* env, jobject, SkCanvas* canvas, 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkMatrix* matrix) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->concat(*matrix); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void setMatrix(JNIEnv* env, jobject, SkCanvas* canvas, 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkMatrix* matrix) { 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == matrix) { 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->resetMatrix(); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->setMatrix(*matrix); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean clipRect_FFFF(JNIEnv* env, jobject jcanvas, jfloat left, 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat top, jfloat right, jfloat bottom) { 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect r; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.set(SkFloatToScalar(left), SkFloatToScalar(top), 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(right), SkFloatToScalar(bottom)); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c->clipRect(r); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean clipRect_IIII(JNIEnv* env, jobject jcanvas, jint left, 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint top, jint right, jint bottom) { 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect r; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.set(SkIntToScalar(left), SkIntToScalar(top), 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkIntToScalar(right), SkIntToScalar(bottom)); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return GraphicsJNI::getNativeCanvas(env, jcanvas)->clipRect(r); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean clipRect_RectF(JNIEnv* env, jobject jcanvas, jobject rectf) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, rectf); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect tmp; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c->clipRect(*GraphicsJNI::jrectf_to_rect(env, rectf, &tmp)); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean clipRect_Rect(JNIEnv* env, jobject jcanvas, jobject rect) { 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, rect); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect tmp; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c->clipRect(*GraphicsJNI::jrect_to_rect(env, rect, &tmp)); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean clipRect(JNIEnv* env, jobject, SkCanvas* canvas, 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float left, float top, float right, float bottom, 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int op) { 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect rect; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rect.set(SkFloatToScalar(left), SkFloatToScalar(top), 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(right), SkFloatToScalar(bottom)); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->clipRect(rect, (SkRegion::Op)op); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean clipPath(JNIEnv* env, jobject, SkCanvas* canvas, 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPath* path, int op) { 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->clipPath(*path, (SkRegion::Op)op); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean clipRegion(JNIEnv* env, jobject, SkCanvas* canvas, 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRegion* deviceRgn, int op) { 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->clipRegion(*deviceRgn, (SkRegion::Op)op); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void setDrawFilter(JNIEnv* env, jobject, SkCanvas* canvas, 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkDrawFilter* filter) { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->setDrawFilter(filter); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean quickReject__RectFI(JNIEnv* env, jobject, SkCanvas* canvas, 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject rect, int edgetype) { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect rect_; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, rect, &rect_); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->quickReject(rect_, (SkCanvas::EdgeType)edgetype); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean quickReject__PathI(JNIEnv* env, jobject, SkCanvas* canvas, 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPath* path, int edgetype) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->quickReject(*path, (SkCanvas::EdgeType)edgetype); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static jboolean quickReject__FFFFI(JNIEnv* env, jobject, SkCanvas* canvas, 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat left, jfloat top, jfloat right, 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat bottom, int edgetype) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect r; 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.set(SkFloatToScalar(left), SkFloatToScalar(top), 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(right), SkFloatToScalar(bottom)); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return canvas->quickReject(r, (SkCanvas::EdgeType)edgetype); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawRGB(JNIEnv* env, jobject, SkCanvas* canvas, 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint r, jint g, jint b) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawARGB(0xFF, r, g, b); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawARGB(JNIEnv* env, jobject, SkCanvas* canvas, 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint a, jint r, jint g, jint b) { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawARGB(a, r, g, b); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawColor__I(JNIEnv* env, jobject, SkCanvas* canvas, 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint color) { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawColor(color); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawColor__II(JNIEnv* env, jobject, SkCanvas* canvas, 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint color, SkPorterDuff::Mode mode) { 35147c0d4eaa926d979c5ea366934750526c20af8ffMike Reed canvas->drawColor(color, SkPorterDuff::ToXfermodeMode(mode)); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawPaint(JNIEnv* env, jobject, SkCanvas* canvas, 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPaint* paint) { 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawPaint(*paint); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void doPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray, 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint offset, jint count, jobject jpaint, 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas::PointMode mode) { 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jptsArray); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jpaint); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaFloatArray autoPts(env, jptsArray); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* floats = autoPts.ptr(); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int length = autoPts.length(); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((offset | count) < 0 || offset + count > length) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doThrowAIOOBE(env); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now convert the floats into SkPoints 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count >>= 1; // now it is the number of points 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkAutoSTMalloc<32, SkPoint> storage(count); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint* pts = storage.get(); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const float* src = floats + offset; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pts[i].set(SkFloatToScalar(src[0]), SkFloatToScalar(src[1])); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src += 2; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawPoints(mode, count, pts, paint); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray, 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint offset, jint count, jobject jpaint) { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doPoints(env, jcanvas, jptsArray, offset, count, jpaint, 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas::kPoints_PointMode); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawLines(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray, 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint offset, jint count, jobject jpaint) { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doPoints(env, jcanvas, jptsArray, offset, count, jpaint, 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas::kLines_PointMode); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawPoint(JNIEnv* env, jobject jcanvas, float x, float y, 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject jpaint) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jpaint); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawPoint(SkFloatToScalar(x), SkFloatToScalar(y), paint); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawLine__FFFFPaint(JNIEnv* env, jobject, SkCanvas* canvas, 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat startX, jfloat startY, jfloat stopX, 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat stopY, SkPaint* paint) { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawLine(SkFloatToScalar(startX), SkFloatToScalar(startY), 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(stopX), SkFloatToScalar(stopY), 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *paint); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawRect__RectFPaint(JNIEnv* env, jobject, SkCanvas* canvas, 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject rect, SkPaint* paint) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect rect_; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, rect, &rect_); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawRect(rect_, *paint); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawRect__FFFFPaint(JNIEnv* env, jobject, SkCanvas* canvas, 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat left, jfloat top, jfloat right, 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat bottom, SkPaint* paint) { 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar left_ = SkFloatToScalar(left); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar top_ = SkFloatToScalar(top); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar right_ = SkFloatToScalar(right); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar bottom_ = SkFloatToScalar(bottom); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawRectCoords(left_, top_, right_, bottom_, *paint); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawOval(JNIEnv* env, jobject, SkCanvas* canvas, jobject joval, 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPaint* paint) { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect oval; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, joval, &oval); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawOval(oval, *paint); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawCircle(JNIEnv* env, jobject, SkCanvas* canvas, jfloat cx, 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat cy, jfloat radius, SkPaint* paint) { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawCircle(SkFloatToScalar(cx), SkFloatToScalar(cy), 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(radius), *paint); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawArc(JNIEnv* env, jobject, SkCanvas* canvas, jobject joval, 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat startAngle, jfloat sweepAngle, 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jboolean useCenter, SkPaint* paint) { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect oval; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, joval, &oval); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawArc(oval, SkFloatToScalar(startAngle), 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(sweepAngle), useCenter, *paint); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawRoundRect(JNIEnv* env, jobject, SkCanvas* canvas, 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject jrect, jfloat rx, jfloat ry, 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPaint* paint) { 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect rect; 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, jrect, &rect); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawRoundRect(rect, SkFloatToScalar(rx), SkFloatToScalar(ry), 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *paint); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawPath(JNIEnv* env, jobject, SkCanvas* canvas, SkPath* path, 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPaint* paint) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawPath(*path, *paint); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawPicture(JNIEnv* env, jobject, SkCanvas* canvas, 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPicture* picture) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(canvas); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(picture); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef TIME_DRAW 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkMSec now = get_thread_msec(); //SkTime::GetMSecs(); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawPicture(*picture); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef TIME_DRAW 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("---- picture playback %d ms\n", get_thread_msec() - now); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawBitmap__BitmapFFPaint(JNIEnv* env, jobject jcanvas, 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas, SkBitmap* bitmap, 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat left, jfloat top, 48911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn SkPaint* paint, jint canvasDensity, 4900d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn jint screenDensity, jint bitmapDensity) { 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar left_ = SkFloatToScalar(left); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar top_ = SkFloatToScalar(top); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn if (canvasDensity == bitmapDensity || canvasDensity == 0 49511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn || bitmapDensity == 0) { 4960d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn if (screenDensity != 0 && screenDensity != bitmapDensity) { 4970d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn SkPaint filteredPaint; 4980d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn if (paint) { 4990d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn filteredPaint = *paint; 5000d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn } 5010d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn filteredPaint.setFilterBitmap(true); 5020d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint); 5030d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn } else { 5040d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn canvas->drawBitmap(*bitmap, left_, top_, paint); 5050d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn } 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->save(); 50811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn SkScalar scale = SkFloatToScalar(canvasDensity / (float)bitmapDensity); 50911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn canvas->translate(left_, top_); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->scale(scale, scale); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPaint filteredPaint; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (paint) { 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filteredPaint = *paint; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filteredPaint.setFilterBitmap(true); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->restore(); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap, 5250d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn jobject srcIRect, const SkRect& dst, SkPaint* paint, 5260d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn jint screenDensity, jint bitmapDensity) { 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkIRect src, *srcPtr = NULL; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != srcIRect) { 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::jrect_to_irect(env, srcIRect, &src); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project srcPtr = &src; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5330d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn 5340d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn if (screenDensity != 0 && screenDensity != bitmapDensity) { 5350d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn SkPaint filteredPaint; 5360d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn if (paint) { 5370d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn filteredPaint = *paint; 5380d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn } 5390d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn filteredPaint.setFilterBitmap(true); 5400d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint); 5410d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn } else { 5420d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint); 5430d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas, 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkBitmap* bitmap, jobject srcIRect, 5480d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn jobject dstRectF, SkPaint* paint, 5490d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn jint screenDensity, jint bitmapDensity) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect dst; 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst); 5520d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint, 5530d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn screenDensity, bitmapDensity); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawBitmapRR(JNIEnv* env, jobject, SkCanvas* canvas, 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkBitmap* bitmap, jobject srcIRect, 5580d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn jobject dstRect, SkPaint* paint, 5590d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn jint screenDensity, jint bitmapDensity) { 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect dst; 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::jrect_to_rect(env, dstRect, &dst); 5620d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint, 5630d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn screenDensity, bitmapDensity); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawBitmapArray(JNIEnv* env, jobject, SkCanvas* canvas, 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray jcolors, int offset, int stride, 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat x, jfloat y, int width, int height, 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jboolean hasAlpha, SkPaint* paint) 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkBitmap bitmap; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bitmap.setConfig(hasAlpha ? SkBitmap::kARGB_8888_Config : 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkBitmap::kRGB_565_Config, width, height); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!bitmap.allocPixels()) { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!GraphicsJNI::SetPixels(env, jcolors, offset, stride, 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, 0, width, height, bitmap)) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawBitmap(bitmap, SkFloatToScalar(x), SkFloatToScalar(y), 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint); 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawBitmapMatrix(JNIEnv* env, jobject, SkCanvas* canvas, 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkBitmap* bitmap, const SkMatrix* matrix, 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkPaint* paint) { 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawBitmapMatrix(*bitmap, *matrix, paint); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawBitmapMesh(JNIEnv* env, jobject, SkCanvas* canvas, 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkBitmap* bitmap, int meshWidth, int meshHeight, 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray jverts, int vertIndex, jintArray jcolors, 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int colorIndex, const SkPaint* paint) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int ptCount = (meshWidth + 1) * (meshHeight + 1); 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int indexCount = meshWidth * meshHeight * 6; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1)); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount); 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Our temp storage holds 2 or 3 arrays. 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project texture points [ptCount * sizeof(SkPoint)] 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project optionally vertex points [ptCount * sizeof(SkPoint)] if we need a 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project copy to convert from float to fixed 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indices [ptCount * sizeof(uint16_t)] 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t storageSize = ptCount * sizeof(SkPoint); // texs[] 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef SK_SCALAR_IS_FIXED 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project storageSize += ptCount * sizeof(SkPoint); // storage for verts 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project storageSize += indexCount * sizeof(uint16_t); // indices[] 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkAutoMalloc storage(storageSize); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint* texs = (SkPoint*)storage.get(); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint* verts; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint16_t* indices; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef SK_SCALAR_IS_FLOAT 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project verts = (SkPoint*)(vertA.ptr() + vertIndex); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indices = (uint16_t*)(texs + ptCount); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project verts = texs + ptCount; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indices = (uint16_t*)(verts + ptCount); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // convert floats to fixed 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const float* src = vertA.ptr() + vertIndex; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < ptCount; i++) { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1])); 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src += 2; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cons up texture coordinates and indices 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkScalar w = SkIntToScalar(bitmap->width()); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkScalar h = SkIntToScalar(bitmap->height()); 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkScalar dx = w / meshWidth; 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkScalar dy = h / meshHeight; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint* texsPtr = texs; 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar y = 0; 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i <= meshHeight; i++) { 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == meshHeight) { 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = h; // to ensure numerically we hit h exactly 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar x = 0; 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j = 0; j < meshWidth; j++) { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project texsPtr->set(x, y); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project texsPtr += 1; 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x += dx; 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project texsPtr->set(w, y); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project texsPtr += 1; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y += dy; 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(texsPtr - texs == ptCount); 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cons up indices 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint16_t* indexPtr = indices; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = 0; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < meshHeight; i++) { 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j = 0; j < meshWidth; j++) { 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // lower-left triangle 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *indexPtr++ = index; 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *indexPtr++ = index + meshWidth + 1; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *indexPtr++ = index + meshWidth + 2; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // upper-right triangle 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *indexPtr++ = index; 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *indexPtr++ = index + meshWidth + 2; 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *indexPtr++ = index + 1; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // bump to the next cell 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 1; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // bump to the next row 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 1; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(indexPtr - indices == indexCount); 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT((char*)indexPtr - (char*)storage.get() == storageSize); 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // double-check that we have legal indices 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef SK_DEBUG 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < indexCount; i++) { 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT((unsigned)indices[i] < (unsigned)ptCount); 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cons-up a shader for the bitmap 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPaint tmpPaint; 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (paint) { 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmpPaint = *paint; 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkShader* shader = SkShader::CreateBitmapShader(*bitmap, 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmpPaint.setShader(shader)->safeUnref(); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, verts, 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project texs, (const SkColor*)colorA.ptr(), NULL, indices, 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indexCount, tmpPaint); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawVertices(JNIEnv* env, jobject, SkCanvas* canvas, 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas::VertexMode mode, int vertexCount, 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray jverts, int vertIndex, 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray jtexs, int texIndex, 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray jcolors, int colorIndex, 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jshortArray jindices, int indexIndex, 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int indexCount, const SkPaint* paint) { 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaFloatArray vertA(env, jverts, vertIndex + vertexCount); 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaFloatArray texA(env, jtexs, texIndex + vertexCount); 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaIntArray colorA(env, jcolors, colorIndex + vertexCount); 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaShortArray indexA(env, jindices, indexIndex + indexCount); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int ptCount = vertexCount >> 1; 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint* verts; 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint* texs = NULL; 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef SK_SCALAR_IS_FLOAT 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project verts = (SkPoint*)(vertA.ptr() + vertIndex); 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jtexs != NULL) { 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project texs = (SkPoint*)(texA.ptr() + texIndex); 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = ptCount; // for verts 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jtexs != NULL) { 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count += ptCount; // += for texs 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkAutoMalloc storage(count * sizeof(SkPoint)); 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project verts = (SkPoint*)storage.get(); 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const float* src = vertA.ptr() + vertIndex; 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < ptCount; i++) { 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1])); 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src += 2; 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jtexs != NULL) { 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project texs = verts + ptCount; 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src = texA.ptr() + texIndex; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < ptCount; i++) { 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project texs[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1])); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src += 2; 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkColor* colors = NULL; 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* indices = NULL; 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jcolors != NULL) { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors = (const SkColor*)(colorA.ptr() + colorIndex); 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jindices != NULL) { 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indices = (const uint16_t*)(indexA.ptr() + indexIndex); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawVertices(mode, ptCount, verts, texs, colors, NULL, 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indices, indexCount, *paint); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 766f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 767f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt static void shapeRtlText__(const jchar* text, jsize len, jsize start, jsize count, jchar* shaped) { 768f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt // fake shaping, just reverse the text 769f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt for (int i = 0; i < count; ++i) { 770f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt shaped[i] = text[start + count - 1 - i]; 771f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 772f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt // fix surrogate pairs, if any 773f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt for (int i = 1; i < count; ++i) { 774f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (shaped[i] >= 0xd800 && shaped[i] < 0xdc00 && 775f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt shaped[i-1] >= 0xdc00 && shaped[i-1] < 0xe000) { 776f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jchar c = shaped[i]; shaped[i] = shaped[i-1]; shaped[i-1] = c; 777f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt i += 1; 778f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 779f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 780f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 781f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 782f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt static void drawText__(JNIEnv* env, SkCanvas* canvas, const jchar* text, jsize len, 783f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jfloat x, jfloat y, int flags, SkPaint* paint) { 784f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt SkScalar x_ = SkFloatToScalar(x); 785f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt SkScalar y_ = SkFloatToScalar(y); 786f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 787f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt SkPaint::Align horiz = paint->getTextAlign(); 788f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 789f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt bool needBidi = (flags == kBidi_RTL) || (flags == kBidi_Default_RTL); 790f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (!needBidi && flags < kBidi_Force_LTR) { 791f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt for (int i = 0; i < len; ++i) { 792f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (text[i] >= 0x0590) { 793f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt needBidi = TRUE; 794f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt break; 795f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 796f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 797f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 798f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 799f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt int dir = (flags == kBidi_Force_RTL) ? kDirection_RTL : kDirection_LTR; // will be reset if we run bidi 800f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt UErrorCode status = U_ZERO_ERROR; 801f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jchar *shaped = NULL; 802f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt int32_t slen = 0; 803f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (needBidi || (flags == kBidi_Force_RTL)) { 804f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt shaped = (jchar *)malloc(len * sizeof(jchar)); 805f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (!shaped) { 806f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt status = U_MEMORY_ALLOCATION_ERROR; 807f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } else { 808f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (needBidi) { 809f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt static int RTL_OPTS = UBIDI_DO_MIRRORING | UBIDI_KEEP_BASE_COMBINING | 810f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt UBIDI_REMOVE_BIDI_CONTROLS | UBIDI_OUTPUT_REVERSE; 811f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jint lineDir = 0; 812f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt switch (flags) { 813f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt case kBidi_LTR: lineDir = 0; break; // no ICU constant, canonical LTR level 814f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt case kBidi_RTL: lineDir = 1; break; // no ICU constant, canonical RTL level 815f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt case kBidi_Default_LTR: lineDir = UBIDI_DEFAULT_LTR; break; 816f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt case kBidi_Default_RTL: lineDir = UBIDI_DEFAULT_RTL; break; 817f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 818f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 819f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt UBiDi* bidi = ubidi_open(); 820f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt ubidi_setPara(bidi, text, len, lineDir, NULL, &status); 821f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (U_SUCCESS(status)) { 822f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt dir = ubidi_getParaLevel(bidi) & 0x1; 823f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 824f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt int rc = ubidi_countRuns(bidi, &status); 825f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (U_SUCCESS(status)) { 826f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt int32_t start; 827f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt int32_t length; 828f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt UBiDiDirection dir; 829f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jchar *buffer = NULL; 830f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt for (int i = 0; i < rc; ++i) { 831f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt dir = ubidi_getVisualRun(bidi, i, &start, &length); 832f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt // fake shaping, except it doesn't shape, just mirrors and reverses 833f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt // use harfbuzz when available 834f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (dir == UBIDI_RTL) { 835f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt slen += ubidi_writeReverse(text + start, length, shaped + slen, 836f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt length, RTL_OPTS, &status); 837f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } else { 838f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt for (int i = 0; i < length; ++i) { 839f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt shaped[slen + i] = text[start + i]; 840f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 841f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt slen += length; 842f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 843f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 844f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 845f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt ubidi_close(bidi); 846f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 847f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } else { 848f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt shapeRtlText__(text, len, 0, len, shaped); 849f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 850f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 851f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 852f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 853f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (!U_SUCCESS(status)) { 854f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt char buffer[35]; 855f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt sprintf(buffer, "DrawText bidi error %d", status); 856f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt doThrowIAE(env, buffer); 857f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } else { 858f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt bool trimLeft = false; 859f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt bool trimRight = false; 860f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 861f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt switch (horiz) { 862f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt case SkPaint::kLeft_Align: trimLeft = dir & kDirection_Mask; break; 863f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt case SkPaint::kCenter_Align: trimLeft = trimRight = true; break; 864f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt case SkPaint::kRight_Align: trimRight = !(dir & kDirection_Mask); 865f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt default: break; 866f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 867f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt const jchar* workText = shaped ? shaped : text; 868f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt const jchar* workLimit = workText + len; 869f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 870f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (trimLeft) { 871f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt while (workText < workLimit && *workText == ' ') { 872f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt ++workText; 873f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 874f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 875f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (trimRight) { 876f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt while (workLimit > workText && *(workLimit - 1) == ' ') { 877f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt --workLimit; 878f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 879f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 880f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt int32_t workBytes = (workLimit - workText) << 1; 881f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 882f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt canvas->drawText(workText, workBytes, x_, y_, *paint); 883f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 884f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 885f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (shaped) { 886f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt free(shaped); 887f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 888f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 890f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt static void drawText___CIIFFIPaint(JNIEnv* env, jobject, SkCanvas* canvas, 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jcharArray text, int index, int count, 892f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jfloat x, jfloat y, int flags, SkPaint* paint) { 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jchar* textArray = env->GetCharArrayElements(text, NULL); 894f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt drawText__(env, canvas, textArray + index, count, x, y, flags, paint); 895f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 898f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt static void drawText__StringIIFFIPaint(JNIEnv* env, jobject, 899f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt SkCanvas* canvas, jstring text, 900f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt int start, int end, 901f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jfloat x, jfloat y, int flags, SkPaint* paint) { 902f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt const jchar* textArray = env->GetStringChars(text, NULL); 903f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt drawText__(env, canvas, textArray + start, end - start, x, y, flags, paint); 904f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt env->ReleaseStringChars(text, textArray); 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 907f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt // Draws a unidirectional run of text. Does not run bidi, but does reorder the 908f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt // text and run shaping (or will, when we have harfbuzz support). 909f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt static void drawTextRun__(JNIEnv* env, SkCanvas* canvas, const jchar* chars, int len, 910f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt int start, int count, 911f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jfloat x, jfloat y, int flags, SkPaint* paint) { 912f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 913f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt SkScalar x_ = SkFloatToScalar(x); 914f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt SkScalar y_ = SkFloatToScalar(y); 915f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 916f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt uint8_t rtl = flags & 0x1; 917f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 918f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt UErrorCode status = U_ZERO_ERROR; 919f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jchar *shaped = NULL; 920f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (rtl) { 921f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt shaped = (jchar *)malloc(count * sizeof(jchar)); 922f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (!shaped) { 923f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt status = U_MEMORY_ALLOCATION_ERROR; 924f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } else { 925f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt shapeRtlText__(chars, len, start, count, shaped); 926f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 927f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 928f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 929f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (!U_SUCCESS(status)) { 930f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt char buffer[30]; 931f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt sprintf(buffer, "DrawTextRun error %d", status); 932f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt doThrowIAE(env, buffer); 933f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } else { 934f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (shaped) { 935f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt canvas->drawText(shaped, count << 1, x_, y_, *paint); 936f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } else { 937f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt canvas->drawText(chars + start, count << 1, x_, y_, *paint); 938f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 939f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 940f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 941f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt if (shaped) { 942f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt free(shaped); 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 945f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 946f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt static void drawTextRun___CIIFFIPaint( 947f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt JNIEnv* env, jobject, SkCanvas* canvas, jcharArray text, int index, 948f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt int count, jfloat x, jfloat y, int flags, SkPaint* paint) { 949f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 950f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jint len = env->GetArrayLength(text); 951f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jchar* chars = env->GetCharArrayElements(text, NULL); 952f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt drawTextRun__(env, canvas, chars, len, index, count, x, y, flags, paint); 953f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt env->ReleaseCharArrayElements(text, chars, JNI_ABORT); 954f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 955f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 956f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt static void drawTextRun__StringIIFFIPaint( 957f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt JNIEnv* env, jobject obj, SkCanvas* canvas, jstring text, int start, 958f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt int end, jfloat x, jfloat y, int flags, SkPaint* paint) { 959f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 960f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt jint len = env->GetStringLength(text); 961f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt const jchar* chars = env->GetStringChars(text, NULL); 962f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt drawTextRun__(env, canvas, chars, len, start, end - start, x, y, flags, paint); 963f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt env->ReleaseStringChars(text, chars); 964f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt } 965f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawPosText___CII_FPaint(JNIEnv* env, jobject, SkCanvas* canvas, 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jcharArray text, int index, int count, 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray pos, SkPaint* paint) { 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jchar* textArray = text ? env->GetCharArrayElements(text, NULL) : NULL; 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jsize textCount = text ? env->GetArrayLength(text) : NULL; 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL; 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int posCount = pos ? env->GetArrayLength(pos) >> 1: 0; 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL; 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int indx; 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (indx = 0; indx < posCount; indx++) { 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]); 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]); 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 979ad8b8f57a457ff615112b7fa4987f39e75fc5ff6Mike Reed canvas->drawPosText(textArray + index, count << 1, posPtr, *paint); 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (text) { 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseCharArrayElements(text, textArray, 0); 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos) { 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(pos, posArray, 0); 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] posPtr; 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawPosText__String_FPaint(JNIEnv* env, jobject, 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas, jstring text, 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloatArray pos, SkPaint* paint) { 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* text_ = text ? env->GetStringChars(text, NULL) : NULL; 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int byteLength = text ? env->GetStringLength(text) : 0; 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL; 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int posCount = pos ? env->GetArrayLength(pos) >> 1: 0; 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL; 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int indx = 0; indx < posCount; indx++) { 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]); 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]); 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawPosText(text_, byteLength << 1, posPtr, *paint); 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (text) { 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseStringChars(text, (const jchar*) text_); 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos) { 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(pos, posArray, 0); 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] posPtr; 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawTextOnPath___CIIPathFFPaint(JNIEnv* env, jobject, 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas, jcharArray text, int index, int count, 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPath* path, jfloat hOffset, jfloat vOffset, SkPaint* paint) { 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jchar* textArray = env->GetCharArrayElements(text, NULL); 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawTextOnPathHV(textArray + index, count << 1, *path, 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(hOffset), SkFloatToScalar(vOffset), *paint); 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseCharArrayElements(text, textArray, 0); 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void drawTextOnPath__StringPathFFPaint(JNIEnv* env, jobject, 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* canvas, jstring text, SkPath* path, 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat hOffset, jfloat vOffset, SkPaint* paint) { 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const jchar* text_ = env->GetStringChars(text, NULL); 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int byteLength = env->GetStringLength(text) << 1; 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas->drawTextOnPathHV(text_, byteLength, *path, 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(hOffset), SkFloatToScalar(vOffset), *paint); 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseStringChars(text, text_); 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static bool getClipBounds(JNIEnv* env, jobject, SkCanvas* canvas, 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject bounds) { 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRect r; 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkIRect ir; 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool result = canvas->getClipBounds(&r, SkCanvas::kBW_EdgeType); 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.round(&ir); 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void)GraphicsJNI::irect_to_jrect(ir, env, bounds); 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void getCTM(JNIEnv* env, jobject, SkCanvas* canvas, 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkMatrix* matrix) { 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *matrix = canvas->getTotalMatrix(); 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gCanvasMethods[] = { 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"finalizer", "(I)V", (void*) SkCanvasGlue::finalizer}, 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"initRaster","(I)I", (void*) SkCanvasGlue::initRaster}, 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"initGL","()I", (void*) SkCanvasGlue::initGL}, 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"isOpaque","()Z", (void*) SkCanvasGlue::isOpaque}, 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"getWidth","()I", (void*) SkCanvasGlue::getWidth}, 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"getHeight","()I", (void*) SkCanvasGlue::getHeight}, 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_setBitmap","(II)V", (void*) SkCanvasGlue::setBitmap}, 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"nativeSetViewport", "(III)V", (void*) SkCanvasGlue::setViewport}, 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"save","()I", (void*) SkCanvasGlue::saveAll}, 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"save","(I)I", (void*) SkCanvasGlue::save}, 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_saveLayer","(ILandroid/graphics/RectF;II)I", 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::saveLayer}, 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_saveLayer","(IFFFFII)I", (void*) SkCanvasGlue::saveLayer4F}, 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_saveLayerAlpha","(ILandroid/graphics/RectF;II)I", 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::saveLayerAlpha}, 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_saveLayerAlpha","(IFFFFII)I", 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::saveLayerAlpha4F}, 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"restore","()V", (void*) SkCanvasGlue::restore}, 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"getSaveCount","()I", (void*) SkCanvasGlue::getSaveCount}, 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"restoreToCount","(I)V", (void*) SkCanvasGlue::restoreToCount}, 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"translate","(FF)V", (void*) SkCanvasGlue::translate}, 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"scale","(FF)V", (void*) SkCanvasGlue::scale__FF}, 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"rotate","(F)V", (void*) SkCanvasGlue::rotate__F}, 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"skew","(FF)V", (void*) SkCanvasGlue::skew__FF}, 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_concat","(II)V", (void*) SkCanvasGlue::concat}, 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_setMatrix","(II)V", (void*) SkCanvasGlue::setMatrix}, 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"clipRect","(FFFF)Z", (void*) SkCanvasGlue::clipRect_FFFF}, 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"clipRect","(IIII)Z", (void*) SkCanvasGlue::clipRect_IIII}, 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"clipRect","(Landroid/graphics/RectF;)Z", 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::clipRect_RectF}, 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"clipRect","(Landroid/graphics/Rect;)Z", 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::clipRect_Rect}, 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_clipRect","(IFFFFI)Z", (void*) SkCanvasGlue::clipRect}, 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_clipPath","(III)Z", (void*) SkCanvasGlue::clipPath}, 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_clipRegion","(III)Z", (void*) SkCanvasGlue::clipRegion}, 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"nativeSetDrawFilter", "(II)V", (void*) SkCanvasGlue::setDrawFilter}, 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_getClipBounds","(ILandroid/graphics/Rect;)Z", 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::getClipBounds}, 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_getCTM", "(II)V", (void*)SkCanvasGlue::getCTM}, 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_quickReject","(ILandroid/graphics/RectF;I)Z", 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::quickReject__RectFI}, 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_quickReject","(III)Z", (void*) SkCanvasGlue::quickReject__PathI}, 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_quickReject","(IFFFFI)Z", (void*)SkCanvasGlue::quickReject__FFFFI}, 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawRGB","(IIII)V", (void*) SkCanvasGlue::drawRGB}, 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawARGB","(IIIII)V", (void*) SkCanvasGlue::drawARGB}, 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawColor","(II)V", (void*) SkCanvasGlue::drawColor__I}, 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawColor","(III)V", (void*) SkCanvasGlue::drawColor__II}, 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawPaint","(II)V", (void*) SkCanvasGlue::drawPaint}, 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"drawPoint", "(FFLandroid/graphics/Paint;)V", 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawPoint}, 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"drawPoints", "([FIILandroid/graphics/Paint;)V", 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawPoints}, 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"drawLines", "([FIILandroid/graphics/Paint;)V", 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawLines}, 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawLine","(IFFFFI)V", (void*) SkCanvasGlue::drawLine__FFFFPaint}, 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawRect","(ILandroid/graphics/RectF;I)V", 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawRect__RectFPaint}, 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawRect","(IFFFFI)V", (void*) SkCanvasGlue::drawRect__FFFFPaint}, 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawOval","(ILandroid/graphics/RectF;I)V", 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawOval}, 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawCircle","(IFFFI)V", (void*) SkCanvasGlue::drawCircle}, 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawArc","(ILandroid/graphics/RectF;FFZI)V", 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawArc}, 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawRoundRect","(ILandroid/graphics/RectF;FFI)V", 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawRoundRect}, 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawPath","(III)V", (void*) SkCanvasGlue::drawPath}, 11160d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn {"native_drawBitmap","(IIFFIIII)V", 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawBitmap__BitmapFFPaint}, 11180d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;III)V", 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawBitmapRF}, 11200d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;III)V", 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawBitmapRR}, 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawBitmap", "(I[IIIFFIIZI)V", 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)SkCanvasGlue::drawBitmapArray}, 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"nativeDrawBitmapMatrix", "(IIII)V", 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)SkCanvasGlue::drawBitmapMatrix}, 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"nativeDrawBitmapMesh", "(IIII[FI[III)V", 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)SkCanvasGlue::drawBitmapMesh}, 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"nativeDrawVertices", "(III[FI[FI[II[SIII)V", 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)SkCanvasGlue::drawVertices}, 1131f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt {"native_drawText","(I[CIIFFII)V", 1132f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt (void*) SkCanvasGlue::drawText___CIIFFIPaint}, 1133f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt {"native_drawText","(ILjava/lang/String;IIFFII)V", 1134f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt (void*) SkCanvasGlue::drawText__StringIIFFIPaint}, 1135f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt {"native_drawTextRun","(I[CIIFFII)V", 1136f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt (void*) SkCanvasGlue::drawTextRun___CIIFFIPaint}, 1137f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt {"native_drawTextRun","(ILjava/lang/String;IIFFII)V", 1138f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt (void*) SkCanvasGlue::drawTextRun__StringIIFFIPaint}, 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawPosText","(I[CII[FI)V", 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawPosText___CII_FPaint}, 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawPosText","(ILjava/lang/String;[FI)V", 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawPosText__String_FPaint}, 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawTextOnPath","(I[CIIIFFI)V", 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawTextOnPath___CIIPathFFPaint}, 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawTextOnPath","(ILjava/lang/String;IFFI)V", 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint}, 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_drawPicture", "(II)V", (void*) SkCanvasGlue::drawPicture}, 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches} 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1152c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed/////////////////////////////////////////////////////////////////////////////// 1153c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 1154c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reedstatic void BoundaryPatch_computeCubic(JNIEnv* env, jobject, jfloatArray jpts, 1155c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed int texW, int texH, int rows, int cols, 1156c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed jfloatArray jverts, jshortArray jidx) { 1157c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed AutoJavaFloatArray ptsArray(env, jpts, 24, kRO_JNIAccess); 1158c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 1159c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed int vertCount = rows * cols; 1160c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed AutoJavaFloatArray vertsArray(env, jverts, vertCount * 4, kRW_JNIAccess); 1161c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed SkPoint* verts = (SkPoint*)vertsArray.ptr(); 1162c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed SkPoint* texs = verts + vertCount; 1163c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 1164c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed int idxCount = (rows - 1) * (cols - 1) * 6; 1165c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed AutoJavaShortArray idxArray(env, jidx, idxCount, kRW_JNIAccess); 1166c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed uint16_t* idx = (uint16_t*)idxArray.ptr(); // cast from int16_t* 1167c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 1168c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed SkCubicBoundary cubic; 1169c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed memcpy(cubic.fPts, ptsArray.ptr(), 12 * sizeof(SkPoint)); 1170c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 1171c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed SkBoundaryPatch patch; 1172c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed patch.setBoundary(&cubic); 1173c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed // generate our verts 1174c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed patch.evalPatch(verts, rows, cols); 1175c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 1176c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed SkMeshIndices mesh; 1177c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed // generate our texs and idx 1178c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed mesh.init(texs, idx, texW, texH, rows, cols); 1179c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed} 1180c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 1181c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reedstatic JNINativeMethod gBoundaryPatchMethods[] = { 1182c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed {"nativeComputeCubicPatch", "([FIIII[F[S)V", 1183c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed (void*)BoundaryPatch_computeCubic }, 1184c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed}; 1185c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 1186c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed/////////////////////////////////////////////////////////////////////////////// 1187c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h> 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define REG(env, name, array) \ 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = android::AndroidRuntime::registerNativeMethods(env, name, array, \ 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SK_ARRAY_COUNT(array)); \ 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result < 0) return result 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_graphics_Canvas(JNIEnv* env) { 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result; 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project REG(env, "android/graphics/Canvas", gCanvasMethods); 1199c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed REG(env, "android/graphics/utils/BoundaryPatch", gBoundaryPatchMethods); 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1205