Canvas.cpp revision 47c0d4eaa926d979c5ea366934750526c20af8ff
14f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* 24f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Copyright (C) 2006-2007 The Android Open Source Project 34f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * 44f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 54f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * you may not use this file except in compliance with the License. 64f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * You may obtain a copy of the License at 74f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * 84f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 94f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * 104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * See the License for the specific language governing permissions and 144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * limitations under the License. 154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "jni.h" 184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "GraphicsJNI.h" 194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <android_runtime/AndroidRuntime.h> 204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "SkCanvas.h" 224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "SkDevice.h" 234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "SkGLCanvas.h" 244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "SkGraphics.h" 254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "SkImageRef_GlobalPool.h" 264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "SkPorterDuff.h" 274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "SkShader.h" 284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "SkTemplates.h" 294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#define TIME_DRAWx 314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 32e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik)static uint32_t get_thread_msec() { 334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if defined(HAVE_POSIX_CLOCKS) 344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct timespec tm; 354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm); 374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 386310a8261c922533a692fb3e74ece2da98d4bafaColin Cross return tm.tv_sec * 1000LL + tm.tv_nsec / 1000000; 393899e9fc01cf608f19f716749c54cc5c4d17e766Colin Cross#else 40ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross struct timeval tv; 414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project gettimeofday(&tv, NULL); 434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return tv.tv_sec * 1000LL + tv.tv_usec / 1000; 444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectnamespace android { 484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectclass SkCanvasGlue { 504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectpublic: 514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void finalizer(JNIEnv* env, jobject clazz, SkCanvas* canvas) { 534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->unref(); 544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 55008abac082f1c098d402f944d9287dce67ffce0aMike Chan 564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static SkCanvas* initRaster(JNIEnv* env, jobject, SkBitmap* bitmap) { 574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return bitmap ? new SkCanvas(*bitmap) : new SkCanvas; 584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static SkCanvas* initGL(JNIEnv* env, jobject) { 614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return new SkGLCanvas; 624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void freeCaches(JNIEnv* env, jobject) { 65008abac082f1c098d402f944d9287dce67ffce0aMike Chan // these are called in no particular order 664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkGLCanvas::DeleteAllTextures(); 674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkImageRef_GlobalPool::SetRAMUsed(0); 684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkGraphics::SetFontCacheUsed(0); 694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7135237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project static jboolean isOpaque(JNIEnv* env, jobject jcanvas) { 724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* 764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project Currently we cannot support transparency in GL-based canvas' at 774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project the view level. Therefore we cannot base our answer on the device's 784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bitmap, but need to hard-code the answer. If we relax this 794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project limitation in views, we can simplify the following code as well. 804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8135237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project Use the getViewport() call to find out if we're gl-based... 824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (canvas->getViewport(NULL)) { 844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return true; 854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project // normal technique, rely on the device's bitmap for the answer 884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return canvas->getDevice()->accessBitmap(false).isOpaque(); 894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static int getWidth(JNIEnv* env, jobject jcanvas) { 924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return canvas->getDevice()->accessBitmap(false).width(); 954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static int getHeight(JNIEnv* env, jobject jcanvas) { 984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 1004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return canvas->getDevice()->accessBitmap(false).height(); 1014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void setViewport(JNIEnv* env, jobject, SkCanvas* canvas, 1044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int width, int height) { 1054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->setViewport(width, height); 1064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void setBitmap(JNIEnv* env, jobject, SkCanvas* canvas, 1094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkBitmap* bitmap) { 1104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->setBitmapDevice(*bitmap); 1114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static int saveAll(JNIEnv* env, jobject jcanvas) { 1144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 1154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return GraphicsJNI::getNativeCanvas(env, jcanvas)->save(); 1164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static int save(JNIEnv* env, jobject jcanvas, SkCanvas::SaveFlags flags) { 1194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 1204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return GraphicsJNI::getNativeCanvas(env, jcanvas)->save(flags); 1214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static int saveLayer(JNIEnv* env, jobject, SkCanvas* canvas, jobject bounds, 1244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkPaint* paint, int flags) { 1254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect* bounds_ = NULL; 1264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect storage; 1274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (bounds != NULL) { 1284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, bounds, &storage); 1294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bounds_ = &storage; 1304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return canvas->saveLayer(bounds_, paint, (SkCanvas::SaveFlags)flags); 1324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 133f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 1344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static int saveLayer4F(JNIEnv* env, jobject, SkCanvas* canvas, 1354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat l, jfloat t, jfloat r, jfloat b, 1364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkPaint* paint, int flags) { 137e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) SkRect bounds; 138e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) bounds.set(SkFloatToScalar(l), SkFloatToScalar(t), SkFloatToScalar(r), 139e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) SkFloatToScalar(b)); 140e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) return canvas->saveLayer(&bounds, paint, (SkCanvas::SaveFlags)flags); 141e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) } 142e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) 143e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) static int saveLayerAlpha(JNIEnv* env, jobject, SkCanvas* canvas, 144e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) jobject bounds, int alpha, int flags) { 145e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) SkRect* bounds_ = NULL; 146e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) SkRect storage; 147e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) if (bounds != NULL) { 148e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik) GraphicsJNI::jrectf_to_rect(env, bounds, &storage); 1494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bounds_ = &storage; 1504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return canvas->saveLayerAlpha(bounds_, alpha, 1524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project (SkCanvas::SaveFlags)flags); 1534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static int saveLayerAlpha4F(JNIEnv* env, jobject, SkCanvas* canvas, 1564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat l, jfloat t, jfloat r, jfloat b, 1574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int alpha, int flags) { 1584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect bounds; 1594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bounds.set(SkFloatToScalar(l), SkFloatToScalar(t), SkFloatToScalar(r), 1604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkFloatToScalar(b)); 1614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return canvas->saveLayerAlpha(&bounds, alpha, 1624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project (SkCanvas::SaveFlags)flags); 1634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void restore(JNIEnv* env, jobject jcanvas) { 1664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 1674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 1684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (canvas->getSaveCount() <= 1) { // cannot restore anymore 1694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project doThrowISE(env, "Underflow in restore"); 1704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->restore(); 1734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static int getSaveCount(JNIEnv* env, jobject jcanvas) { 1764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 1774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return GraphicsJNI::getNativeCanvas(env, jcanvas)->getSaveCount(); 1784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void restoreToCount(JNIEnv* env, jobject jcanvas, int restoreCount) { 1814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 1824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 1834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (restoreCount < 1) { 1844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project doThrowIAE(env, "Underflow in restoreToCount"); 1854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->restoreToCount(restoreCount); 1884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void translate(JNIEnv* env, jobject jcanvas, jfloat dx, jfloat dy) { 19135237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 19235237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project SkScalar dx_ = SkFloatToScalar(dx); 19335237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project SkScalar dy_ = SkFloatToScalar(dy); 19435237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->translate(dx_, dy_); 19535237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project } 19635237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project 19735237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project static void scale__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) { 19835237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 19935237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project SkScalar sx_ = SkFloatToScalar(sx); 20035237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project SkScalar sy_ = SkFloatToScalar(sy); 20135237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->scale(sx_, sy_); 20235237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project } 20335237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project 20435237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project static void rotate__F(JNIEnv* env, jobject jcanvas, jfloat degrees) { 20535237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 20635237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project SkScalar degrees_ = SkFloatToScalar(degrees); 20735237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->rotate(degrees_); 20835237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project } 2094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void skew__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) { 21135237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 21235237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project SkScalar sx_ = SkFloatToScalar(sx); 21335237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project SkScalar sy_ = SkFloatToScalar(sy); 21435237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->skew(sx_, sy_); 21535237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project } 21635237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project 21735237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project static void concat(JNIEnv* env, jobject, SkCanvas* canvas, 21835237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project const SkMatrix* matrix) { 21935237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project canvas->concat(*matrix); 2204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void setMatrix(JNIEnv* env, jobject, SkCanvas* canvas, 2234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project const SkMatrix* matrix) { 2246310a8261c922533a692fb3e74ece2da98d4bafaColin Cross if (NULL == matrix) { 2254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->resetMatrix(); 2264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 2274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->setMatrix(*matrix); 2284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static jboolean clipRect_FFFF(JNIEnv* env, jobject jcanvas, jfloat left, 2324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat top, jfloat right, jfloat bottom) { 2334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 2344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect r; 2354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project r.set(SkFloatToScalar(left), SkFloatToScalar(top), 2364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkFloatToScalar(right), SkFloatToScalar(bottom)); 2374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas); 2384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return c->clipRect(r); 2394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static jboolean clipRect_IIII(JNIEnv* env, jobject jcanvas, jint left, 2424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jint top, jint right, jint bottom) { 2434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 2444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect r; 2454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project r.set(SkIntToScalar(left), SkIntToScalar(top), 2464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkIntToScalar(right), SkIntToScalar(bottom)); 2474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return GraphicsJNI::getNativeCanvas(env, jcanvas)->clipRect(r); 2484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static jboolean clipRect_RectF(JNIEnv* env, jobject jcanvas, jobject rectf) { 2514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 2524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, rectf); 2534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas); 2544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect tmp; 2554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return c->clipRect(*GraphicsJNI::jrectf_to_rect(env, rectf, &tmp)); 2564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static jboolean clipRect_Rect(JNIEnv* env, jobject jcanvas, jobject rect) { 2594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jcanvas); 2604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, rect); 2614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas); 2624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect tmp; 2634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return c->clipRect(*GraphicsJNI::jrect_to_rect(env, rect, &tmp)); 2644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static jboolean clipRect(JNIEnv* env, jobject, SkCanvas* canvas, 2674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project float left, float top, float right, float bottom, 2684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int op) { 2694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect rect; 2704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project rect.set(SkFloatToScalar(left), SkFloatToScalar(top), 2714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkFloatToScalar(right), SkFloatToScalar(bottom)); 2724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return canvas->clipRect(rect, (SkRegion::Op)op); 2734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static jboolean clipPath(JNIEnv* env, jobject, SkCanvas* canvas, 276e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) SkPath* path, int op) { 2774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return canvas->clipPath(*path, (SkRegion::Op)op); 2784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 280cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross static jboolean clipRegion(JNIEnv* env, jobject, SkCanvas* canvas, 2814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRegion* deviceRgn, int op) { 2824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return canvas->clipRegion(*deviceRgn, (SkRegion::Op)op); 2834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void setDrawFilter(JNIEnv* env, jobject, SkCanvas* canvas, 2864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkDrawFilter* filter) { 2874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->setDrawFilter(filter); 2884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 290cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross static jboolean quickReject__RectFI(JNIEnv* env, jobject, SkCanvas* canvas, 291cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross jobject rect, int edgetype) { 292cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross SkRect rect_; 293cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross GraphicsJNI::jrectf_to_rect(env, rect, &rect_); 294cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross return canvas->quickReject(rect_, (SkCanvas::EdgeType)edgetype); 295cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross } 296cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross 2974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static jboolean quickReject__PathI(JNIEnv* env, jobject, SkCanvas* canvas, 2984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkPath* path, int edgetype) { 299e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) return canvas->quickReject(*path, (SkCanvas::EdgeType)edgetype); 3004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 301e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 302e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) static jboolean quickReject__FFFFI(JNIEnv* env, jobject, SkCanvas* canvas, 3034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat left, jfloat top, jfloat right, 3044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat bottom, int edgetype) { 305e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) SkRect r; 306e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) r.set(SkFloatToScalar(left), SkFloatToScalar(top), 307e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) SkFloatToScalar(right), SkFloatToScalar(bottom)); 308e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) return canvas->quickReject(r, (SkCanvas::EdgeType)edgetype); 309e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) } 310e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 311cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross static void drawRGB(JNIEnv* env, jobject, SkCanvas* canvas, 312cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross jint r, jint g, jint b) { 313e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) canvas->drawARGB(0xFF, r, g, b); 314e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) } 315e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 316e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) static void drawARGB(JNIEnv* env, jobject, SkCanvas* canvas, 317e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) jint a, jint r, jint g, jint b) { 318e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) canvas->drawARGB(a, r, g, b); 319e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) } 320e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 321e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) static void drawColor__I(JNIEnv* env, jobject, SkCanvas* canvas, 322e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) jint color) { 323e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) canvas->drawColor(color); 324e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) } 325e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 3264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawColor__II(JNIEnv* env, jobject, SkCanvas* canvas, 327e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) jint color, SkPorterDuff::Mode mode) { 328e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) canvas->drawColor(color, SkPorterDuff::ToXfermodeMode(mode)); 329e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) } 330e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 331e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) static void drawPaint(JNIEnv* env, jobject, SkCanvas* canvas, 332e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) SkPaint* paint) { 333e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) canvas->drawPaint(*paint); 334e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) } 335e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 336e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) static void doPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray, 337e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) jint offset, jint count, jobject jpaint, 338e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) SkCanvas::PointMode mode) { 339e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) NPE_CHECK_RETURN_VOID(env, jcanvas); 340e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) NPE_CHECK_RETURN_VOID(env, jptsArray); 341e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) NPE_CHECK_RETURN_VOID(env, jpaint); 342e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 343e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint); 344e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 345e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) AutoJavaFloatArray autoPts(env, jptsArray); 346e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) float* floats = autoPts.ptr(); 347e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) const int length = autoPts.length(); 348e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 349e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) if ((offset | count) < 0 || offset + count > length) { 350e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) doThrowAIOOBE(env); 351e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) return; 352e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) } 353e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 354e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) // now convert the floats into SkPoints 355e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) count >>= 1; // now it is the number of points 356e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) SkAutoSTMalloc<32, SkPoint> storage(count); 357e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) SkPoint* pts = storage.get(); 358e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) const float* src = floats + offset; 359cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross for (int i = 0; i < count; i++) { 360cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross pts[i].set(SkFloatToScalar(src[0]), SkFloatToScalar(src[1])); 361e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) src += 2; 362e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) } 363e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) canvas->drawPoints(mode, count, pts, paint); 364e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) } 365e520d036165b36cf5c4cb305f9cec7d183977b61Jay Freeman (saurik) 3664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray, 3674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jint offset, jint count, jobject jpaint) { 3684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project doPoints(env, jcanvas, jptsArray, offset, count, jpaint, 3694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas::kPoints_PointMode); 3704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawLines(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray, 3734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jint offset, jint count, jobject jpaint) { 3744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project doPoints(env, jcanvas, jptsArray, offset, count, jpaint, 3754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas::kLines_PointMode); 3764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawPoint(JNIEnv* env, jobject jcanvas, float x, float y, 3794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jobject jpaint) { 3804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jcanvas); 3814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NPE_CHECK_RETURN_VOID(env, jpaint); 3824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); 3834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint); 3844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->drawPoint(SkFloatToScalar(x), SkFloatToScalar(y), paint); 3864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawLine__FFFFPaint(JNIEnv* env, jobject, SkCanvas* canvas, 3894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat startX, jfloat startY, jfloat stopX, 3904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat stopY, SkPaint* paint) { 3914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->drawLine(SkFloatToScalar(startX), SkFloatToScalar(startY), 3924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkFloatToScalar(stopX), SkFloatToScalar(stopY), 3934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *paint); 3944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawRect__RectFPaint(JNIEnv* env, jobject, SkCanvas* canvas, 3974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jobject rect, SkPaint* paint) { 3984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect rect_; 399f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat GraphicsJNI::jrectf_to_rect(env, rect, &rect_); 4004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->drawRect(rect_, *paint); 4014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawRect__FFFFPaint(JNIEnv* env, jobject, SkCanvas* canvas, 4044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat left, jfloat top, jfloat right, 4054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat bottom, SkPaint* paint) { 4064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkScalar left_ = SkFloatToScalar(left); 4074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkScalar top_ = SkFloatToScalar(top); 4084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkScalar right_ = SkFloatToScalar(right); 4094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkScalar bottom_ = SkFloatToScalar(bottom); 4104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->drawRectCoords(left_, top_, right_, bottom_, *paint); 4114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawOval(JNIEnv* env, jobject, SkCanvas* canvas, jobject joval, 4144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkPaint* paint) { 4154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect oval; 4164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, joval, &oval); 4174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->drawOval(oval, *paint); 4184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 420f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat static void drawCircle(JNIEnv* env, jobject, SkCanvas* canvas, jfloat cx, 4214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat cy, jfloat radius, SkPaint* paint) { 4224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->drawCircle(SkFloatToScalar(cx), SkFloatToScalar(cy), 4234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkFloatToScalar(radius), *paint); 4244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawArc(JNIEnv* env, jobject, SkCanvas* canvas, jobject joval, 42711e1c42df69b15c938aa1b7570e4370e6ab15a86Jay Freeman (saurik) jfloat startAngle, jfloat sweepAngle, 4284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jboolean useCenter, SkPaint* paint) { 4294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkRect oval; 4304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, joval, &oval); 4314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->drawArc(oval, SkFloatToScalar(startAngle), 4324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkFloatToScalar(sweepAngle), useCenter, *paint); 4334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawRoundRect(JNIEnv* env, jobject, SkCanvas* canvas, 43635237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project jobject jrect, jfloat rx, jfloat ry, 43735237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project SkPaint* paint) { 43835237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project SkRect rect; 43935237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project GraphicsJNI::jrectf_to_rect(env, jrect, &rect); 44035237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project canvas->drawRoundRect(rect, SkFloatToScalar(rx), SkFloatToScalar(ry), 44135237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project *paint); 44235237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project } 44335237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project 44435237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project static void drawPath(JNIEnv* env, jobject, SkCanvas* canvas, SkPath* path, 44535237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project SkPaint* paint) { 44635237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project canvas->drawPath(*path, *paint); 44735237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project } 44835237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project 44935237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project static void drawPicture(JNIEnv* env, jobject, SkCanvas* canvas, 4504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkPicture* picture) { 4514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkASSERT(canvas); 4524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkASSERT(picture); 4534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#ifdef TIME_DRAW 4557c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkMSec now = get_thread_msec(); //SkTime::GetMSecs(); 4567c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat#endif 4577c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat canvas->drawPicture(*picture); 4587c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat#ifdef TIME_DRAW 4597c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat LOGD("---- picture playback %d ms\n", get_thread_msec() - now); 4607c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat#endif 4617c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat } 4627c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat 4637c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat static void drawBitmap__BitmapFFPaint(JNIEnv* env, jobject jcanvas, 4647c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkCanvas* canvas, SkBitmap* bitmap, 4657c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat jfloat left, jfloat top, 4667c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkPaint* paint, 4677c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat jboolean autoScale, jfloat densityScale) { 4687c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkScalar left_ = SkFloatToScalar(left); 4697c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkScalar top_ = SkFloatToScalar(top); 4707c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat 4717c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat if (!autoScale || densityScale <= 0.0f) { 4727c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat canvas->drawBitmap(*bitmap, left_, top_, paint); 4734833d9f4986d6dafacff841beb3bf93172c84bdcTom Zhu } else { 4747c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat canvas->save(); 4757c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkScalar canvasScale = GraphicsJNI::getCanvasDensityScale(env, jcanvas); 4767c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkScalar scale = canvasScale / SkFloatToScalar(densityScale); 4777c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat canvas->scale(scale, scale); 4787c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat 4797c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkPaint filteredPaint; 4807c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat if (paint) { 4817c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat filteredPaint = *paint; 4827c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat } 4837c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat filteredPaint.setFilterBitmap(true); 4847c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat 4857c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint); 4867c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat 4877c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat canvas->restore(); 4887c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat } 4897c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat } 4907c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat 4917c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap, 4927c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat jobject srcIRect, const SkRect& dst, SkPaint* paint) { 4937c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkIRect src, *srcPtr = NULL; 4947c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat 4957c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat if (NULL != srcIRect) { 4967c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat GraphicsJNI::jrect_to_irect(env, srcIRect, &src); 4977c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat srcPtr = &src; 4987c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat } 4997c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint); 5007c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat } 5017c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat 5027c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat static void drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas, 5037c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkBitmap* bitmap, jobject srcIRect, 5047c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat jobject dstRectF, SkPaint* paint) { 5057c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkRect dst; 5067c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst); 5077c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint); 5087c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat } 5097c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat 5107c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat static void drawBitmapRR(JNIEnv* env, jobject, SkCanvas* canvas, 5117c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkBitmap* bitmap, jobject srcIRect, 5127c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat jobject dstRect, SkPaint* paint) { 5137c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat SkRect dst; 5147c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat GraphicsJNI::jrect_to_rect(env, dstRect, &dst); 5157c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint); 5167c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat } 5174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawBitmapArray(JNIEnv* env, jobject, SkCanvas* canvas, 5194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jintArray jcolors, int offset, int stride, 5204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloat x, jfloat y, int width, int height, 5214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jboolean hasAlpha, SkPaint* paint) 5224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project { 5234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkBitmap bitmap; 5244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bitmap.setConfig(hasAlpha ? SkBitmap::kARGB_8888_Config : 5264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkBitmap::kRGB_565_Config, width, height); 5274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!bitmap.allocPixels()) { 5284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 5294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!GraphicsJNI::SetPixels(env, jcolors, offset, stride, 5324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 0, 0, width, height, bitmap)) { 5334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 5344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->drawBitmap(bitmap, SkFloatToScalar(x), SkFloatToScalar(y), 5374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project paint); 5384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawBitmapMatrix(JNIEnv* env, jobject, SkCanvas* canvas, 5414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project const SkBitmap* bitmap, const SkMatrix* matrix, 5424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project const SkPaint* paint) { 5434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project canvas->drawBitmapMatrix(*bitmap, *matrix, paint); 5444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static void drawBitmapMesh(JNIEnv* env, jobject, SkCanvas* canvas, 5474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project const SkBitmap* bitmap, int meshWidth, int meshHeight, 5484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project jfloatArray jverts, int vertIndex, jintArray jcolors, 5494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int colorIndex, const SkPaint* paint) { 5504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project const int ptCount = (meshWidth + 1) * (meshHeight + 1); 5524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project const int indexCount = meshWidth * meshHeight * 6; 5534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1)); 5554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount); 5564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* Our temp storage holds 2 or 3 arrays. 5584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project texture points [ptCount * sizeof(SkPoint)] 5594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project optionally vertex points [ptCount * sizeof(SkPoint)] if we need a 5604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project copy to convert from float to fixed 5614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project indices [ptCount * sizeof(uint16_t)] 5624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 5634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ssize_t storageSize = ptCount * sizeof(SkPoint); // texs[] 5644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#ifdef SK_SCALAR_IS_FIXED 5654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project storageSize += ptCount * sizeof(SkPoint); // storage for verts 5664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 5674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project storageSize += indexCount * sizeof(uint16_t); // indices[] 5684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkAutoMalloc storage(storageSize); 5704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkPoint* texs = (SkPoint*)storage.get(); 5714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SkPoint* verts; 5724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project uint16_t* indices; 5734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#ifdef SK_SCALAR_IS_FLOAT 5744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project verts = (SkPoint*)(vertA.ptr() + vertIndex); 5754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project indices = (uint16_t*)(texs + ptCount); 5764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#else 5774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project verts = texs + ptCount; 5784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project indices = (uint16_t*)(verts + ptCount); 5794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project // convert floats to fixed 5804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project { 5814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project const float* src = vertA.ptr() + vertIndex; 5824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (int i = 0; i < ptCount; i++) { 5834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1])); 5844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project src += 2; 5854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 586cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross } 587cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross#endif 588cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross 589cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross // cons up texture coordinates and indices 590cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross { 591cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross const SkScalar w = SkIntToScalar(bitmap->width()); 592cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross const SkScalar h = SkIntToScalar(bitmap->height()); 593cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross const SkScalar dx = w / meshWidth; 594 const SkScalar dy = h / meshHeight; 595 596 SkPoint* texsPtr = texs; 597 SkScalar y = 0; 598 for (int i = 0; i <= meshHeight; i++) { 599 if (i == meshHeight) { 600 y = h; // to ensure numerically we hit h exactly 601 } 602 SkScalar x = 0; 603 for (int j = 0; j < meshWidth; j++) { 604 texsPtr->set(x, y); 605 texsPtr += 1; 606 x += dx; 607 } 608 texsPtr->set(w, y); 609 texsPtr += 1; 610 y += dy; 611 } 612 SkASSERT(texsPtr - texs == ptCount); 613 } 614 615 // cons up indices 616 { 617 uint16_t* indexPtr = indices; 618 int index = 0; 619 for (int i = 0; i < meshHeight; i++) { 620 for (int j = 0; j < meshWidth; j++) { 621 // lower-left triangle 622 *indexPtr++ = index; 623 *indexPtr++ = index + meshWidth + 1; 624 *indexPtr++ = index + meshWidth + 2; 625 // upper-right triangle 626 *indexPtr++ = index; 627 *indexPtr++ = index + meshWidth + 2; 628 *indexPtr++ = index + 1; 629 // bump to the next cell 630 index += 1; 631 } 632 // bump to the next row 633 index += 1; 634 } 635 SkASSERT(indexPtr - indices == indexCount); 636 SkASSERT((char*)indexPtr - (char*)storage.get() == storageSize); 637 } 638 639 // double-check that we have legal indices 640#ifdef SK_DEBUG 641 { 642 for (int i = 0; i < indexCount; i++) { 643 SkASSERT((unsigned)indices[i] < (unsigned)ptCount); 644 } 645 } 646#endif 647 648 // cons-up a shader for the bitmap 649 SkPaint tmpPaint; 650 if (paint) { 651 tmpPaint = *paint; 652 } 653 SkShader* shader = SkShader::CreateBitmapShader(*bitmap, 654 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); 655 tmpPaint.setShader(shader)->safeUnref(); 656 657 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, verts, 658 texs, (const SkColor*)colorA.ptr(), NULL, indices, 659 indexCount, tmpPaint); 660 } 661 662 static void drawVertices(JNIEnv* env, jobject, SkCanvas* canvas, 663 SkCanvas::VertexMode mode, int vertexCount, 664 jfloatArray jverts, int vertIndex, 665 jfloatArray jtexs, int texIndex, 666 jintArray jcolors, int colorIndex, 667 jshortArray jindices, int indexIndex, 668 int indexCount, const SkPaint* paint) { 669 670 AutoJavaFloatArray vertA(env, jverts, vertIndex + vertexCount); 671 AutoJavaFloatArray texA(env, jtexs, texIndex + vertexCount); 672 AutoJavaIntArray colorA(env, jcolors, colorIndex + vertexCount); 673 AutoJavaShortArray indexA(env, jindices, indexIndex + indexCount); 674 675 const int ptCount = vertexCount >> 1; 676 677 SkPoint* verts; 678 SkPoint* texs = NULL; 679#ifdef SK_SCALAR_IS_FLOAT 680 verts = (SkPoint*)(vertA.ptr() + vertIndex); 681 if (jtexs != NULL) { 682 texs = (SkPoint*)(texA.ptr() + texIndex); 683 } 684#else 685 int count = ptCount; // for verts 686 if (jtexs != NULL) { 687 count += ptCount; // += for texs 688 } 689 SkAutoMalloc storage(count * sizeof(SkPoint)); 690 verts = (SkPoint*)storage.get(); 691 const float* src = vertA.ptr() + vertIndex; 692 for (int i = 0; i < ptCount; i++) { 693 verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1])); 694 src += 2; 695 } 696 if (jtexs != NULL) { 697 texs = verts + ptCount; 698 src = texA.ptr() + texIndex; 699 for (int i = 0; i < ptCount; i++) { 700 texs[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1])); 701 src += 2; 702 } 703 } 704#endif 705 706 const SkColor* colors = NULL; 707 const uint16_t* indices = NULL; 708 if (jcolors != NULL) { 709 colors = (const SkColor*)(colorA.ptr() + colorIndex); 710 } 711 if (jindices != NULL) { 712 indices = (const uint16_t*)(indexA.ptr() + indexIndex); 713 } 714 715 canvas->drawVertices(mode, ptCount, verts, texs, colors, NULL, 716 indices, indexCount, *paint); 717 } 718 719 static void drawText___CIIFFPaint(JNIEnv* env, jobject, SkCanvas* canvas, 720 jcharArray text, int index, int count, 721 jfloat x, jfloat y, SkPaint* paint) { 722 jchar* textArray = env->GetCharArrayElements(text, NULL); 723 jsize textCount = env->GetArrayLength(text); 724 SkScalar x_ = SkFloatToScalar(x); 725 SkScalar y_ = SkFloatToScalar(y); 726 canvas->drawText(textArray + index, count << 1, x_, y_, *paint); 727 env->ReleaseCharArrayElements(text, textArray, 0); 728 } 729 730 static void drawText__StringIIFFPaint(JNIEnv* env, jobject, 731 SkCanvas* canvas, jstring text, int start, int end, 732 jfloat x, jfloat y, SkPaint* paint) { 733 const void* text_ = env->GetStringChars(text, NULL); 734 SkScalar x_ = SkFloatToScalar(x); 735 SkScalar y_ = SkFloatToScalar(y); 736 canvas->drawText((const uint16_t*)text_ + start, (end - start) << 1, 737 x_, y_, *paint); 738 env->ReleaseStringChars(text, (const jchar*) text_); 739 } 740 741 static void drawString(JNIEnv* env, jobject canvas, jstring text, 742 jfloat x, jfloat y, jobject paint) { 743 NPE_CHECK_RETURN_VOID(env, canvas); 744 NPE_CHECK_RETURN_VOID(env, paint); 745 NPE_CHECK_RETURN_VOID(env, text); 746 size_t count = env->GetStringLength(text); 747 if (0 == count) { 748 return; 749 } 750 const jchar* text_ = env->GetStringChars(text, NULL); 751 SkCanvas* c = GraphicsJNI::getNativeCanvas(env, canvas); 752 c->drawText(text_, count << 1, SkFloatToScalar(x), SkFloatToScalar(y), 753 *GraphicsJNI::getNativePaint(env, paint)); 754 env->ReleaseStringChars(text, text_); 755 } 756 757 static void drawPosText___CII_FPaint(JNIEnv* env, jobject, SkCanvas* canvas, 758 jcharArray text, int index, int count, 759 jfloatArray pos, SkPaint* paint) { 760 jchar* textArray = text ? env->GetCharArrayElements(text, NULL) : NULL; 761 jsize textCount = text ? env->GetArrayLength(text) : NULL; 762 float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL; 763 int posCount = pos ? env->GetArrayLength(pos) >> 1: 0; 764 SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL; 765 int indx; 766 for (indx = 0; indx < posCount; indx++) { 767 posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]); 768 posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]); 769 } 770 canvas->drawPosText(textArray + index, count << 1, posPtr, *paint); 771 if (text) { 772 env->ReleaseCharArrayElements(text, textArray, 0); 773 } 774 if (pos) { 775 env->ReleaseFloatArrayElements(pos, posArray, 0); 776 } 777 delete[] posPtr; 778 } 779 780 static void drawPosText__String_FPaint(JNIEnv* env, jobject, 781 SkCanvas* canvas, jstring text, 782 jfloatArray pos, SkPaint* paint) { 783 const void* text_ = text ? env->GetStringChars(text, NULL) : NULL; 784 int byteLength = text ? env->GetStringLength(text) : 0; 785 float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL; 786 int posCount = pos ? env->GetArrayLength(pos) >> 1: 0; 787 SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL; 788 789 for (int indx = 0; indx < posCount; indx++) { 790 posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]); 791 posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]); 792 } 793 canvas->drawPosText(text_, byteLength << 1, posPtr, *paint); 794 if (text) { 795 env->ReleaseStringChars(text, (const jchar*) text_); 796 } 797 if (pos) { 798 env->ReleaseFloatArrayElements(pos, posArray, 0); 799 } 800 delete[] posPtr; 801 } 802 803 static void drawTextOnPath___CIIPathFFPaint(JNIEnv* env, jobject, 804 SkCanvas* canvas, jcharArray text, int index, int count, 805 SkPath* path, jfloat hOffset, jfloat vOffset, SkPaint* paint) { 806 807 jchar* textArray = env->GetCharArrayElements(text, NULL); 808 canvas->drawTextOnPathHV(textArray + index, count << 1, *path, 809 SkFloatToScalar(hOffset), SkFloatToScalar(vOffset), *paint); 810 env->ReleaseCharArrayElements(text, textArray, 0); 811 } 812 813 static void drawTextOnPath__StringPathFFPaint(JNIEnv* env, jobject, 814 SkCanvas* canvas, jstring text, SkPath* path, 815 jfloat hOffset, jfloat vOffset, SkPaint* paint) { 816 const jchar* text_ = env->GetStringChars(text, NULL); 817 int byteLength = env->GetStringLength(text) << 1; 818 canvas->drawTextOnPathHV(text_, byteLength, *path, 819 SkFloatToScalar(hOffset), SkFloatToScalar(vOffset), *paint); 820 env->ReleaseStringChars(text, text_); 821 } 822 823 static bool getClipBounds(JNIEnv* env, jobject, SkCanvas* canvas, 824 jobject bounds) { 825 SkRect r; 826 SkIRect ir; 827 bool result = canvas->getClipBounds(&r, SkCanvas::kBW_EdgeType); 828 829 r.round(&ir); 830 (void)GraphicsJNI::irect_to_jrect(ir, env, bounds); 831 return result; 832 } 833 834 static void getCTM(JNIEnv* env, jobject, SkCanvas* canvas, 835 SkMatrix* matrix) { 836 *matrix = canvas->getTotalMatrix(); 837 } 838}; 839 840/////////////////////////////////////////////////////////////////////////////// 841 842static JNINativeMethod gCanvasMethods[] = { 843 {"finalizer", "(I)V", (void*) SkCanvasGlue::finalizer}, 844 {"initRaster","(I)I", (void*) SkCanvasGlue::initRaster}, 845 {"initGL","()I", (void*) SkCanvasGlue::initGL}, 846 {"isOpaque","()Z", (void*) SkCanvasGlue::isOpaque}, 847 {"getWidth","()I", (void*) SkCanvasGlue::getWidth}, 848 {"getHeight","()I", (void*) SkCanvasGlue::getHeight}, 849 {"native_setBitmap","(II)V", (void*) SkCanvasGlue::setBitmap}, 850 {"nativeSetViewport", "(III)V", (void*) SkCanvasGlue::setViewport}, 851 {"save","()I", (void*) SkCanvasGlue::saveAll}, 852 {"save","(I)I", (void*) SkCanvasGlue::save}, 853 {"native_saveLayer","(ILandroid/graphics/RectF;II)I", 854 (void*) SkCanvasGlue::saveLayer}, 855 {"native_saveLayer","(IFFFFII)I", (void*) SkCanvasGlue::saveLayer4F}, 856 {"native_saveLayerAlpha","(ILandroid/graphics/RectF;II)I", 857 (void*) SkCanvasGlue::saveLayerAlpha}, 858 {"native_saveLayerAlpha","(IFFFFII)I", 859 (void*) SkCanvasGlue::saveLayerAlpha4F}, 860 {"restore","()V", (void*) SkCanvasGlue::restore}, 861 {"getSaveCount","()I", (void*) SkCanvasGlue::getSaveCount}, 862 {"restoreToCount","(I)V", (void*) SkCanvasGlue::restoreToCount}, 863 {"translate","(FF)V", (void*) SkCanvasGlue::translate}, 864 {"scale","(FF)V", (void*) SkCanvasGlue::scale__FF}, 865 {"rotate","(F)V", (void*) SkCanvasGlue::rotate__F}, 866 {"skew","(FF)V", (void*) SkCanvasGlue::skew__FF}, 867 {"native_concat","(II)V", (void*) SkCanvasGlue::concat}, 868 {"native_setMatrix","(II)V", (void*) SkCanvasGlue::setMatrix}, 869 {"clipRect","(FFFF)Z", (void*) SkCanvasGlue::clipRect_FFFF}, 870 {"clipRect","(IIII)Z", (void*) SkCanvasGlue::clipRect_IIII}, 871 {"clipRect","(Landroid/graphics/RectF;)Z", 872 (void*) SkCanvasGlue::clipRect_RectF}, 873 {"clipRect","(Landroid/graphics/Rect;)Z", 874 (void*) SkCanvasGlue::clipRect_Rect}, 875 {"native_clipRect","(IFFFFI)Z", (void*) SkCanvasGlue::clipRect}, 876 {"native_clipPath","(III)Z", (void*) SkCanvasGlue::clipPath}, 877 {"native_clipRegion","(III)Z", (void*) SkCanvasGlue::clipRegion}, 878 {"nativeSetDrawFilter", "(II)V", (void*) SkCanvasGlue::setDrawFilter}, 879 {"native_getClipBounds","(ILandroid/graphics/Rect;)Z", 880 (void*) SkCanvasGlue::getClipBounds}, 881 {"native_getCTM", "(II)V", (void*)SkCanvasGlue::getCTM}, 882 {"native_quickReject","(ILandroid/graphics/RectF;I)Z", 883 (void*) SkCanvasGlue::quickReject__RectFI}, 884 {"native_quickReject","(III)Z", (void*) SkCanvasGlue::quickReject__PathI}, 885 {"native_quickReject","(IFFFFI)Z", (void*)SkCanvasGlue::quickReject__FFFFI}, 886 {"native_drawRGB","(IIII)V", (void*) SkCanvasGlue::drawRGB}, 887 {"native_drawARGB","(IIIII)V", (void*) SkCanvasGlue::drawARGB}, 888 {"native_drawColor","(II)V", (void*) SkCanvasGlue::drawColor__I}, 889 {"native_drawColor","(III)V", (void*) SkCanvasGlue::drawColor__II}, 890 {"native_drawPaint","(II)V", (void*) SkCanvasGlue::drawPaint}, 891 {"drawPoint", "(FFLandroid/graphics/Paint;)V", 892 (void*) SkCanvasGlue::drawPoint}, 893 {"drawPoints", "([FIILandroid/graphics/Paint;)V", 894 (void*) SkCanvasGlue::drawPoints}, 895 {"drawLines", "([FIILandroid/graphics/Paint;)V", 896 (void*) SkCanvasGlue::drawLines}, 897 {"native_drawLine","(IFFFFI)V", (void*) SkCanvasGlue::drawLine__FFFFPaint}, 898 {"native_drawRect","(ILandroid/graphics/RectF;I)V", 899 (void*) SkCanvasGlue::drawRect__RectFPaint}, 900 {"native_drawRect","(IFFFFI)V", (void*) SkCanvasGlue::drawRect__FFFFPaint}, 901 {"native_drawOval","(ILandroid/graphics/RectF;I)V", 902 (void*) SkCanvasGlue::drawOval}, 903 {"native_drawCircle","(IFFFI)V", (void*) SkCanvasGlue::drawCircle}, 904 {"native_drawArc","(ILandroid/graphics/RectF;FFZI)V", 905 (void*) SkCanvasGlue::drawArc}, 906 {"native_drawRoundRect","(ILandroid/graphics/RectF;FFI)V", 907 (void*) SkCanvasGlue::drawRoundRect}, 908 {"native_drawPath","(III)V", (void*) SkCanvasGlue::drawPath}, 909 {"native_drawBitmap","(IIFFIZF)V", 910 (void*) SkCanvasGlue::drawBitmap__BitmapFFPaint}, 911 {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;I)V", 912 (void*) SkCanvasGlue::drawBitmapRF}, 913 {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;I)V", 914 (void*) SkCanvasGlue::drawBitmapRR}, 915 {"native_drawBitmap", "(I[IIIFFIIZI)V", 916 (void*)SkCanvasGlue::drawBitmapArray}, 917 918 {"nativeDrawBitmapMatrix", "(IIII)V", 919 (void*)SkCanvasGlue::drawBitmapMatrix}, 920 {"nativeDrawBitmapMesh", "(IIII[FI[III)V", 921 (void*)SkCanvasGlue::drawBitmapMesh}, 922 {"nativeDrawVertices", "(III[FI[FI[II[SIII)V", 923 (void*)SkCanvasGlue::drawVertices}, 924 {"native_drawText","(I[CIIFFI)V", 925 (void*) SkCanvasGlue::drawText___CIIFFPaint}, 926 {"native_drawText","(ILjava/lang/String;IIFFI)V", 927 (void*) SkCanvasGlue::drawText__StringIIFFPaint}, 928 {"drawText","(Ljava/lang/String;FFLandroid/graphics/Paint;)V", 929 (void*) SkCanvasGlue::drawString}, 930 {"native_drawPosText","(I[CII[FI)V", 931 (void*) SkCanvasGlue::drawPosText___CII_FPaint}, 932 {"native_drawPosText","(ILjava/lang/String;[FI)V", 933 (void*) SkCanvasGlue::drawPosText__String_FPaint}, 934 {"native_drawTextOnPath","(I[CIIIFFI)V", 935 (void*) SkCanvasGlue::drawTextOnPath___CIIPathFFPaint}, 936 {"native_drawTextOnPath","(ILjava/lang/String;IFFI)V", 937 (void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint}, 938 {"native_drawPicture", "(II)V", (void*) SkCanvasGlue::drawPicture}, 939 940 {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches} 941}; 942 943#include <android_runtime/AndroidRuntime.h> 944 945#define REG(env, name, array) \ 946 result = android::AndroidRuntime::registerNativeMethods(env, name, array, \ 947 SK_ARRAY_COUNT(array)); \ 948 if (result < 0) return result 949 950int register_android_graphics_Canvas(JNIEnv* env) { 951 int result; 952 953 REG(env, "android/graphics/Canvas", gCanvasMethods); 954 955 return result; 956} 957 958} 959