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