Canvas.cpp revision 889a3fa6ab9710104af60db5f73d69f253ddf254
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"
23caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed#include "SkGraphics.h"
24caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed#include "SkImageRef_GlobalPool.h"
2547c0d4eaa926d979c5ea366934750526c20af8ffMike Reed#include "SkPorterDuff.h"
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkShader.h"
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkTemplates.h"
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt#include "TextLayout.h"
30fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio#include "TextLayoutCache.h"
31f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt
32f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt#include "unicode/ubidi.h"
330c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt#include "unicode/ushape.h"
340c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
350c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt#include <utils/Log.h>
36f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define TIME_DRAWx
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic uint32_t get_thread_msec() {
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(HAVE_POSIX_CLOCKS)
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct timespec tm;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm);
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return tm.tv_sec * 1000LL + tm.tv_nsec / 1000000;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct timeval tv;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gettimeofday(&tv, NULL);
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return tv.tv_sec * 1000LL + tv.tv_usec / 1000;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass SkCanvasGlue {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void finalizer(JNIEnv* env, jobject clazz, SkCanvas* canvas) {
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->unref();
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static SkCanvas* initRaster(JNIEnv* env, jobject, SkBitmap* bitmap) {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bitmap ? new SkCanvas(*bitmap) : new SkCanvas;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
67caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed    static void freeCaches(JNIEnv* env, jobject) {
68caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed        // these are called in no particular order
69caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed        SkImageRef_GlobalPool::SetRAMUsed(0);
70889a3fa6ab9710104af60db5f73d69f253ddf254Derek Sollenberger        SkGraphics::PurgeFontCache();
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean isOpaque(JNIEnv* env, jobject jcanvas) {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jcanvas);
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->getDevice()->accessBitmap(false).isOpaque();
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int getWidth(JNIEnv* env, jobject jcanvas) {
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jcanvas);
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->getDevice()->accessBitmap(false).width();
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int getHeight(JNIEnv* env, jobject jcanvas) {
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jcanvas);
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->getDevice()->accessBitmap(false).height();
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
910965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy    static void setBitmap(JNIEnv* env, jobject, SkCanvas* canvas, SkBitmap* bitmap) {
920965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy        if (bitmap) {
930965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy            canvas->setBitmapDevice(*bitmap);
940965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy        } else {
950965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy            canvas->setDevice(NULL);
960965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy        }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int saveAll(JNIEnv* env, jobject jcanvas) {
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jcanvas);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return GraphicsJNI::getNativeCanvas(env, jcanvas)->save();
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int save(JNIEnv* env, jobject jcanvas, SkCanvas::SaveFlags flags) {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jcanvas);
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return GraphicsJNI::getNativeCanvas(env, jcanvas)->save(flags);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int saveLayer(JNIEnv* env, jobject, SkCanvas* canvas, jobject bounds,
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         SkPaint* paint, int flags) {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect* bounds_ = NULL;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect  storage;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bounds != NULL) {
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            GraphicsJNI::jrectf_to_rect(env, bounds, &storage);
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bounds_ = &storage;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->saveLayer(bounds_, paint, (SkCanvas::SaveFlags)flags);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int saveLayer4F(JNIEnv* env, jobject, SkCanvas* canvas,
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           jfloat l, jfloat t, jfloat r, jfloat b,
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           SkPaint* paint, int flags) {
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect bounds;
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bounds.set(SkFloatToScalar(l), SkFloatToScalar(t), SkFloatToScalar(r),
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   SkFloatToScalar(b));
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->saveLayer(&bounds, paint, (SkCanvas::SaveFlags)flags);
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int saveLayerAlpha(JNIEnv* env, jobject, SkCanvas* canvas,
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              jobject bounds, int alpha, int flags) {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect* bounds_ = NULL;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect  storage;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bounds != NULL) {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            GraphicsJNI::jrectf_to_rect(env, bounds, &storage);
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bounds_ = &storage;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->saveLayerAlpha(bounds_, alpha,
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      (SkCanvas::SaveFlags)flags);
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int saveLayerAlpha4F(JNIEnv* env, jobject, SkCanvas* canvas,
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                jfloat l, jfloat t, jfloat r, jfloat b,
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                int alpha, int flags) {
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect  bounds;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bounds.set(SkFloatToScalar(l), SkFloatToScalar(t), SkFloatToScalar(r),
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   SkFloatToScalar(b));
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->saveLayerAlpha(&bounds, alpha,
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      (SkCanvas::SaveFlags)flags);
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void restore(JNIEnv* env, jobject jcanvas) {
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jcanvas);
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (canvas->getSaveCount() <= 1) {  // cannot restore anymore
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doThrowISE(env, "Underflow in restore");
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->restore();
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int getSaveCount(JNIEnv* env, jobject jcanvas) {
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jcanvas);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return GraphicsJNI::getNativeCanvas(env, jcanvas)->getSaveCount();
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void restoreToCount(JNIEnv* env, jobject jcanvas, int restoreCount) {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jcanvas);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (restoreCount < 1) {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doThrowIAE(env, "Underflow in restoreToCount");
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->restoreToCount(restoreCount);
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void translate(JNIEnv* env, jobject jcanvas, jfloat dx, jfloat dy) {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jcanvas);
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar dx_ = SkFloatToScalar(dx);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar dy_ = SkFloatToScalar(dy);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->translate(dx_, dy_);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void scale__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jcanvas);
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar sx_ = SkFloatToScalar(sx);
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar sy_ = SkFloatToScalar(sy);
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->scale(sx_, sy_);
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void rotate__F(JNIEnv* env, jobject jcanvas, jfloat degrees) {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jcanvas);
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar degrees_ = SkFloatToScalar(degrees);
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->rotate(degrees_);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void skew__FF(JNIEnv* env, jobject jcanvas, jfloat sx, jfloat sy) {
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jcanvas);
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar sx_ = SkFloatToScalar(sx);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar sy_ = SkFloatToScalar(sy);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void)GraphicsJNI::getNativeCanvas(env, jcanvas)->skew(sx_, sy_);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void concat(JNIEnv* env, jobject, SkCanvas* canvas,
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       const SkMatrix* matrix) {
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->concat(*matrix);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setMatrix(JNIEnv* env, jobject, SkCanvas* canvas,
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          const SkMatrix* matrix) {
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (NULL == matrix) {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas->resetMatrix();
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas->setMatrix(*matrix);
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean clipRect_FFFF(JNIEnv* env, jobject jcanvas, jfloat left,
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  jfloat top, jfloat right, jfloat bottom) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jcanvas);
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect  r;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.set(SkFloatToScalar(left), SkFloatToScalar(top),
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project              SkFloatToScalar(right), SkFloatToScalar(bottom));
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c->clipRect(r);
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean clipRect_IIII(JNIEnv* env, jobject jcanvas, jint left,
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  jint top, jint right, jint bottom) {
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jcanvas);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect  r;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.set(SkIntToScalar(left), SkIntToScalar(top),
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project              SkIntToScalar(right), SkIntToScalar(bottom));
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return GraphicsJNI::getNativeCanvas(env, jcanvas)->clipRect(r);
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean clipRect_RectF(JNIEnv* env, jobject jcanvas, jobject rectf) {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jcanvas);
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, rectf);
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect tmp;
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c->clipRect(*GraphicsJNI::jrectf_to_rect(env, rectf, &tmp));
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean clipRect_Rect(JNIEnv* env, jobject jcanvas, jobject rect) {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jcanvas);
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, rect);
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkCanvas* c = GraphicsJNI::getNativeCanvas(env, jcanvas);
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect tmp;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c->clipRect(*GraphicsJNI::jrect_to_rect(env, rect, &tmp));
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean clipRect(JNIEnv* env, jobject, SkCanvas* canvas,
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             float left, float top, float right, float bottom,
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             int op) {
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect rect;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rect.set(SkFloatToScalar(left), SkFloatToScalar(top),
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 SkFloatToScalar(right), SkFloatToScalar(bottom));
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->clipRect(rect, (SkRegion::Op)op);
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean clipPath(JNIEnv* env, jobject, SkCanvas* canvas,
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             SkPath* path, int op) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->clipPath(*path, (SkRegion::Op)op);
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean clipRegion(JNIEnv* env, jobject, SkCanvas* canvas,
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               SkRegion* deviceRgn, int op) {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->clipRegion(*deviceRgn, (SkRegion::Op)op);
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setDrawFilter(JNIEnv* env, jobject, SkCanvas* canvas,
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              SkDrawFilter* filter) {
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->setDrawFilter(filter);
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean quickReject__RectFI(JNIEnv* env, jobject, SkCanvas* canvas,
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        jobject rect, int edgetype) {
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect rect_;
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::jrectf_to_rect(env, rect, &rect_);
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->quickReject(rect_, (SkCanvas::EdgeType)edgetype);
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean quickReject__PathI(JNIEnv* env, jobject, SkCanvas* canvas,
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       SkPath* path, int edgetype) {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->quickReject(*path, (SkCanvas::EdgeType)edgetype);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean quickReject__FFFFI(JNIEnv* env, jobject, SkCanvas* canvas,
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       jfloat left, jfloat top, jfloat right,
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       jfloat bottom, int edgetype) {
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect r;
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.set(SkFloatToScalar(left), SkFloatToScalar(top),
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project              SkFloatToScalar(right), SkFloatToScalar(bottom));
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return canvas->quickReject(r, (SkCanvas::EdgeType)edgetype);
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawRGB(JNIEnv* env, jobject, SkCanvas* canvas,
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        jint r, jint g, jint b) {
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawARGB(0xFF, r, g, b);
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawARGB(JNIEnv* env, jobject, SkCanvas* canvas,
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         jint a, jint r, jint g, jint b) {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawARGB(a, r, g, b);
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawColor__I(JNIEnv* env, jobject, SkCanvas* canvas,
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             jint color) {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawColor(color);
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawColor__II(JNIEnv* env, jobject, SkCanvas* canvas,
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              jint color, SkPorterDuff::Mode mode) {
31447c0d4eaa926d979c5ea366934750526c20af8ffMike Reed        canvas->drawColor(color, SkPorterDuff::ToXfermodeMode(mode));
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawPaint(JNIEnv* env, jobject, SkCanvas* canvas,
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          SkPaint* paint) {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawPaint(*paint);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void doPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         jint offset, jint count, jobject jpaint,
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         SkCanvas::PointMode mode) {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jcanvas);
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jptsArray);
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jpaint);
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoJavaFloatArray autoPts(env, jptsArray);
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float* floats = autoPts.ptr();
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const int length = autoPts.length();
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((offset | count) < 0 || offset + count > length) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doThrowAIOOBE(env);
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // now convert the floats into SkPoints
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        count >>= 1;    // now it is the number of points
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkAutoSTMalloc<32, SkPoint> storage(count);
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPoint* pts = storage.get();
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const float* src = floats + offset;
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pts[i].set(SkFloatToScalar(src[0]), SkFloatToScalar(src[1]));
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            src += 2;
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawPoints(mode, count, pts, paint);
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawPoints(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           jint offset, jint count, jobject jpaint) {
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        doPoints(env, jcanvas, jptsArray, offset, count, jpaint,
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 SkCanvas::kPoints_PointMode);
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawLines(JNIEnv* env, jobject jcanvas, jfloatArray jptsArray,
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           jint offset, jint count, jobject jpaint) {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        doPoints(env, jcanvas, jptsArray, offset, count, jpaint,
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 SkCanvas::kLines_PointMode);
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawPoint(JNIEnv* env, jobject jcanvas, float x, float y,
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          jobject jpaint) {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jcanvas);
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, jpaint);
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const SkPaint& paint = *GraphicsJNI::getNativePaint(env, jpaint);
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawPoint(SkFloatToScalar(x), SkFloatToScalar(y), paint);
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawLine__FFFFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    jfloat startX, jfloat startY, jfloat stopX,
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    jfloat stopY, SkPaint* paint) {
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawLine(SkFloatToScalar(startX), SkFloatToScalar(startY),
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         SkFloatToScalar(stopX), SkFloatToScalar(stopY),
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         *paint);
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawRect__RectFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                     jobject rect, SkPaint* paint) {
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect rect_;
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::jrectf_to_rect(env, rect, &rect_);
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawRect(rect_, *paint);
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawRect__FFFFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    jfloat left, jfloat top, jfloat right,
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    jfloat bottom, SkPaint* paint) {
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar left_ = SkFloatToScalar(left);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar top_ = SkFloatToScalar(top);
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar right_ = SkFloatToScalar(right);
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar bottom_ = SkFloatToScalar(bottom);
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawRectCoords(left_, top_, right_, bottom_, *paint);
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawOval(JNIEnv* env, jobject, SkCanvas* canvas, jobject joval,
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         SkPaint* paint) {
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect oval;
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::jrectf_to_rect(env, joval, &oval);
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawOval(oval, *paint);
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawCircle(JNIEnv* env, jobject, SkCanvas* canvas, jfloat cx,
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           jfloat cy, jfloat radius, SkPaint* paint) {
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawCircle(SkFloatToScalar(cx), SkFloatToScalar(cy),
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           SkFloatToScalar(radius), *paint);
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawArc(JNIEnv* env, jobject, SkCanvas* canvas, jobject joval,
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        jfloat startAngle, jfloat sweepAngle,
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        jboolean useCenter, SkPaint* paint) {
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect oval;
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::jrectf_to_rect(env, joval, &oval);
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawArc(oval, SkFloatToScalar(startAngle),
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        SkFloatToScalar(sweepAngle), useCenter, *paint);
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawRoundRect(JNIEnv* env, jobject, SkCanvas* canvas,
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              jobject jrect, jfloat rx, jfloat ry,
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              SkPaint* paint) {
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect rect;
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::jrectf_to_rect(env, jrect, &rect);
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawRoundRect(rect, SkFloatToScalar(rx), SkFloatToScalar(ry),
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              *paint);
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawPath(JNIEnv* env, jobject, SkCanvas* canvas, SkPath* path,
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         SkPaint* paint) {
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawPath(*path, *paint);
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawPicture(JNIEnv* env, jobject, SkCanvas* canvas,
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SkPicture* picture) {
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(canvas);
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(picture);
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef TIME_DRAW
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkMSec now = get_thread_msec(); //SkTime::GetMSecs();
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawPicture(*picture);
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef TIME_DRAW
4451afd5bab4e0eaba8b5bc2ab5c7b556cd602cf2e7Steve Block        ALOGD("---- picture playback %d ms\n", get_thread_msec() - now);
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawBitmap__BitmapFFPaint(JNIEnv* env, jobject jcanvas,
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                          SkCanvas* canvas, SkBitmap* bitmap,
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                          jfloat left, jfloat top,
45211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                                          SkPaint* paint, jint canvasDensity,
4530d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                                          jint screenDensity, jint bitmapDensity) {
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar left_ = SkFloatToScalar(left);
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar top_ = SkFloatToScalar(top);
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        if (canvasDensity == bitmapDensity || canvasDensity == 0
45811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                || bitmapDensity == 0) {
4590d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn            if (screenDensity != 0 && screenDensity != bitmapDensity) {
4600d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                SkPaint filteredPaint;
4610d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                if (paint) {
4620d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                    filteredPaint = *paint;
4630d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                }
4640d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                filteredPaint.setFilterBitmap(true);
4650d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
4660d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn            } else {
4670d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                canvas->drawBitmap(*bitmap, left_, top_, paint);
4680d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn            }
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas->save();
47111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            SkScalar scale = SkFloatToScalar(canvasDensity / (float)bitmapDensity);
47211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            canvas->translate(left_, top_);
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas->scale(scale, scale);
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkPaint filteredPaint;
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (paint) {
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filteredPaint = *paint;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            filteredPaint.setFilterBitmap(true);
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
48111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas->restore();
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap,
4880d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                        jobject srcIRect, const SkRect& dst, SkPaint* paint,
4890d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                        jint screenDensity, jint bitmapDensity) {
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkIRect    src, *srcPtr = NULL;
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (NULL != srcIRect) {
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            GraphicsJNI::jrect_to_irect(env, srcIRect, &src);
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            srcPtr = &src;
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4960d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn
4970d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn        if (screenDensity != 0 && screenDensity != bitmapDensity) {
4980d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn            SkPaint filteredPaint;
4990d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn            if (paint) {
5000d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                filteredPaint = *paint;
5010d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn            }
5020d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn            filteredPaint.setFilterBitmap(true);
5030d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn            canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
5040d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn        } else {
5050d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn            canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
5060d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn        }
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas,
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             SkBitmap* bitmap, jobject srcIRect,
5110d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                             jobject dstRectF, SkPaint* paint,
5120d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                             jint screenDensity, jint bitmapDensity) {
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect      dst;
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst);
5150d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
5160d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                screenDensity, bitmapDensity);
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawBitmapRR(JNIEnv* env, jobject, SkCanvas* canvas,
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             SkBitmap* bitmap, jobject srcIRect,
5210d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                             jobject dstRect, SkPaint* paint,
5220d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                             jint screenDensity, jint bitmapDensity) {
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect      dst;
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
5250d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
5260d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                screenDensity, bitmapDensity);
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawBitmapArray(JNIEnv* env, jobject, SkCanvas* canvas,
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                jintArray jcolors, int offset, int stride,
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                jfloat x, jfloat y, int width, int height,
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                jboolean hasAlpha, SkPaint* paint)
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkBitmap    bitmap;
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bitmap.setConfig(hasAlpha ? SkBitmap::kARGB_8888_Config :
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         SkBitmap::kRGB_565_Config, width, height);
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!bitmap.allocPixels()) {
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!GraphicsJNI::SetPixels(env, jcolors, offset, stride,
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    0, 0, width, height, bitmap)) {
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawBitmap(bitmap, SkFloatToScalar(x), SkFloatToScalar(y),
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           paint);
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawBitmapMatrix(JNIEnv* env, jobject, SkCanvas* canvas,
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const SkBitmap* bitmap, const SkMatrix* matrix,
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const SkPaint* paint) {
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawBitmapMatrix(*bitmap, *matrix, paint);
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawBitmapMesh(JNIEnv* env, jobject, SkCanvas* canvas,
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          const SkBitmap* bitmap, int meshWidth, int meshHeight,
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          jfloatArray jverts, int vertIndex, jintArray jcolors,
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          int colorIndex, const SkPaint* paint) {
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const int ptCount = (meshWidth + 1) * (meshHeight + 1);
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const int indexCount = meshWidth * meshHeight * 6;
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoJavaFloatArray  vertA(env, jverts, vertIndex + (ptCount << 1));
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoJavaIntArray    colorA(env, jcolors, colorIndex + ptCount);
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*  Our temp storage holds 2 or 3 arrays.
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            texture points [ptCount * sizeof(SkPoint)]
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            optionally vertex points [ptCount * sizeof(SkPoint)] if we need a
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                copy to convert from float to fixed
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            indices [ptCount * sizeof(uint16_t)]
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        */
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ssize_t storageSize = ptCount * sizeof(SkPoint); // texs[]
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef SK_SCALAR_IS_FIXED
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        storageSize += ptCount * sizeof(SkPoint);  // storage for verts
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        storageSize += indexCount * sizeof(uint16_t);  // indices[]
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkAutoMalloc storage(storageSize);
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPoint* texs = (SkPoint*)storage.get();
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPoint* verts;
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint16_t* indices;
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef SK_SCALAR_IS_FLOAT
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        verts = (SkPoint*)(vertA.ptr() + vertIndex);
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        indices = (uint16_t*)(texs + ptCount);
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        verts = texs + ptCount;
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        indices = (uint16_t*)(verts + ptCount);
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // convert floats to fixed
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const float* src = vertA.ptr() + vertIndex;
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < ptCount; i++) {
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                src += 2;
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // cons up texture coordinates and indices
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const SkScalar w = SkIntToScalar(bitmap->width());
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const SkScalar h = SkIntToScalar(bitmap->height());
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const SkScalar dx = w / meshWidth;
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const SkScalar dy = h / meshHeight;
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkPoint* texsPtr = texs;
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkScalar y = 0;
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i <= meshHeight; i++) {
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (i == meshHeight) {
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    y = h;  // to ensure numerically we hit h exactly
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SkScalar x = 0;
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int j = 0; j < meshWidth; j++) {
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    texsPtr->set(x, y);
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    texsPtr += 1;
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    x += dx;
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                texsPtr->set(w, y);
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                texsPtr += 1;
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                y += dy;
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkASSERT(texsPtr - texs == ptCount);
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // cons up indices
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uint16_t* indexPtr = indices;
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int index = 0;
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < meshHeight; i++) {
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int j = 0; j < meshWidth; j++) {
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // lower-left triangle
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    *indexPtr++ = index;
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    *indexPtr++ = index + meshWidth + 1;
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    *indexPtr++ = index + meshWidth + 2;
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // upper-right triangle
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    *indexPtr++ = index;
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    *indexPtr++ = index + meshWidth + 2;
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    *indexPtr++ = index + 1;
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // bump to the next cell
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    index += 1;
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // bump to the next row
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                index += 1;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkASSERT(indexPtr - indices == indexCount);
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkASSERT((char*)indexPtr - (char*)storage.get() == storageSize);
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // double-check that we have legal indices
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef SK_DEBUG
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < indexCount; i++) {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SkASSERT((unsigned)indices[i] < (unsigned)ptCount);
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // cons-up a shader for the bitmap
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPaint tmpPaint;
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (paint) {
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            tmpPaint = *paint;
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkShader* shader = SkShader::CreateBitmapShader(*bitmap,
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
6666062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger        SkSafeUnref(tmpPaint.setShader(shader));
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, verts,
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             texs, (const SkColor*)colorA.ptr(), NULL, indices,
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             indexCount, tmpPaint);
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawVertices(JNIEnv* env, jobject, SkCanvas* canvas,
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             SkCanvas::VertexMode mode, int vertexCount,
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             jfloatArray jverts, int vertIndex,
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             jfloatArray jtexs, int texIndex,
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             jintArray jcolors, int colorIndex,
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             jshortArray jindices, int indexIndex,
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             int indexCount, const SkPaint* paint) {
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoJavaFloatArray  vertA(env, jverts, vertIndex + vertexCount);
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoJavaFloatArray  texA(env, jtexs, texIndex + vertexCount);
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoJavaIntArray    colorA(env, jcolors, colorIndex + vertexCount);
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoJavaShortArray  indexA(env, jindices, indexIndex + indexCount);
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const int ptCount = vertexCount >> 1;
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPoint* verts;
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPoint* texs = NULL;
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef SK_SCALAR_IS_FLOAT
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        verts = (SkPoint*)(vertA.ptr() + vertIndex);
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (jtexs != NULL) {
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            texs = (SkPoint*)(texA.ptr() + texIndex);
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = ptCount;    // for verts
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (jtexs != NULL) {
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            count += ptCount;   // += for texs
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkAutoMalloc storage(count * sizeof(SkPoint));
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        verts = (SkPoint*)storage.get();
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const float* src = vertA.ptr() + vertIndex;
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < ptCount; i++) {
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            src += 2;
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (jtexs != NULL) {
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            texs = verts + ptCount;
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            src = texA.ptr() + texIndex;
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < ptCount; i++) {
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                texs[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                src += 2;
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const SkColor* colors = NULL;
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const uint16_t* indices = NULL;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (jcolors != NULL) {
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            colors = (const SkColor*)(colorA.ptr() + colorIndex);
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (jindices != NULL) {
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            indices = (const uint16_t*)(indexA.ptr() + indexIndex);
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawVertices(mode, ptCount, verts, texs, colors, NULL,
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             indices, indexCount, *paint);
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
729f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
7300c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
731f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    static void drawText___CIIFFIPaint(JNIEnv* env, jobject, SkCanvas* canvas,
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      jcharArray text, int index, int count,
733f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt                                      jfloat x, jfloat y, int flags, SkPaint* paint) {
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jchar* textArray = env->GetCharArrayElements(text, NULL);
735b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#if RTL_USE_HARFBUZZ
736b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio        drawTextWithGlyphs(canvas, textArray + index, 0, count, x, y, flags, paint);
737b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#else
738f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        TextLayout::drawText(paint, textArray + index, count, flags, x, y, canvas);
739b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#endif
740f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7420c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
743f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    static void drawText__StringIIFFIPaint(JNIEnv* env, jobject,
7440c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                                          SkCanvas* canvas, jstring text,
745f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt                                          int start, int end,
746f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt                                          jfloat x, jfloat y, int flags, SkPaint* paint) {
747f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        const jchar* textArray = env->GetStringChars(text, NULL);
748b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#if RTL_USE_HARFBUZZ
749b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio        drawTextWithGlyphs(canvas, textArray, start, end, x, y, flags, paint);
750b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#else
751f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        TextLayout::drawText(paint, textArray + start, end - start, flags, x, y, canvas);
752b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#endif
753f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        env->ReleaseStringChars(text, textArray);
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7550c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
756689e515ed2b8064c15e54d8ab69d87de54c5e0d6Fabrice Di Meglio    static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
757689e515ed2b8064c15e54d8ab69d87de54c5e0d6Fabrice Di Meglio            int start, int end,
758689e515ed2b8064c15e54d8ab69d87de54c5e0d6Fabrice Di Meglio            jfloat x, jfloat y, int flags, SkPaint* paint) {
759689e515ed2b8064c15e54d8ab69d87de54c5e0d6Fabrice Di Meglio
760689e515ed2b8064c15e54d8ab69d87de54c5e0d6Fabrice Di Meglio        jint count = end - start;
76179df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio        drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, flags, paint);
762689e515ed2b8064c15e54d8ab69d87de54c5e0d6Fabrice Di Meglio    }
763689e515ed2b8064c15e54d8ab69d87de54c5e0d6Fabrice Di Meglio
764b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio    static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
765b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio            int start, int count, int contextCount,
766b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio            jfloat x, jfloat y, int flags, SkPaint* paint) {
767b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio
768af033caf26ef4eca99c4024e59def7e42c3fa4cdFabrice Di Meglio        sp<TextLayoutCacheValue> value;
769af033caf26ef4eca99c4024e59def7e42c3fa4cdFabrice Di Meglio#if USE_TEXT_LAYOUT_CACHE
7705c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio        value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count,
7715c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio                contextCount, flags);
772b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio        if (value == NULL) {
773c6aacce37191e1cc79cfeba13b39899f59c68c3bSteve Block            ALOGE("Cannot get TextLayoutCache value");
774b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio            return ;
775b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio        }
776af033caf26ef4eca99c4024e59def7e42c3fa4cdFabrice Di Meglio#else
777af033caf26ef4eca99c4024e59def7e42c3fa4cdFabrice Di Meglio        value = new TextLayoutCacheValue();
7785c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio        value->computeValues(paint, textArray, start, count, contextCount, flags);
779af033caf26ef4eca99c4024e59def7e42c3fa4cdFabrice Di Meglio#endif
7805c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio        doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint);
781b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio    }
782b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio
783fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    static void doDrawGlyphs(SkCanvas* canvas, const jchar* glyphArray, int index, int count,
784fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio            jfloat x, jfloat y, int flags, SkPaint* paint) {
7859f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        // TODO: need to suppress this code after the GL renderer is modified for not
7869f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        // copying the paint
7879f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio
7889f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        // Save old text encoding
7899f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        SkPaint::TextEncoding oldEncoding = paint->getTextEncoding();
7909f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        // Define Glyph encoding
7919f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
7929f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio
793fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio        canvas->drawText(glyphArray + index * 2, count * 2, x, y, *paint);
7949f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio
7959f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        // Get back old encoding
7969f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        paint->setTextEncoding(oldEncoding);
797fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    }
798fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio
7990c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    static void drawTextRun___CIIIIFFIPaint(
800f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        JNIEnv* env, jobject, SkCanvas* canvas, jcharArray text, int index,
8010c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        int count, int contextIndex, int contextCount,
8024beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt        jfloat x, jfloat y, int dirFlags, SkPaint* paint) {
803f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
804f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        jchar* chars = env->GetCharArrayElements(text, NULL);
805b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#if RTL_USE_HARFBUZZ
806b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio        drawTextWithGlyphs(canvas, chars + contextIndex, index - contextIndex,
807b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio                count, contextCount, x, y, dirFlags, paint);
808b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#else
809f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        TextLayout::drawTextRun(paint, chars + contextIndex, index - contextIndex,
810b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio                count, contextCount, dirFlags, x, y, canvas);
811b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#endif
812f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        env->ReleaseCharArrayElements(text, chars, JNI_ABORT);
813f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    }
814f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
8150c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    static void drawTextRun__StringIIIIFFIPaint(
8160c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        JNIEnv* env, jobject obj, SkCanvas* canvas, jstring text, jint start,
8170c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        jint end, jint contextStart, jint contextEnd,
8184beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt        jfloat x, jfloat y, jint dirFlags, SkPaint* paint) {
819f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
8200c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        jint count = end - start;
8210c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        jint contextCount = contextEnd - contextStart;
822f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        const jchar* chars = env->GetStringChars(text, NULL);
823b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#if RTL_USE_HARFBUZZ
824b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio        drawTextWithGlyphs(canvas, chars + contextStart, start - contextStart,
825b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio                count, contextCount, x, y, dirFlags, paint);
826b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#else
827f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        TextLayout::drawTextRun(paint, chars + contextStart, start - contextStart,
828b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio                count, contextCount, dirFlags, x, y, canvas);
829b39d89735b8d88669c779b6a8549a179fd0f6f44Fabrice Di Meglio#endif
830f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        env->ReleaseStringChars(text, chars);
831f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    }
832f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawPosText___CII_FPaint(JNIEnv* env, jobject, SkCanvas* canvas,
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         jcharArray text, int index, int count,
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         jfloatArray pos, SkPaint* paint) {
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jchar* textArray = text ? env->GetCharArrayElements(text, NULL) : NULL;
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jsize textCount = text ? env->GetArrayLength(text) : NULL;
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int indx;
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (indx = 0; indx < posCount; indx++) {
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]);
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]);
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
846ad8b8f57a457ff615112b7fa4987f39e75fc5ff6Mike Reed        canvas->drawPosText(textArray + index, count << 1, posPtr, *paint);
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (text) {
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->ReleaseCharArrayElements(text, textArray, 0);
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pos) {
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->ReleaseFloatArrayElements(pos, posArray, 0);
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete[] posPtr;
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8550c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawPosText__String_FPaint(JNIEnv* env, jobject,
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                           SkCanvas* canvas, jstring text,
8584beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt                                           jfloatArray pos,
8594beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt                                           SkPaint* paint) {
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const void* text_ = text ? env->GetStringChars(text, NULL) : NULL;
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int byteLength = text ? env->GetStringLength(text) : 0;
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int indx = 0; indx < posCount; indx++) {
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            posPtr[indx].fX = SkFloatToScalar(posArray[indx << 1]);
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            posPtr[indx].fY = SkFloatToScalar(posArray[(indx << 1) + 1]);
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas->drawPosText(text_, byteLength << 1, posPtr, *paint);
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (text) {
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->ReleaseStringChars(text, (const jchar*) text_);
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pos) {
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->ReleaseFloatArrayElements(pos, posArray, 0);
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete[] posPtr;
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8790c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawTextOnPath___CIIPathFFPaint(JNIEnv* env, jobject,
8814beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt            SkCanvas* canvas, jcharArray text, int index, int count,
8824beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt            SkPath* path, jfloat hOffset, jfloat vOffset, jint bidiFlags, SkPaint* paint) {
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jchar* textArray = env->GetCharArrayElements(text, NULL);
8858f67eae87ae84fb0c17e7fd4c9b6a62e73b0de29Romain Guy        TextLayout::drawTextOnPath(paint, textArray + index, count, bidiFlags, hOffset, vOffset,
886f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt                                   path, canvas);
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseCharArrayElements(text, textArray, 0);
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8890c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawTextOnPath__StringPathFFPaint(JNIEnv* env, jobject,
8914beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt            SkCanvas* canvas, jstring text, SkPath* path,
8924beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt            jfloat hOffset, jfloat vOffset, jint bidiFlags, SkPaint* paint) {
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* text_ = env->GetStringChars(text, NULL);
8944beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt        int count = env->GetStringLength(text);
895f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        TextLayout::drawTextOnPath(paint, text_, count, bidiFlags, hOffset, vOffset,
896f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt                                   path, canvas);
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringChars(text, text_);
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8990c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static bool getClipBounds(JNIEnv* env, jobject, SkCanvas* canvas,
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              jobject bounds) {
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect   r;
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkIRect ir;
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool     result = canvas->getClipBounds(&r, SkCanvas::kBW_EdgeType);
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.round(&ir);
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void)GraphicsJNI::irect_to_jrect(ir, env, bounds);
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void getCTM(JNIEnv* env, jobject, SkCanvas* canvas,
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       SkMatrix* matrix) {
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *matrix = canvas->getTotalMatrix();
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gCanvasMethods[] = {
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"finalizer", "(I)V", (void*) SkCanvasGlue::finalizer},
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"initRaster","(I)I", (void*) SkCanvasGlue::initRaster},
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"isOpaque","()Z", (void*) SkCanvasGlue::isOpaque},
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getWidth","()I", (void*) SkCanvasGlue::getWidth},
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getHeight","()I", (void*) SkCanvasGlue::getHeight},
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_setBitmap","(II)V", (void*) SkCanvasGlue::setBitmap},
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"save","()I", (void*) SkCanvasGlue::saveAll},
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"save","(I)I", (void*) SkCanvasGlue::save},
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_saveLayer","(ILandroid/graphics/RectF;II)I",
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::saveLayer},
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_saveLayer","(IFFFFII)I", (void*) SkCanvasGlue::saveLayer4F},
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_saveLayerAlpha","(ILandroid/graphics/RectF;II)I",
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::saveLayerAlpha},
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_saveLayerAlpha","(IFFFFII)I",
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::saveLayerAlpha4F},
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"restore","()V", (void*) SkCanvasGlue::restore},
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getSaveCount","()I", (void*) SkCanvasGlue::getSaveCount},
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"restoreToCount","(I)V", (void*) SkCanvasGlue::restoreToCount},
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"translate","(FF)V", (void*) SkCanvasGlue::translate},
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"scale","(FF)V", (void*) SkCanvasGlue::scale__FF},
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"rotate","(F)V", (void*) SkCanvasGlue::rotate__F},
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"skew","(FF)V", (void*) SkCanvasGlue::skew__FF},
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_concat","(II)V", (void*) SkCanvasGlue::concat},
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_setMatrix","(II)V", (void*) SkCanvasGlue::setMatrix},
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"clipRect","(FFFF)Z", (void*) SkCanvasGlue::clipRect_FFFF},
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"clipRect","(IIII)Z", (void*) SkCanvasGlue::clipRect_IIII},
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"clipRect","(Landroid/graphics/RectF;)Z",
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::clipRect_RectF},
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"clipRect","(Landroid/graphics/Rect;)Z",
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::clipRect_Rect},
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_clipRect","(IFFFFI)Z", (void*) SkCanvasGlue::clipRect},
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_clipPath","(III)Z", (void*) SkCanvasGlue::clipPath},
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_clipRegion","(III)Z", (void*) SkCanvasGlue::clipRegion},
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"nativeSetDrawFilter", "(II)V", (void*) SkCanvasGlue::setDrawFilter},
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_getClipBounds","(ILandroid/graphics/Rect;)Z",
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::getClipBounds},
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_getCTM", "(II)V", (void*)SkCanvasGlue::getCTM},
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_quickReject","(ILandroid/graphics/RectF;I)Z",
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::quickReject__RectFI},
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_quickReject","(III)Z", (void*) SkCanvasGlue::quickReject__PathI},
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_quickReject","(IFFFFI)Z", (void*)SkCanvasGlue::quickReject__FFFFI},
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawRGB","(IIII)V", (void*) SkCanvasGlue::drawRGB},
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawARGB","(IIIII)V", (void*) SkCanvasGlue::drawARGB},
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawColor","(II)V", (void*) SkCanvasGlue::drawColor__I},
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawColor","(III)V", (void*) SkCanvasGlue::drawColor__II},
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawPaint","(II)V", (void*) SkCanvasGlue::drawPaint},
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"drawPoint", "(FFLandroid/graphics/Paint;)V",
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    (void*) SkCanvasGlue::drawPoint},
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"drawPoints", "([FIILandroid/graphics/Paint;)V",
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawPoints},
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"drawLines", "([FIILandroid/graphics/Paint;)V",
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawLines},
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawLine","(IFFFFI)V", (void*) SkCanvasGlue::drawLine__FFFFPaint},
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawRect","(ILandroid/graphics/RectF;I)V",
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawRect__RectFPaint},
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawRect","(IFFFFI)V", (void*) SkCanvasGlue::drawRect__FFFFPaint},
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawOval","(ILandroid/graphics/RectF;I)V",
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawOval},
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawCircle","(IFFFI)V", (void*) SkCanvasGlue::drawCircle},
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawArc","(ILandroid/graphics/RectF;FFZI)V",
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawArc},
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawRoundRect","(ILandroid/graphics/RectF;FFI)V",
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawRoundRect},
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawPath","(III)V", (void*) SkCanvasGlue::drawPath},
9820d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn    {"native_drawBitmap","(IIFFIIII)V",
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawBitmap__BitmapFFPaint},
9840d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn    {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;III)V",
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawBitmapRF},
9860d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn    {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;III)V",
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawBitmapRR},
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawBitmap", "(I[IIIFFIIZI)V",
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    (void*)SkCanvasGlue::drawBitmapArray},
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"nativeDrawBitmapMatrix", "(IIII)V",
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*)SkCanvasGlue::drawBitmapMatrix},
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"nativeDrawBitmapMesh", "(IIII[FI[III)V",
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*)SkCanvasGlue::drawBitmapMesh},
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"nativeDrawVertices", "(III[FI[FI[II[SIII)V",
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*)SkCanvasGlue::drawVertices},
996f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    {"native_drawText","(I[CIIFFII)V",
997f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        (void*) SkCanvasGlue::drawText___CIIFFIPaint},
998f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    {"native_drawText","(ILjava/lang/String;IIFFII)V",
999f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        (void*) SkCanvasGlue::drawText__StringIIFFIPaint},
10000c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    {"native_drawTextRun","(I[CIIIIFFII)V",
10010c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        (void*) SkCanvasGlue::drawTextRun___CIIIIFFIPaint},
10020c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    {"native_drawTextRun","(ILjava/lang/String;IIIIFFII)V",
10030c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        (void*) SkCanvasGlue::drawTextRun__StringIIIIFFIPaint},
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawPosText","(I[CII[FI)V",
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawPosText___CII_FPaint},
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawPosText","(ILjava/lang/String;[FI)V",
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawPosText__String_FPaint},
10084beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt    {"native_drawTextOnPath","(I[CIIIFFII)V",
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawTextOnPath___CIIPathFFPaint},
10104beb8ff7175ebd14b96942724a658f407d0b9951Doug Felt    {"native_drawTextOnPath","(ILjava/lang/String;IFFII)V",
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint},
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_drawPicture", "(II)V", (void*) SkCanvasGlue::drawPicture},
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1014caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed    {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches}
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1017c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed///////////////////////////////////////////////////////////////////////////////
1018c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h>
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define REG(env, name, array) \
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result = android::AndroidRuntime::registerNativeMethods(env, name, array, \
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    SK_ARRAY_COUNT(array));  \
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (result < 0) return result
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_graphics_Canvas(JNIEnv* env) {
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result;
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    REG(env, "android/graphics/Canvas", gCanvasMethods);
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return result;
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1035