Paint.cpp revision c41d941f1b999502a2121597edeb3c23d26a2269
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* libs/android_runtime/android/graphics/Paint.cpp
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2006, The Android Open Source Project
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License.
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License.
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "Paint"
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "GraphicsJNI.h"
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ScopedUtfChars.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkBlurDrawLooper.h"
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkColorFilter.h"
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkMaskFilter.h"
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkRasterizer.h"
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkShader.h"
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkTypeface.h"
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkXfermode.h"
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "unicode/uloc.h"
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "unicode/ushape.h"
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/Blur.h"
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38092eb8d43baffd7723bc7847c180a32fb5269481You Kim#include <minikin/GraphemeBreak.h>
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MinikinSkia.h"
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MinikinUtils.h"
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Paint.h"
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "TypefaceImpl.h"
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// temporary for debugging
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <Caches.h>
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct JMetricsID {
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    top;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    ascent;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    descent;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    bottom;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    leading;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass   gFontMetrics_class;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JMetricsID gFontMetrics_fieldID;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass   gFontMetricsInt_class;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JMetricsID gFontMetricsInt_fieldID;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
64092eb8d43baffd7723bc7847c180a32fb5269481You Kimstatic void defaultSettingsForAndroid(Paint* paint) {
65092eb8d43baffd7723bc7847c180a32fb5269481You Kim    // GlyphID encoding is required because we are using Harfbuzz shaping
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
68092eb8d43baffd7723bc7847c180a32fb5269481You Kim
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass PaintGlue {
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    enum MoveOpt {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete obj;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    static jlong init(JNIEnv* env, jobject clazz) {
8169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        Paint* obj = new Paint();
8269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        defaultSettingsForAndroid(obj);
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return reinterpret_cast<jlong>(obj);
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jlong initWithPaint(JNIEnv* env, jobject clazz, jlong paintHandle) {
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = new Paint(*paint);
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return reinterpret_cast<jlong>(obj);
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    static void reset(JNIEnv* env, jobject clazz, jlong objHandle) {
93092eb8d43baffd7723bc7847c180a32fb5269481You Kim        Paint* obj = reinterpret_cast<Paint*>(objHandle);
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        obj->reset();
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        defaultSettingsForAndroid(obj);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void assign(JNIEnv* env, jobject clazz, jlong dstPaintHandle, jlong srcPaintHandle) {
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* dst = reinterpret_cast<Paint*>(dstPaintHandle);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Paint* src = reinterpret_cast<Paint*>(srcPaintHandle);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *dst = *src;
102092eb8d43baffd7723bc7847c180a32fb5269481You Kim    }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
104092eb8d43baffd7723bc7847c180a32fb5269481You Kim    // Equivalent to the Java Paint's FILTER_BITMAP_FLAG.
10569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    static const uint32_t sFilterBitmapFlag = 0x02;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getFlags(JNIEnv* env, jobject paint) {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* nativePaint = GraphicsJNI::getNativePaint(env, paint);
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t result = nativePaint->getFlags();
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        result &= ~sFilterBitmapFlag; // Filtering no longer stored in this bit. Mask away.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (nativePaint->getFilterLevel() != Paint::kNone_FilterLevel) {
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result |= sFilterBitmapFlag;
114f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        }
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return static_cast<jint>(result);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setFlags(JNIEnv* env, jobject paint, jint flags) {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* nativePaint = GraphicsJNI::getNativePaint(env, paint);
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Instead of modifying 0x02, change the filter level.
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativePaint->setFilterLevel(flags & sFilterBitmapFlag
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ? Paint::kLow_FilterLevel
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                : Paint::kNone_FilterLevel);
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Don't pass through filter flag, which is no longer stored in paint's flags.
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flags &= ~sFilterBitmapFlag;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Use the existing value for 0x02.
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const uint32_t existing0x02Flag = nativePaint->getFlags() & sFilterBitmapFlag;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flags |= existing0x02Flag;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativePaint->setFlags(flags);
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getHinting(JNIEnv* env, jobject paint) {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return GraphicsJNI::getNativePaint(env, paint)->getHinting()
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                == Paint::kNo_Hinting ? 0 : 1;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setHinting(JNIEnv* env, jobject paint, jint mode) {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setHinting(
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mode == 0 ? Paint::kNo_Hinting : Paint::kNormal_Hinting);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setAntiAlias(JNIEnv* env, jobject paint, jboolean aa) {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setAntiAlias(aa);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setLinearText(JNIEnv* env, jobject paint, jboolean linearText) {
15169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        NPE_CHECK_RETURN_VOID(env, paint);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setLinearText(linearText);
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setSubpixelText(JNIEnv* env, jobject paint, jboolean subpixelText) {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setSubpixelText(subpixelText);
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setUnderlineText(JNIEnv* env, jobject paint, jboolean underlineText) {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setUnderlineText(underlineText);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setStrikeThruText(JNIEnv* env, jobject paint, jboolean strikeThruText) {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setStrikeThruText(strikeThruText);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setFakeBoldText(JNIEnv* env, jobject paint, jboolean fakeBoldText) {
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setFakeBoldText(fakeBoldText);
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setFilterLevel(
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filterBitmap ? Paint::kLow_FilterLevel : Paint::kNone_FilterLevel);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setDither(dither);
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getStyle(JNIEnv* env, jobject clazz,jlong objHandle) {
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return static_cast<jint>(obj->getStyle());
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setStyle(JNIEnv* env, jobject clazz, jlong objHandle, jint styleHandle) {
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::Style style = static_cast<Paint::Style>(styleHandle);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        obj->setStyle(style);
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getColor(JNIEnv* env, jobject paint) {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int color;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        color = GraphicsJNI::getNativePaint(env, paint)->getColor();
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return static_cast<jint>(color);
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getAlpha(JNIEnv* env, jobject paint) {
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int alpha;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        alpha = GraphicsJNI::getNativePaint(env, paint)->getAlpha();
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return static_cast<jint>(alpha);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setColor(JNIEnv* env, jobject paint, jint color) {
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setColor(color);
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setAlpha(JNIEnv* env, jobject paint, jint a) {
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setAlpha(a);
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat getStrokeWidth(JNIEnv* env, jobject paint) {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeWidth());
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setStrokeWidth(JNIEnv* env, jobject paint, jfloat width) {
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setStrokeWidth(width);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat getStrokeMiter(JNIEnv* env, jobject paint) {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeMiter());
234f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat    }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setStrokeMiter(JNIEnv* env, jobject paint, jfloat miter) {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setStrokeMiter(miter);
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return static_cast<jint>(obj->getStrokeCap());
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle, jint capHandle) {
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::Cap cap = static_cast<Paint::Cap>(capHandle);
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        obj->setStrokeCap(cap);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle) {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return static_cast<jint>(obj->getStrokeJoin());
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle, jint joinHandle) {
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::Join join = (Paint::Join) joinHandle;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        obj->setStrokeJoin(join);
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean getFillPath(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jlong dstHandle) {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPath* src = reinterpret_cast<SkPath*>(srcHandle);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jlong setShader(JNIEnv* env, jobject clazz, jlong objHandle, jlong shaderHandle) {
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return reinterpret_cast<jlong>(obj->setShader(shader));
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jlong setColorFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong filterHandle) {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint *>(objHandle);
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkColorFilter* filter  = reinterpret_cast<SkColorFilter *>(filterHandle);
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return reinterpret_cast<jlong>(obj->setColorFilter(filter));
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
282f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat    static jlong setXfermode(JNIEnv* env, jobject clazz, jlong objHandle, jlong xfermodeHandle) {
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkXfermode* xfermode = reinterpret_cast<SkXfermode*>(xfermodeHandle);
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return reinterpret_cast<jlong>(obj->setXfermode(xfermode));
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jlong setPathEffect(JNIEnv* env, jobject clazz, jlong objHandle, jlong effectHandle) {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPathEffect* effect  = reinterpret_cast<SkPathEffect*>(effectHandle);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return reinterpret_cast<jlong>(obj->setPathEffect(effect));
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jlong setMaskFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong maskfilterHandle) {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkMaskFilter* maskfilter  = reinterpret_cast<SkMaskFilter*>(maskfilterHandle);
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return reinterpret_cast<jlong>(obj->setMaskFilter(maskfilter));
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jlong setTypeface(JNIEnv* env, jobject clazz, jlong objHandle, jlong typefaceHandle) {
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // TODO: in Paint refactoring, set typeface on android Paint, not Paint
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jlong setRasterizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong rasterizerHandle) {
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkAutoTUnref<SkRasterizer> rasterizer(GraphicsJNI::refNativeRasterizer(rasterizerHandle));
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return reinterpret_cast<jlong>(obj->setRasterizer(rasterizer));
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getTextAlign(JNIEnv* env, jobject clazz, jlong objHandle) {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return static_cast<jint>(obj->getTextAlign());
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setTextAlign(JNIEnv* env, jobject clazz, jlong objHandle, jint alignHandle) {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = reinterpret_cast<Paint*>(objHandle);
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::Align align = static_cast<Paint::Align>(alignHandle);
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        obj->setTextAlign(align);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // generate bcp47 identifier for the supplied locale
32369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    static void toLanguageTag(char* output, size_t outSize,
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* locale) {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (output == NULL || outSize <= 0) {
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (locale == NULL) {
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            output[0] = '\0';
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
33169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        }
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char canonicalChars[ULOC_FULLNAME_CAPACITY];
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        UErrorCode uErr = U_ZERO_ERROR;
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uloc_canonicalize(locale, canonicalChars, ULOC_FULLNAME_CAPACITY,
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &uErr);
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (U_SUCCESS(uErr)) {
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char likelyChars[ULOC_FULLNAME_CAPACITY];
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uErr = U_ZERO_ERROR;
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uloc_addLikelySubtags(canonicalChars, likelyChars,
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ULOC_FULLNAME_CAPACITY, &uErr);
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (U_SUCCESS(uErr)) {
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uErr = U_ZERO_ERROR;
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr);
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (U_SUCCESS(uErr)) {
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars,
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            u_errorName(uErr));
34971bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy                }
35071bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy            } else {
35171bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy                ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s",
35271bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy                        canonicalChars, u_errorName(uErr));
35371bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy            }
35471bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        } else {
35571bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy            ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale,
35671bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy                    u_errorName(uErr));
35771bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        }
35871bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        // unable to build a proper language identifier
35971bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        output[0] = '\0';
36071bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy    }
36171bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setTextLocale(JNIEnv* env, jobject clazz, jlong objHandle, jstring locale) {
36371bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        Paint* obj = reinterpret_cast<Paint*>(objHandle);
36471bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        ScopedUtfChars localeChars(env, locale);
36571bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        char langTag[ULOC_FULLNAME_CAPACITY];
36671bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str());
36771bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy
36871bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
36971bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        paintOpts.setLanguage(langTag);
37071bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy        obj->setPaintOptionsAndroid(paintOpts);
37171bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy    }
37271bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy
37371bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy    static jboolean isElegantTextHeight(JNIEnv* env, jobject paint) {
37469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        NPE_CHECK_RETURN_ZERO(env, paint);
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = GraphicsJNI::getNativePaint(env, paint);
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant;
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setElegantTextHeight(JNIEnv* env, jobject paint, jboolean aa) {
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* obj = GraphicsJNI::getNativePaint(env, paint);
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPaintOptionsAndroid::FontVariant variant =
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            aa ? SkPaintOptionsAndroid::kElegant_Variant :
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkPaintOptionsAndroid::kDefault_Variant;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        paintOpts.setFontVariant(variant);
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        obj->setPaintOptionsAndroid(paintOpts);
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat getTextSize(JNIEnv* env, jobject paint) {
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSize());
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setTextSize(JNIEnv* env, jobject paint, jfloat textSize) {
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setTextSize(textSize);
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
40069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat getTextScaleX(JNIEnv* env, jobject paint) {
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextScaleX());
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setTextScaleX(JNIEnv* env, jobject paint, jfloat scaleX) {
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setTextScaleX(scaleX);
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
41069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat getTextSkewX(JNIEnv* env, jobject paint) {
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSkewX());
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setTextSkewX(JNIEnv* env, jobject paint, jfloat skewX) {
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_VOID(env, paint);
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(skewX);
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat getLetterSpacing(JNIEnv* env, jobject clazz, jlong paintHandle) {
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return paint->getLetterSpacing();
42469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setLetterSpacing(JNIEnv* env, jobject clazz, jlong paintHandle, jfloat letterSpacing) {
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        paint->setLetterSpacing(letterSpacing);
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static SkScalar getMetricsInternal(JNIEnv* env, jobject jpaint, Paint::FontMetrics *metrics) {
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const int kElegantTop = 2500;
43369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        const int kElegantBottom = -1000;
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const int kElegantAscent = 1900;
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const int kElegantDescent = -500;
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const int kElegantLeading = 0;
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        typeface = TypefaceImpl_resolveDefault(typeface);
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle);
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float saveSkewX = paint->getTextSkewX();
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool savefakeBold = paint->isFakeBoldText();
44369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        MinikinFontSkia::populateSkPaint(paint, baseFont.font, baseFont.fakery);
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar spacing = paint->getFontMetrics(metrics);
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The populateSkPaint call may have changed fake bold / text skew
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // because we want to measure with those effects applied, so now
44769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        // restore the original settings.
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        paint->setTextSkewX(saveSkewX);
449092eb8d43baffd7723bc7847c180a32fb5269481You Kim        paint->setFakeBoldText(savefakeBold);
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant) {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkScalar size = paint->getTextSize();
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            metrics->fTop = -size * kElegantTop / 2048;
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            metrics->fBottom = -size * kElegantBottom / 2048;
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            metrics->fAscent = -size * kElegantAscent / 2048;
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            metrics->fDescent = -size * kElegantDescent / 2048;
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            metrics->fLeading = size * kElegantLeading / 2048;
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            spacing = metrics->fDescent - metrics->fAscent + metrics->fLeading;
45969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        }
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return spacing;
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat ascent(JNIEnv* env, jobject paint) {
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::FontMetrics metrics;
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        getMetricsInternal(env, paint, &metrics);
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return SkScalarToFloat(metrics.fAscent);
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat descent(JNIEnv* env, jobject paint) {
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::FontMetrics metrics;
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        getMetricsInternal(env, paint, &metrics);
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return SkScalarToFloat(metrics.fDescent);
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::FontMetrics metrics;
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkScalar spacing = getMetricsInternal(env, paint, &metrics);
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (metricsObj) {
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop));
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent));
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent));
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom));
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading));
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return SkScalarToFloat(spacing);
49169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    }
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getFontMetricsInt(JNIEnv* env, jobject paint, jobject metricsObj) {
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::FontMetrics metrics;
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        getMetricsInternal(env, paint, &metrics);
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int ascent = SkScalarRoundToInt(metrics.fAscent);
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int descent = SkScalarRoundToInt(metrics.fDescent);
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int leading = SkScalarRoundToInt(metrics.fLeading);
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (metricsObj) {
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class));
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloorToInt(metrics.fTop));
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent);
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent);
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeilToInt(metrics.fBottom));
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading);
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return descent - ascent + leading;
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat measureText_CIII(JNIEnv* env, jobject jpaint, jcharArray text, jint index, jint count,
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jint bidiFlags) {
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jpaint);
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, text);
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t textLength = env->GetArrayLength(text);
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((index | count) < 0 || (size_t)(index + count) > textLength) {
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doThrowAIOOBE(env);
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count == 0) {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetCharArrayElements(text, NULL);
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloat result = 0;
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
53169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        Layout layout;
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray, index, count, textLength);
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        result = layout.getAdvance();
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat measureText_StringIII(JNIEnv* env, jobject jpaint, jstring text, jint start, jint end,
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jint bidiFlags) {
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jpaint);
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, text);
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t textLength = env->GetStringLength(text);
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = end - start;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((start | count) < 0 || (size_t)end > textLength) {
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doThrowAIOOBE(env);
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count == 0) {
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetStringChars(text, NULL);
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloat width = 0;
55769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Layout layout;
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray, start, count, textLength);
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        width = layout.getAdvance();
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringChars(text, textArray);
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return width;
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat measureText_StringI(JNIEnv* env, jobject jpaint, jstring text, jint bidiFlags) {
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jpaint);
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, text);
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t textLength = env->GetStringLength(text);
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (textLength == 0) {
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetStringChars(text, NULL);
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloat width = 0;
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Layout layout;
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray, 0, textLength, textLength);
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        width = layout.getAdvance();
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringChars(text, textArray);
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return width;
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int dotextwidths(JNIEnv* env, Paint* paint, TypefaceImpl* typeface, const jchar text[], int count,
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jfloatArray widths, jint bidiFlags) {
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, text);
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count < 0 || !widths) {
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doThrowAIOOBE(env);
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count == 0) {
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t widthsLength = env->GetArrayLength(widths);
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((size_t)count > widthsLength) {
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doThrowAIOOBE(env);
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoJavaFloatArray autoWidths(env, widths, count);
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloat* widthsArray = autoWidths.ptr();
60969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Layout layout;
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count);
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        layout.getAdvances(widthsArray);
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return count;
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getTextWidths___CIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jcharArray text,
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jint index, jint count, jint bidiFlags, jfloatArray widths) {
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetCharArrayElements(text, NULL);
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        count = dotextwidths(env, paint, typeface, textArray + index, count, widths, bidiFlags);
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      JNI_ABORT);
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return count;
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getTextWidths__StringIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring text,
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jint start, jint end, jint bidiFlags, jfloatArray widths) {
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetStringChars(text, NULL);
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = dotextwidths(env, paint, typeface, textArray + start, end - start, widths, bidiFlags);
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringChars(text, textArray);
63569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        return count;
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat doTextRunAdvances(JNIEnv *env, Paint *paint, TypefaceImpl* typeface, const jchar *text,
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    jint start, jint count, jint contextCount, jboolean isRtl,
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    jfloatArray advances, jint advancesIndex) {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, paint);
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, text);
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((start | count | contextCount | advancesIndex) < 0 || contextCount < count) {
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doThrowAIOOBE(env);
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count == 0) {
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (advances) {
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t advancesLength = env->GetArrayLength(advances);
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((size_t)count > advancesLength) {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                doThrowAIOOBE(env);
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloat* advancesArray = new jfloat[count];
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloat totalAdvance = 0;
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
66269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Layout layout;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count, contextCount);
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        layout.getAdvances(advancesArray);
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        totalAdvance = layout.getAdvance();
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (advances != NULL) {
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
67069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        }
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete [] advancesArray;
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return totalAdvance;
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat getTextRunAdvances___CIIIIZ_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jlong typefaceHandle,
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jcharArray text, jint index, jint count, jint contextIndex, jint contextCount,
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jboolean isRtl, jfloatArray advances, jint advancesIndex) {
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jchar* textArray = env->GetCharArrayElements(text, NULL);
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextIndex,
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                index - contextIndex, count, contextCount, isRtl, advances, advancesIndex);
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jfloat getTextRunAdvances__StringIIIIZ_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jlong typefaceHandle,
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jstring text, jint start, jint end, jint contextStart, jint contextEnd, jboolean isRtl,
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jfloatArray advances, jint advancesIndex) {
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetStringChars(text, NULL);
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextStart,
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                start - contextStart, end - start, contextEnd - contextStart, isRtl,
69769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes                advances, advancesIndex);
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringChars(text, textArray);
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint doTextRunCursor(JNIEnv *env, Paint* paint, const jchar *text, jint start,
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jint count, jint flags, jint offset, jint opt) {
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphemeBreak::MoveOpt moveOpt = GraphemeBreak::MoveOpt(opt);
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t result = GraphemeBreak::getTextRunCursor(text, start, count, offset, moveOpt);
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return static_cast<jint>(result);
70769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    }
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text,
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jint contextStart, jint contextCount, jint dir, jint offset, jint cursorOpt) {
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jchar* textArray = env->GetCharArrayElements(text, NULL);
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, dir,
71469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes                offset, cursorOpt);
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text,
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jint contextStart, jint contextEnd, jint dir, jint offset, jint cursorOpt) {
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetStringChars(text, NULL);
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jint result = doTextRunCursor(env, paint, textArray, contextStart,
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                contextEnd - contextStart, dir, offset, cursorOpt);
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringChars(text, textArray);
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
72969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    class GetTextFunctor {
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public:
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GetTextFunctor(const Layout& layout, SkPath* path, jfloat x, jfloat y, Paint* paint,
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    uint16_t* glyphs, SkPoint* pos)
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                : layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) {
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void operator()(size_t start, size_t end) {
73769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes            for (size_t i = start; i < end; i++) {
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                glyphs[i] = layout.getGlyphId(i);
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pos[i].fX = x + layout.getX(i);
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pos[i].fY = y + layout.getY(i);
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (start == 0) {
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, path);
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, &tmpPath);
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                path->addPath(tmpPath);
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private:
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Layout& layout;
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPath* path;
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloat x;
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jfloat y;
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint;
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint16_t* glyphs;
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPoint* pos;
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPath tmpPath;
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
75969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void getTextPath(JNIEnv* env, Paint* paint, TypefaceImpl* typeface, const jchar* text,
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) {
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Layout layout;
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count);
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t nGlyphs = layout.nGlyphs();
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint16_t* glyphs = new uint16_t[nGlyphs];
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPoint* pos = new SkPoint[nGlyphs];
76769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        x += MinikinUtils::xOffsetForTextAlign(paint, layout);
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::Align align = paint->getTextAlign();
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        paint->setTextAlign(Paint::kLeft_Align);
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GetTextFunctor f(layout, path, x, y, paint, glyphs, pos);
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MinikinUtils::forFontRun(layout, paint, f);
77469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        paint->setTextAlign(align);
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete[] glyphs;
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete[] pos;
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle,
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jlong typefaceHandle, jint bidiFlags,
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) {
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetCharArrayElements(text, NULL);
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        getTextPath(env, paint, typeface, textArray + index, count, bidiFlags, x, y, path);
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
78969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle,
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jlong typefaceHandle, jint bidiFlags,
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) {
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetStringChars(text, NULL);
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        getTextPath(env, paint, typeface, textArray + start, end - start, bidiFlags, x, y, path);
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringChars(text, textArray);
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
80069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void setShadowLayer(JNIEnv* env, jobject clazz, jlong paintHandle, jfloat radius,
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               jfloat dx, jfloat dy, jint color) {
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (radius <= 0) {
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            paint->setLooper(NULL);
80669a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        }
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else {
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkScalar sigma = android::uirenderer::Blur::convertRadiusToSigma(radius);
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            paint->setLooper(SkBlurDrawLooper::Create((SkColor)color, sigma, dx, dy))->unref();
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
81369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    static jboolean hasShadowLayer(JNIEnv* env, jobject clazz, jlong paintHandle) {
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return paint->getLooper() && paint->getLooper()->asABlurShadow(NULL);
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static int breakText(JNIEnv* env, const Paint& paint, TypefaceImpl* typeface, const jchar text[],
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured,
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         Paint::TextBufferDirection textBufferDirection) {
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t measuredCount = 0;
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float measured = 0;
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Layout layout;
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, 0, count, count);
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float* advances = new float[count];
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        layout.getAdvances(advances);
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const bool forwardScan = (textBufferDirection == Paint::kForward_TextBufferDirection);
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // traverse in the given direction
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int index = forwardScan ? i : (count - i - 1);
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float width = advances[index];
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (measured + width > maxWidth) {
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // properly handle clusters when scanning backwards
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (forwardScan || width != 0.0f) {
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                measuredCount = i + 1;
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            measured += width;
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete[] advances;
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (jmeasured && env->GetArrayLength(jmeasured) > 0) {
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            AutoJavaFloatArray autoMeasured(env, jmeasured, 1);
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jfloat* array = autoMeasured.ptr();
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[0] = measured;
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return measuredCount;
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint breakTextC(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jcharArray jtext,
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jint index, jint count, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jtext);
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::TextBufferDirection tbd;
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count < 0) {
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            tbd = Paint::kBackward_TextBufferDirection;
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            count = -count;
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else {
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            tbd = Paint::kForward_TextBufferDirection;
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
86971bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy            doThrowAIOOBE(env);
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* text = env->GetCharArrayElements(jtext, NULL);
87469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        count = breakText(env, *paint, typeface, text + index, count, maxWidth,
87569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes                          bidiFlags, jmeasuredWidth, tbd);
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text),
87769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes                                      JNI_ABORT);
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return count;
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint breakTextS(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring jtext,
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NPE_CHECK_RETURN_ZERO(env, jtext);
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint::TextBufferDirection tbd = forwards ?
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        Paint::kForward_TextBufferDirection :
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        Paint::kBackward_TextBufferDirection;
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
89269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        int count = env->GetStringLength(jtext);
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* text = env->GetStringChars(jtext, NULL);
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        count = breakText(env, *paint, typeface, text, count, maxWidth, bidiFlags, jmeasuredWidth, tbd);
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringChars(jtext, text);
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return count;
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
89969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    static void doTextBounds(JNIEnv* env, const jchar* text, int count, jobject bounds,
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Paint& paint, TypefaceImpl* typeface, jint bidiFlags) {
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect  r;
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkIRect ir;
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Layout layout;
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, 0, count, count);
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MinikinRect rect;
90769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        layout.getBounds(&rect);
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.fLeft = rect.mLeft;
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.fTop = rect.mTop;
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.fRight = rect.mRight;
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.fBottom = rect.mBottom;
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.roundOut(&ir);
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::irect_to_jrect(ir, env, bounds);
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle,
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                jstring text, jint start, jint end, jint bidiFlags, jobject bounds) {
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Paint* paint = reinterpret_cast<Paint*>(paintHandle);;
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetStringChars(text, NULL);
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        doTextBounds(env, textArray + start, end - start, bounds, *paint, typeface, bidiFlags);
92269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        env->ReleaseStringChars(text, textArray);
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle,
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) {
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* textArray = env->GetCharArrayElements(text, NULL);
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        doTextBounds(env, textArray + index, count, bounds, *paint, typeface, bidiFlags);
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      JNI_ABORT);
9333762c311729fe9f3af085c14c5c1fb471d994c03Steve Block    }
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod methods[] = {
938    {"finalizer", "(J)V", (void*) PaintGlue::finalizer},
939    {"native_init","()J", (void*) PaintGlue::init},
940    {"native_initWithPaint","(J)J", (void*) PaintGlue::initWithPaint},
941    {"native_reset","(J)V", (void*) PaintGlue::reset},
942    {"native_set","(JJ)V", (void*) PaintGlue::assign},
943    {"getFlags","()I", (void*) PaintGlue::getFlags},
944    {"setFlags","(I)V", (void*) PaintGlue::setFlags},
945    {"getHinting","()I", (void*) PaintGlue::getHinting},
946    {"setHinting","(I)V", (void*) PaintGlue::setHinting},
947    {"setAntiAlias","(Z)V", (void*) PaintGlue::setAntiAlias},
948    {"setSubpixelText","(Z)V", (void*) PaintGlue::setSubpixelText},
949    {"setLinearText","(Z)V", (void*) PaintGlue::setLinearText},
950    {"setUnderlineText","(Z)V", (void*) PaintGlue::setUnderlineText},
951    {"setStrikeThruText","(Z)V", (void*) PaintGlue::setStrikeThruText},
952    {"setFakeBoldText","(Z)V", (void*) PaintGlue::setFakeBoldText},
953    {"setFilterBitmap","(Z)V", (void*) PaintGlue::setFilterBitmap},
954    {"setDither","(Z)V", (void*) PaintGlue::setDither},
955    {"native_getStyle","(J)I", (void*) PaintGlue::getStyle},
956    {"native_setStyle","(JI)V", (void*) PaintGlue::setStyle},
957    {"getColor","()I", (void*) PaintGlue::getColor},
958    {"setColor","(I)V", (void*) PaintGlue::setColor},
959    {"getAlpha","()I", (void*) PaintGlue::getAlpha},
960    {"setAlpha","(I)V", (void*) PaintGlue::setAlpha},
961    {"getStrokeWidth","()F", (void*) PaintGlue::getStrokeWidth},
962    {"setStrokeWidth","(F)V", (void*) PaintGlue::setStrokeWidth},
963    {"getStrokeMiter","()F", (void*) PaintGlue::getStrokeMiter},
964    {"setStrokeMiter","(F)V", (void*) PaintGlue::setStrokeMiter},
965    {"native_getStrokeCap","(J)I", (void*) PaintGlue::getStrokeCap},
966    {"native_setStrokeCap","(JI)V", (void*) PaintGlue::setStrokeCap},
967    {"native_getStrokeJoin","(J)I", (void*) PaintGlue::getStrokeJoin},
968    {"native_setStrokeJoin","(JI)V", (void*) PaintGlue::setStrokeJoin},
969    {"native_getFillPath","(JJJ)Z", (void*) PaintGlue::getFillPath},
970    {"native_setShader","(JJ)J", (void*) PaintGlue::setShader},
971    {"native_setColorFilter","(JJ)J", (void*) PaintGlue::setColorFilter},
972    {"native_setXfermode","(JJ)J", (void*) PaintGlue::setXfermode},
973    {"native_setPathEffect","(JJ)J", (void*) PaintGlue::setPathEffect},
974    {"native_setMaskFilter","(JJ)J", (void*) PaintGlue::setMaskFilter},
975    {"native_setTypeface","(JJ)J", (void*) PaintGlue::setTypeface},
976    {"native_setRasterizer","(JJ)J", (void*) PaintGlue::setRasterizer},
977    {"native_getTextAlign","(J)I", (void*) PaintGlue::getTextAlign},
978    {"native_setTextAlign","(JI)V", (void*) PaintGlue::setTextAlign},
979    {"native_setTextLocale","(JLjava/lang/String;)V", (void*) PaintGlue::setTextLocale},
980    {"isElegantTextHeight","()Z", (void*) PaintGlue::isElegantTextHeight},
981    {"setElegantTextHeight","(Z)V", (void*) PaintGlue::setElegantTextHeight},
982    {"getTextSize","()F", (void*) PaintGlue::getTextSize},
983    {"setTextSize","(F)V", (void*) PaintGlue::setTextSize},
984    {"getTextScaleX","()F", (void*) PaintGlue::getTextScaleX},
985    {"setTextScaleX","(F)V", (void*) PaintGlue::setTextScaleX},
986    {"getTextSkewX","()F", (void*) PaintGlue::getTextSkewX},
987    {"setTextSkewX","(F)V", (void*) PaintGlue::setTextSkewX},
988    {"native_getLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing},
989    {"native_setLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing},
990    {"ascent","()F", (void*) PaintGlue::ascent},
991    {"descent","()F", (void*) PaintGlue::descent},
992    {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)PaintGlue::getFontMetrics},
993    {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)PaintGlue::getFontMetricsInt},
994    {"native_measureText","([CIII)F", (void*) PaintGlue::measureText_CIII},
995    {"native_measureText","(Ljava/lang/String;I)F", (void*) PaintGlue::measureText_StringI},
996    {"native_measureText","(Ljava/lang/String;III)F", (void*) PaintGlue::measureText_StringIII},
997    {"native_breakText","(JJ[CIIFI[F)I", (void*) PaintGlue::breakTextC},
998    {"native_breakText","(JJLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS},
999    {"native_getTextWidths","(JJ[CIII[F)I", (void*) PaintGlue::getTextWidths___CIII_F},
1000    {"native_getTextWidths","(JJLjava/lang/String;III[F)I", (void*) PaintGlue::getTextWidths__StringIII_F},
1001    {"native_getTextRunAdvances","(JJ[CIIIIZ[FI)F",
1002        (void*) PaintGlue::getTextRunAdvances___CIIIIZ_FI},
1003    {"native_getTextRunAdvances","(JJLjava/lang/String;IIIIZ[FI)F",
1004        (void*) PaintGlue::getTextRunAdvances__StringIIIIZ_FI},
1005
1006    {"native_getTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C},
1007    {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I",
1008        (void*) PaintGlue::getTextRunCursor__String},
1009    {"native_getTextPath","(JJI[CIIFFJ)V", (void*) PaintGlue::getTextPath___C},
1010    {"native_getTextPath","(JJILjava/lang/String;IIFFJ)V", (void*) PaintGlue::getTextPath__String},
1011    {"nativeGetStringBounds", "(JJLjava/lang/String;IIILandroid/graphics/Rect;)V",
1012                                        (void*) PaintGlue::getStringBounds },
1013    {"nativeGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V",
1014                                    (void*) PaintGlue::getCharArrayBounds },
1015    {"native_setShadowLayer", "(JFFFI)V", (void*)PaintGlue::setShadowLayer},
1016    {"native_hasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer}
1017};
1018
1019static jfieldID req_fieldID(jfieldID id) {
1020    SkASSERT(id);
1021    return id;
1022}
1023
1024int register_android_graphics_Paint(JNIEnv* env) {
1025    gFontMetrics_class = env->FindClass("android/graphics/Paint$FontMetrics");
1026    SkASSERT(gFontMetrics_class);
1027    gFontMetrics_class = (jclass)env->NewGlobalRef(gFontMetrics_class);
1028
1029    gFontMetrics_fieldID.top = req_fieldID(env->GetFieldID(gFontMetrics_class, "top", "F"));
1030    gFontMetrics_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetrics_class, "ascent", "F"));
1031    gFontMetrics_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetrics_class, "descent", "F"));
1032    gFontMetrics_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetrics_class, "bottom", "F"));
1033    gFontMetrics_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetrics_class, "leading", "F"));
1034
1035    gFontMetricsInt_class = env->FindClass("android/graphics/Paint$FontMetricsInt");
1036    SkASSERT(gFontMetricsInt_class);
1037    gFontMetricsInt_class = (jclass)env->NewGlobalRef(gFontMetricsInt_class);
1038
1039    gFontMetricsInt_fieldID.top = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "top", "I"));
1040    gFontMetricsInt_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "ascent", "I"));
1041    gFontMetricsInt_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "descent", "I"));
1042    gFontMetricsInt_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "bottom", "I"));
1043    gFontMetricsInt_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "leading", "I"));
1044
1045    int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Paint", methods,
1046        sizeof(methods) / sizeof(methods[0]));
1047    return result;
1048}
1049
1050}
1051