Paint.cpp revision dbffd250003e60c0f11ac3ad2b63f91f67962610
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** 58451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes** Licensed under the Apache License, Version 2.0 (the "License"); 68451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes** you may not use this file except in compliance with the License. 78451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes** You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 98451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes** http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 118451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes** Unless required by applicable law or agreed to in writing, software 128451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes** distributed under the License is distributed on an "AS IS" BASIS, 138451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 148451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes** 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 18f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn#define LOG_TAG "Paint" 19f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn 20f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn#include <utils/Log.h> 21f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "GraphicsJNI.h" 24ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h" 25f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien#include <ScopedStringChars.h> 26a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien#include <ScopedUtfChars.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkBlurDrawLooper.h" 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkColorFilter.h" 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkMaskFilter.h" 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkRasterizer.h" 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkShader.h" 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkTypeface.h" 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkXfermode.h" 35ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett#include "unicode/uloc.h" 360c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt#include "unicode/ushape.h" 37c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger#include "utils/Blur.h" 380c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 39e368b6bcfd499543a876b4cae02f1ca563ff1cb6Raph Levien#include <minikin/GraphemeBreak.h> 40a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien#include <minikin/Measurement.h> 411a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "MinikinSkia.h" 421a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "MinikinUtils.h" 436ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod#include "Paint.h" 443d528c403c8945cc326bb656ff0c2e11373401daRaph Levien#include "TypefaceImpl.h" 451a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 46f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien#include <vector> 47536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi#include <memory> 48f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien 490c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt// temporary for debugging 505c13d89c1332fcc499379b9064b891187b75ca32Chet Haase#include <Caches.h> 510c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt#include <utils/Log.h> 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct JMetricsID { 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID top; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID ascent; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID descent; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID bottom; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID leading; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gFontMetrics_class; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JMetricsID gFontMetrics_fieldID; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gFontMetricsInt_class; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JMetricsID gFontMetricsInt_fieldID; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 696ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbodstatic void defaultSettingsForAndroid(Paint* paint) { 70c511bee87cda99a252d1a62487f47c8f05aee78cFabrice Di Meglio // GlyphID encoding is required because we are using Harfbuzz shaping 716ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod paint->setTextEncoding(Paint::kGlyphID_TextEncoding); 723d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed} 733d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed 74476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reckstruct LocaleCacheEntry { 75476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck std::string javaLocale; 76476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck std::string languageTag; 77476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck}; 78476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck 79476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reckstatic thread_local LocaleCacheEntry sSingleEntryLocaleCache; 80476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck 81dbffd250003e60c0f11ac3ad2b63f91f67962610John Recknamespace PaintGlue { 820c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt enum MoveOpt { 830c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT 840c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt }; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) { 876ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete obj; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 91dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jlong init(JNIEnv* env, jobject) { 92e3a40ea488c7cfa396d5901255719a6ddab791d4Ben Wagner static_assert(1 << 0 == SkPaint::kAntiAlias_Flag, "paint_flags_mismatch"); 93e3a40ea488c7cfa396d5901255719a6ddab791d4Ben Wagner static_assert(1 << 2 == SkPaint::kDither_Flag, "paint_flags_mismatch"); 94e3a40ea488c7cfa396d5901255719a6ddab791d4Ben Wagner static_assert(1 << 3 == SkPaint::kUnderlineText_Flag, "paint_flags_mismatch"); 95e3a40ea488c7cfa396d5901255719a6ddab791d4Ben Wagner static_assert(1 << 4 == SkPaint::kStrikeThruText_Flag, "paint_flags_mismatch"); 96e3a40ea488c7cfa396d5901255719a6ddab791d4Ben Wagner static_assert(1 << 5 == SkPaint::kFakeBoldText_Flag, "paint_flags_mismatch"); 97e3a40ea488c7cfa396d5901255719a6ddab791d4Ben Wagner static_assert(1 << 6 == SkPaint::kLinearText_Flag, "paint_flags_mismatch"); 98e3a40ea488c7cfa396d5901255719a6ddab791d4Ben Wagner static_assert(1 << 7 == SkPaint::kSubpixelText_Flag, "paint_flags_mismatch"); 99e3a40ea488c7cfa396d5901255719a6ddab791d4Ben Wagner static_assert(1 << 8 == SkPaint::kDevKernText_Flag, "paint_flags_mismatch"); 100e3a40ea488c7cfa396d5901255719a6ddab791d4Ben Wagner static_assert(1 << 10 == SkPaint::kEmbeddedBitmapText_Flag, "paint_flags_mismatch"); 1010b8606266c1afc69cbeb73acda67c85d87943318Derek Sollenberger 1026ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = new Paint(); 1033d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed defaultSettingsForAndroid(obj); 10436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(obj); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jlong initWithPaint(JNIEnv* env, jobject clazz, jlong paintHandle) { 1086ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 1096ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = new Paint(*paint); 11036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(obj); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1128451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 11336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static void reset(JNIEnv* env, jobject clazz, jlong objHandle) { 1146ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project obj->reset(); 1163d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed defaultSettingsForAndroid(obj); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1188451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 11936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static void assign(JNIEnv* env, jobject clazz, jlong dstPaintHandle, jlong srcPaintHandle) { 1206ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* dst = reinterpret_cast<Paint*>(dstPaintHandle); 1216ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* src = reinterpret_cast<Paint*>(srcPaintHandle); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *dst = *src; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1248451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 1254c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed // Equivalent to the Java Paint's FILTER_BITMAP_FLAG. 1264c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed static const uint32_t sFilterBitmapFlag = 0x02; 1274c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed 128dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jint getFlags(JNIEnv* env, jobject, jlong paintHandle) { 129dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck Paint* nativePaint = reinterpret_cast<Paint*>(paintHandle); 1304c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed uint32_t result = nativePaint->getFlags(); 1314c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed result &= ~sFilterBitmapFlag; // Filtering no longer stored in this bit. Mask away. 1322a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed if (nativePaint->getFilterQuality() != kNone_SkFilterQuality) { 1334c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed result |= sFilterBitmapFlag; 1344c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed } 13536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return static_cast<jint>(result); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1378451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 138dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setFlags(JNIEnv* env, jobject, jlong paintHandle, jint flags) { 139dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck Paint* nativePaint = reinterpret_cast<Paint*>(paintHandle); 1404c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed // Instead of modifying 0x02, change the filter level. 1412a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed nativePaint->setFilterQuality(flags & sFilterBitmapFlag 1422a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed ? kLow_SkFilterQuality 1432a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed : kNone_SkFilterQuality); 1444c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed // Don't pass through filter flag, which is no longer stored in paint's flags. 1454c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed flags &= ~sFilterBitmapFlag; 1464c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed // Use the existing value for 0x02. 1474c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed const uint32_t existing0x02Flag = nativePaint->getFlags() & sFilterBitmapFlag; 1484c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed flags |= existing0x02Flag; 1494c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed nativePaint->setFlags(flags); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1518451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 152dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jint getHinting(JNIEnv* env, jobject, jlong paintHandle) { 153dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck return reinterpret_cast<Paint*>(paintHandle)->getHinting() 1546ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod == Paint::kNo_Hinting ? 0 : 1; 155f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn } 156f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn 157dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setHinting(JNIEnv* env, jobject, jlong paintHandle, jint mode) { 158dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setHinting( 1596ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod mode == 0 ? Paint::kNo_Hinting : Paint::kNormal_Hinting); 160f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn } 161f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn 162dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setAntiAlias(JNIEnv* env, jobject, jlong paintHandle, jboolean aa) { 163dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setAntiAlias(aa); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1658451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 166dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setLinearText(JNIEnv* env, jobject, jlong paintHandle, jboolean linearText) { 167dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setLinearText(linearText); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1698451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 170dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setSubpixelText(JNIEnv* env, jobject, jlong paintHandle, jboolean subpixelText) { 171dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setSubpixelText(subpixelText); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1738451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 174dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setUnderlineText(JNIEnv* env, jobject, jlong paintHandle, jboolean underlineText) { 175dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setUnderlineText(underlineText); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1778451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 178dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setStrikeThruText(JNIEnv* env, jobject, jlong paintHandle, jboolean strikeThruText) { 179dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setStrikeThruText(strikeThruText); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1818451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 182dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setFakeBoldText(JNIEnv* env, jobject, jlong paintHandle, jboolean fakeBoldText) { 183dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setFakeBoldText(fakeBoldText); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1858451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 186dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setFilterBitmap(JNIEnv* env, jobject, jlong paintHandle, jboolean filterBitmap) { 187dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setFilterQuality( 1882a1ce8a4e5258b6599cb8e86864eb816d24d69b4Mike Reed filterBitmap ? kLow_SkFilterQuality : kNone_SkFilterQuality); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1908451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 191dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setDither(JNIEnv* env, jobject, jlong paintHandle, jboolean dither) { 192dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setDither(dither); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1948451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 19536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jint getStyle(JNIEnv* env, jobject clazz,jlong objHandle) { 1966ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 19736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return static_cast<jint>(obj->getStyle()); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1998451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 20036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static void setStyle(JNIEnv* env, jobject clazz, jlong objHandle, jint styleHandle) { 2016ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 2026ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::Style style = static_cast<Paint::Style>(styleHandle); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project obj->setStyle(style); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2058451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 206dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jint getColor(JNIEnv* env, jobject, jlong paintHandle) { 20736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat int color; 208dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck color = reinterpret_cast<Paint*>(paintHandle)->getColor(); 20936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return static_cast<jint>(color); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2118451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 212dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jint getAlpha(JNIEnv* env, jobject, jlong paintHandle) { 21336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat int alpha; 214dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck alpha = reinterpret_cast<Paint*>(paintHandle)->getAlpha(); 21536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return static_cast<jint>(alpha); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2178451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 218dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setColor(JNIEnv* env, jobject, jlong paintHandle, jint color) { 219dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setColor(color); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2218451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 222dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setAlpha(JNIEnv* env, jobject, jlong paintHandle, jint a) { 223dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setAlpha(a); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2258451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 226dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jfloat getStrokeWidth(JNIEnv* env, jobject, jlong paintHandle) { 227dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck return SkScalarToFloat(reinterpret_cast<Paint*>(paintHandle)->getStrokeWidth()); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2298451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 230dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setStrokeWidth(JNIEnv* env, jobject, jlong paintHandle, jfloat width) { 231dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setStrokeWidth(width); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2338451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 234dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jfloat getStrokeMiter(JNIEnv* env, jobject, jlong paintHandle) { 235dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck return SkScalarToFloat(reinterpret_cast<Paint*>(paintHandle)->getStrokeMiter()); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2378451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 238dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setStrokeMiter(JNIEnv* env, jobject, jlong paintHandle, jfloat miter) { 239dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setStrokeMiter(miter); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2418451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 24236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jint getStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle) { 2436ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 24436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return static_cast<jint>(obj->getStrokeCap()); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2468451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 24736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static void setStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle, jint capHandle) { 2486ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 2496ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::Cap cap = static_cast<Paint::Cap>(capHandle); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project obj->setStrokeCap(cap); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2528451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 25336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jint getStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle) { 2546ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 25536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return static_cast<jint>(obj->getStrokeJoin()); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2578451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 25836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static void setStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle, jint joinHandle) { 2596ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 2606ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::Join join = (Paint::Join) joinHandle; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project obj->setStrokeJoin(join); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2638451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 26436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jboolean getFillPath(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jlong dstHandle) { 2656ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 26636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat SkPath* src = reinterpret_cast<SkPath*>(srcHandle); 26736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat SkPath* dst = reinterpret_cast<SkPath*>(dstHandle); 26836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2708451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 27136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jlong setShader(JNIEnv* env, jobject clazz, jlong objHandle, jlong shaderHandle) { 2726ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 27336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); 27436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(obj->setShader(shader)); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2768451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 27736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jlong setColorFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong filterHandle) { 2786ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint *>(objHandle); 27936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(filterHandle); 28036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(obj->setColorFilter(filter)); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2828451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 28336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jlong setXfermode(JNIEnv* env, jobject clazz, jlong objHandle, jlong xfermodeHandle) { 2846ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 28536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat SkXfermode* xfermode = reinterpret_cast<SkXfermode*>(xfermodeHandle); 28636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(obj->setXfermode(xfermode)); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2888451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 28936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jlong setPathEffect(JNIEnv* env, jobject clazz, jlong objHandle, jlong effectHandle) { 2906ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 29136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat SkPathEffect* effect = reinterpret_cast<SkPathEffect*>(effectHandle); 29236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(obj->setPathEffect(effect)); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2948451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 29536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jlong setMaskFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong maskfilterHandle) { 2966ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 29736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat SkMaskFilter* maskfilter = reinterpret_cast<SkMaskFilter*>(maskfilterHandle); 29836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(obj->setMaskFilter(maskfilter)); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3008451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 30136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jlong setTypeface(JNIEnv* env, jobject clazz, jlong objHandle, jlong typefaceHandle) { 3026ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod // TODO: in Paint refactoring, set typeface on android Paint, not Paint 303a033630e805c407080221e20b236b6054f324670Raph Levien return NULL; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3058451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 30636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jlong setRasterizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong rasterizerHandle) { 3076ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 3084c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed SkAutoTUnref<SkRasterizer> rasterizer(GraphicsJNI::refNativeRasterizer(rasterizerHandle)); 30936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(obj->setRasterizer(rasterizer)); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3118451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 31236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jint getTextAlign(JNIEnv* env, jobject clazz, jlong objHandle) { 3136ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 31436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return static_cast<jint>(obj->getTextAlign()); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3168451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 31736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static void setTextAlign(JNIEnv* env, jobject clazz, jlong objHandle, jint alignHandle) { 3186ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 3196ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::Align align = static_cast<Paint::Align>(alignHandle); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project obj->setTextAlign(align); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3228451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 323ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett // generate bcp47 identifier for the supplied locale 324ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett static void toLanguageTag(char* output, size_t outSize, 325ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett const char* locale) { 326ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett if (output == NULL || outSize <= 0) { 327ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett return; 328ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett } 329ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett if (locale == NULL) { 330ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett output[0] = '\0'; 331ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett return; 332ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett } 333ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett char canonicalChars[ULOC_FULLNAME_CAPACITY]; 334ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett UErrorCode uErr = U_ZERO_ERROR; 335ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett uloc_canonicalize(locale, canonicalChars, ULOC_FULLNAME_CAPACITY, 336ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett &uErr); 337ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett if (U_SUCCESS(uErr)) { 338ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett char likelyChars[ULOC_FULLNAME_CAPACITY]; 339ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett uErr = U_ZERO_ERROR; 340ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett uloc_addLikelySubtags(canonicalChars, likelyChars, 341ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett ULOC_FULLNAME_CAPACITY, &uErr); 342ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett if (U_SUCCESS(uErr)) { 343ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett uErr = U_ZERO_ERROR; 344ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr); 345ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett if (U_SUCCESS(uErr)) { 346ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett return; 347ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett } else { 348ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars, 349ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett u_errorName(uErr)); 350ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett } 351ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett } else { 352ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s", 353ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett canonicalChars, u_errorName(uErr)); 354ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett } 355ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett } else { 356ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale, 357ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett u_errorName(uErr)); 358ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett } 359ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett // unable to build a proper language identifier 360ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett output[0] = '\0'; 361ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett } 362ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett 36336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static void setTextLocale(JNIEnv* env, jobject clazz, jlong objHandle, jstring locale) { 3646ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 365ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett ScopedUtfChars localeChars(env, locale); 366476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck if (sSingleEntryLocaleCache.javaLocale != localeChars.c_str()) { 367476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck sSingleEntryLocaleCache.javaLocale = localeChars.c_str(); 368476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck char langTag[ULOC_FULLNAME_CAPACITY]; 369476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str()); 370476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck sSingleEntryLocaleCache.languageTag = langTag; 371476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck } 372d7a80774f0a2175f9ee81a7741f9a171c78e0b8bDerek Sollenberger 373476f7158222e49ec24a5fc08f0bbb33fb8ca10bfJohn Reck obj->setTextLocale(sSingleEntryLocaleCache.languageTag); 374517825f1a9f14f92908bd7859b91b927c2eec6d9Fabrice Di Meglio } 375517825f1a9f14f92908bd7859b91b927c2eec6d9Fabrice Di Meglio 376dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jboolean isElegantTextHeight(JNIEnv* env, jobject, jlong paintHandle) { 377dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck Paint* obj = reinterpret_cast<Paint*>(paintHandle); 3786f03023ece076d33d8b171d5398c8ed70abf3f54Derek Sollenberger return obj->getFontVariant() == VARIANT_ELEGANT; 37953c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien } 38053c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien 381dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setElegantTextHeight(JNIEnv* env, jobject, jlong paintHandle, jboolean aa) { 382dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck Paint* obj = reinterpret_cast<Paint*>(paintHandle); 3836f03023ece076d33d8b171d5398c8ed70abf3f54Derek Sollenberger obj->setFontVariant(aa ? VARIANT_ELEGANT : VARIANT_DEFAULT); 38453c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien } 38553c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien 386dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jfloat getTextSize(JNIEnv* env, jobject, jlong paintHandle) { 387dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck return SkScalarToFloat(reinterpret_cast<Paint*>(paintHandle)->getTextSize()); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3898451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 390dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setTextSize(JNIEnv* env, jobject, jlong paintHandle, jfloat textSize) { 391dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setTextSize(textSize); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3938451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 394dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jfloat getTextScaleX(JNIEnv* env, jobject, jlong paintHandle) { 395dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck return SkScalarToFloat(reinterpret_cast<Paint*>(paintHandle)->getTextScaleX()); 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3978451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 398dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setTextScaleX(JNIEnv* env, jobject, jlong paintHandle, jfloat scaleX) { 399dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setTextScaleX(scaleX); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4018451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 402dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jfloat getTextSkewX(JNIEnv* env, jobject, jlong paintHandle) { 403dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck return SkScalarToFloat(reinterpret_cast<Paint*>(paintHandle)->getTextSkewX()); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4058451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 406dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static void setTextSkewX(JNIEnv* env, jobject, jlong paintHandle, jfloat skewX) { 407dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck reinterpret_cast<Paint*>(paintHandle)->setTextSkewX(skewX); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4098451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 410fa80f7491df82d71b7084500519a2195afbea706Behdad Esfahbod static jfloat getLetterSpacing(JNIEnv* env, jobject clazz, jlong paintHandle) { 411fa80f7491df82d71b7084500519a2195afbea706Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 412fa80f7491df82d71b7084500519a2195afbea706Behdad Esfahbod return paint->getLetterSpacing(); 413fa80f7491df82d71b7084500519a2195afbea706Behdad Esfahbod } 414fa80f7491df82d71b7084500519a2195afbea706Behdad Esfahbod 415fa80f7491df82d71b7084500519a2195afbea706Behdad Esfahbod static void setLetterSpacing(JNIEnv* env, jobject clazz, jlong paintHandle, jfloat letterSpacing) { 416fa80f7491df82d71b7084500519a2195afbea706Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 417fa80f7491df82d71b7084500519a2195afbea706Behdad Esfahbod paint->setLetterSpacing(letterSpacing); 418fa80f7491df82d71b7084500519a2195afbea706Behdad Esfahbod } 419fa80f7491df82d71b7084500519a2195afbea706Behdad Esfahbod 420805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod static void setFontFeatureSettings(JNIEnv* env, jobject clazz, jlong paintHandle, jstring settings) { 421805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 422e9ad3931fae71c8a8cd000fd52d5df4be79b0895Behdad Esfahbod if (!settings) { 423805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod paint->setFontFeatureSettings(std::string()); 424e9ad3931fae71c8a8cd000fd52d5df4be79b0895Behdad Esfahbod } else { 425805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod ScopedUtfChars settingsChars(env, settings); 426805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod paint->setFontFeatureSettings(std::string(settingsChars.c_str(), settingsChars.size())); 427805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod } 428805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod } 429805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod 430210a189e226d5ce64f760d557efc6570409c8147Raph Levien static jint getHyphenEdit(JNIEnv* env, jobject clazz, jlong paintHandle, jint hyphen) { 431210a189e226d5ce64f760d557efc6570409c8147Raph Levien Paint* paint = reinterpret_cast<Paint*>(paintHandle); 432210a189e226d5ce64f760d557efc6570409c8147Raph Levien return paint->getHyphenEdit(); 433210a189e226d5ce64f760d557efc6570409c8147Raph Levien } 434210a189e226d5ce64f760d557efc6570409c8147Raph Levien 435210a189e226d5ce64f760d557efc6570409c8147Raph Levien static void setHyphenEdit(JNIEnv* env, jobject clazz, jlong paintHandle, jint hyphen) { 436210a189e226d5ce64f760d557efc6570409c8147Raph Levien Paint* paint = reinterpret_cast<Paint*>(paintHandle); 437210a189e226d5ce64f760d557efc6570409c8147Raph Levien paint->setHyphenEdit((uint32_t)hyphen); 438210a189e226d5ce64f760d557efc6570409c8147Raph Levien } 439210a189e226d5ce64f760d557efc6570409c8147Raph Levien 440dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static SkScalar getMetricsInternal(jlong paintHandle, jlong typefaceHandle, 441dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck Paint::FontMetrics *metrics) { 44253c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien const int kElegantTop = 2500; 44353c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien const int kElegantBottom = -1000; 444817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien const int kElegantAscent = 1900; 445817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien const int kElegantDescent = -500; 44653c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien const int kElegantLeading = 0; 447dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 448dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 449817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien typeface = TypefaceImpl_resolveDefault(typeface); 4501fc0fa87d42ce9268ece76b85b9edc834593e53aRaph Levien FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle); 4510627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien float saveSkewX = paint->getTextSkewX(); 4520627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien bool savefakeBold = paint->isFakeBoldText(); 4531fc0fa87d42ce9268ece76b85b9edc834593e53aRaph Levien MinikinFontSkia::populateSkPaint(paint, baseFont.font, baseFont.fakery); 45453c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien SkScalar spacing = paint->getFontMetrics(metrics); 4550627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien // The populateSkPaint call may have changed fake bold / text skew 4560627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien // because we want to measure with those effects applied, so now 4570627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien // restore the original settings. 4580627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien paint->setTextSkewX(saveSkewX); 4590627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien paint->setFakeBoldText(savefakeBold); 4606f03023ece076d33d8b171d5398c8ed70abf3f54Derek Sollenberger if (paint->getFontVariant() == VARIANT_ELEGANT) { 46153c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien SkScalar size = paint->getTextSize(); 46253c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien metrics->fTop = -size * kElegantTop / 2048; 46353c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien metrics->fBottom = -size * kElegantBottom / 2048; 46453c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien metrics->fAscent = -size * kElegantAscent / 2048; 46553c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien metrics->fDescent = -size * kElegantDescent / 2048; 46653c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien metrics->fLeading = size * kElegantLeading / 2048; 46753c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien spacing = metrics->fDescent - metrics->fAscent + metrics->fLeading; 46853c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien } 46953c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien return spacing; 47053c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien } 47153c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien 472dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jfloat ascent(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle) { 4736ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::FontMetrics metrics; 474dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck getMetricsInternal(paintHandle, typefaceHandle, &metrics); 475817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien return SkScalarToFloat(metrics.fAscent); 476817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien } 477817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien 478dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jfloat descent(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle) { 4796ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::FontMetrics metrics; 480dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck getMetricsInternal(paintHandle, typefaceHandle, &metrics); 481817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien return SkScalarToFloat(metrics.fDescent); 482817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien } 483817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien 484dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jfloat getFontMetrics(JNIEnv* env, jobject, jlong paintHandle, 485dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck jlong typefaceHandle, jobject metricsObj) { 4866ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::FontMetrics metrics; 487dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck SkScalar spacing = getMetricsInternal(paintHandle, typefaceHandle, &metrics); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (metricsObj) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class)); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop)); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent)); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent)); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom)); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading)); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SkScalarToFloat(spacing); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4998451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 500dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jint getFontMetricsInt(JNIEnv* env, jobject, jlong paintHandle, 501dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck jlong typefaceHandle, jobject metricsObj) { 5026ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::FontMetrics metrics; 5038451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 504dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck getMetricsInternal(paintHandle, typefaceHandle, &metrics); 50546cb9bdbf56b27cbf2ab878b41d21e30896a4feaLeon Scroggins int ascent = SkScalarRoundToInt(metrics.fAscent); 50646cb9bdbf56b27cbf2ab878b41d21e30896a4feaLeon Scroggins int descent = SkScalarRoundToInt(metrics.fDescent); 50746cb9bdbf56b27cbf2ab878b41d21e30896a4feaLeon Scroggins int leading = SkScalarRoundToInt(metrics.fLeading); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (metricsObj) { 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class)); 51146cb9bdbf56b27cbf2ab878b41d21e30896a4feaLeon Scroggins env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloorToInt(metrics.fTop)); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent); 51446cb9bdbf56b27cbf2ab878b41d21e30896a4feaLeon Scroggins env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeilToInt(metrics.fBottom)); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return descent - ascent + leading; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 520536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi static jfloat doTextAdvances(JNIEnv *env, Paint *paint, TypefaceImpl* typeface, 521536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi const jchar *text, jint start, jint count, jint contextCount, jint bidiFlags, 522536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi jfloatArray advances, jint advancesIndex) { 5236ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio NPE_CHECK_RETURN_ZERO(env, text); 5246ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 5256ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if ((start | count | contextCount | advancesIndex) < 0 || contextCount < count) { 5266ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio doThrowAIOOBE(env); 5276ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio return 0; 5286ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5296ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if (count == 0) { 5306ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio return 0; 5316ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5326ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if (advances) { 5336ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio size_t advancesLength = env->GetArrayLength(advances); 534536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi if ((size_t)(count + advancesIndex) > advancesLength) { 5356ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio doThrowAIOOBE(env); 5366ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio return 0; 5376ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5386ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 539051910b9f998030dacb8a0722588cc715813fde1Raph Levien 5401a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien Layout layout; 541536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count, 542536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi contextCount); 5430c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt if (advances != NULL) { 544536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi std::unique_ptr<jfloat> advancesArray(new jfloat[count]); 545536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi layout.getAdvances(advancesArray.get()); 546536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray.get()); 5470c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 548536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi return layout.getAdvance(); 5490c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 5500c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 551536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi static jfloat getTextAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle, 5521a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien jlong typefaceHandle, 5530c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt jcharArray text, jint index, jint count, jint contextIndex, jint contextCount, 554536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi jint bidiFlags, jfloatArray advances, jint advancesIndex) { 5556ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 5561a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 5570c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt jchar* textArray = env->GetCharArrayElements(text, NULL); 558536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi jfloat result = doTextAdvances(env, paint, typeface, textArray + contextIndex, 559536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi index - contextIndex, count, contextCount, bidiFlags, advances, advancesIndex); 5600c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 5610c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt return result; 5620c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 5630c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 564536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi static jfloat getTextAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle, 5651a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien jlong typefaceHandle, 566536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint bidiFlags, 567665f02c66702b77db25e950ff433230186bc3243Fabrice Di Meglio jfloatArray advances, jint advancesIndex) { 5686ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 5691a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 5700c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt const jchar* textArray = env->GetStringChars(text, NULL); 571536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi jfloat result = doTextAdvances(env, paint, typeface, textArray + contextStart, 572536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi start - contextStart, end - start, contextEnd - contextStart, bidiFlags, 573665f02c66702b77db25e950ff433230186bc3243Fabrice Di Meglio advances, advancesIndex); 574eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio env->ReleaseStringChars(text, textArray); 575eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio return result; 576eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio } 577eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio 5786ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod static jint doTextRunCursor(JNIEnv *env, Paint* paint, const jchar *text, jint start, 579a4bf8114a73371b51a0eba9d5d61dfeb597a1abbFabrice Di Meglio jint count, jint flags, jint offset, jint opt) { 580e368b6bcfd499543a876b4cae02f1ca563ff1cb6Raph Levien GraphemeBreak::MoveOpt moveOpt = GraphemeBreak::MoveOpt(opt); 581e368b6bcfd499543a876b4cae02f1ca563ff1cb6Raph Levien size_t result = GraphemeBreak::getTextRunCursor(text, start, count, offset, moveOpt); 582e368b6bcfd499543a876b4cae02f1ca563ff1cb6Raph Levien return static_cast<jint>(result); 5830c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 5840c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 58536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text, 586051910b9f998030dacb8a0722588cc715813fde1Raph Levien jint contextStart, jint contextCount, jint dir, jint offset, jint cursorOpt) { 5876ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 5880c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt jchar* textArray = env->GetCharArrayElements(text, NULL); 589051910b9f998030dacb8a0722588cc715813fde1Raph Levien jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, dir, 5900c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt offset, cursorOpt); 5910c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 5920c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt return result; 5930c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 5940c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 59536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text, 596051910b9f998030dacb8a0722588cc715813fde1Raph Levien jint contextStart, jint contextEnd, jint dir, jint offset, jint cursorOpt) { 5976ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 5980c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt const jchar* textArray = env->GetStringChars(text, NULL); 5990c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt jint result = doTextRunCursor(env, paint, textArray, contextStart, 600051910b9f998030dacb8a0722588cc715813fde1Raph Levien contextEnd - contextStart, dir, offset, cursorOpt); 6010c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt env->ReleaseStringChars(text, textArray); 6020c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt return result; 6030c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6040c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 605f2114d5646194100242206b267ddd6e7194b7da9Raph Levien class GetTextFunctor { 606f2114d5646194100242206b267ddd6e7194b7da9Raph Levien public: 6076ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod GetTextFunctor(const Layout& layout, SkPath* path, jfloat x, jfloat y, Paint* paint, 608f2114d5646194100242206b267ddd6e7194b7da9Raph Levien uint16_t* glyphs, SkPoint* pos) 609f2114d5646194100242206b267ddd6e7194b7da9Raph Levien : layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) { 610f2114d5646194100242206b267ddd6e7194b7da9Raph Levien } 611f2114d5646194100242206b267ddd6e7194b7da9Raph Levien 6121fc0fa87d42ce9268ece76b85b9edc834593e53aRaph Levien void operator()(size_t start, size_t end) { 613f2114d5646194100242206b267ddd6e7194b7da9Raph Levien for (size_t i = start; i < end; i++) { 614f2114d5646194100242206b267ddd6e7194b7da9Raph Levien glyphs[i] = layout.getGlyphId(i); 615f2114d5646194100242206b267ddd6e7194b7da9Raph Levien pos[i].fX = x + layout.getX(i); 616f2114d5646194100242206b267ddd6e7194b7da9Raph Levien pos[i].fY = y + layout.getY(i); 617f2114d5646194100242206b267ddd6e7194b7da9Raph Levien } 618f2114d5646194100242206b267ddd6e7194b7da9Raph Levien if (start == 0) { 619f2114d5646194100242206b267ddd6e7194b7da9Raph Levien paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, path); 620f2114d5646194100242206b267ddd6e7194b7da9Raph Levien } else { 621f2114d5646194100242206b267ddd6e7194b7da9Raph Levien paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, &tmpPath); 622f2114d5646194100242206b267ddd6e7194b7da9Raph Levien path->addPath(tmpPath); 623f2114d5646194100242206b267ddd6e7194b7da9Raph Levien } 624f2114d5646194100242206b267ddd6e7194b7da9Raph Levien } 625f2114d5646194100242206b267ddd6e7194b7da9Raph Levien private: 626f2114d5646194100242206b267ddd6e7194b7da9Raph Levien const Layout& layout; 627f2114d5646194100242206b267ddd6e7194b7da9Raph Levien SkPath* path; 628f2114d5646194100242206b267ddd6e7194b7da9Raph Levien jfloat x; 629f2114d5646194100242206b267ddd6e7194b7da9Raph Levien jfloat y; 6306ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint; 631f2114d5646194100242206b267ddd6e7194b7da9Raph Levien uint16_t* glyphs; 632f2114d5646194100242206b267ddd6e7194b7da9Raph Levien SkPoint* pos; 633f2114d5646194100242206b267ddd6e7194b7da9Raph Levien SkPath tmpPath; 634f2114d5646194100242206b267ddd6e7194b7da9Raph Levien }; 635f2114d5646194100242206b267ddd6e7194b7da9Raph Levien 6366ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod static void getTextPath(JNIEnv* env, Paint* paint, TypefaceImpl* typeface, const jchar* text, 637f2114d5646194100242206b267ddd6e7194b7da9Raph Levien jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) { 638f2114d5646194100242206b267ddd6e7194b7da9Raph Levien Layout layout; 63963c5c78a72a21d57913e8601cc2a1ab72a424a02Behdad Esfahbod MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count); 640f2114d5646194100242206b267ddd6e7194b7da9Raph Levien size_t nGlyphs = layout.nGlyphs(); 641f2114d5646194100242206b267ddd6e7194b7da9Raph Levien uint16_t* glyphs = new uint16_t[nGlyphs]; 642f2114d5646194100242206b267ddd6e7194b7da9Raph Levien SkPoint* pos = new SkPoint[nGlyphs]; 643f2114d5646194100242206b267ddd6e7194b7da9Raph Levien 644f2114d5646194100242206b267ddd6e7194b7da9Raph Levien x += MinikinUtils::xOffsetForTextAlign(paint, layout); 6456ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::Align align = paint->getTextAlign(); 6466ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod paint->setTextAlign(Paint::kLeft_Align); 6476ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod paint->setTextEncoding(Paint::kGlyphID_TextEncoding); 648f2114d5646194100242206b267ddd6e7194b7da9Raph Levien GetTextFunctor f(layout, path, x, y, paint, glyphs, pos); 6491fc0fa87d42ce9268ece76b85b9edc834593e53aRaph Levien MinikinUtils::forFontRun(layout, paint, f); 650f2114d5646194100242206b267ddd6e7194b7da9Raph Levien paint->setTextAlign(align); 651f2114d5646194100242206b267ddd6e7194b7da9Raph Levien delete[] glyphs; 652f2114d5646194100242206b267ddd6e7194b7da9Raph Levien delete[] pos; 653f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt } 654f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt 655f2114d5646194100242206b267ddd6e7194b7da9Raph Levien static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, 656f2114d5646194100242206b267ddd6e7194b7da9Raph Levien jlong typefaceHandle, jint bidiFlags, 65736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) { 6586ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 659f2114d5646194100242206b267ddd6e7194b7da9Raph Levien TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 66036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat SkPath* path = reinterpret_cast<SkPath*>(pathHandle); 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const jchar* textArray = env->GetCharArrayElements(text, NULL); 662f2114d5646194100242206b267ddd6e7194b7da9Raph Levien getTextPath(env, paint, typeface, textArray + index, count, bidiFlags, x, y, path); 663f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 665f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt 666f2114d5646194100242206b267ddd6e7194b7da9Raph Levien static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, 667f2114d5646194100242206b267ddd6e7194b7da9Raph Levien jlong typefaceHandle, jint bidiFlags, 66836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) { 6696ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 670f2114d5646194100242206b267ddd6e7194b7da9Raph Levien TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 67136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat SkPath* path = reinterpret_cast<SkPath*>(pathHandle); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const jchar* textArray = env->GetStringChars(text, NULL); 673f2114d5646194100242206b267ddd6e7194b7da9Raph Levien getTextPath(env, paint, typeface, textArray + start, end - start, bidiFlags, x, y, path); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseStringChars(text, textArray); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 676f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt 677c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger static void setShadowLayer(JNIEnv* env, jobject clazz, jlong paintHandle, jfloat radius, 67836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jfloat dx, jfloat dy, jint color) { 6796ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (radius <= 0) { 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint->setLooper(NULL); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 684c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger SkScalar sigma = android::uirenderer::Blur::convertRadiusToSigma(radius); 68549f0db34811bc374eb6af0a6ba233325ff6f14ccVictoria Lease paint->setLooper(SkBlurDrawLooper::Create((SkColor)color, sigma, dx, dy))->unref(); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger static jboolean hasShadowLayer(JNIEnv* env, jobject clazz, jlong paintHandle) { 6906ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 691c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger return paint->getLooper() && paint->getLooper()->asABlurShadow(NULL); 692c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger } 693c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger 6946ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod static int breakText(JNIEnv* env, const Paint& paint, TypefaceImpl* typeface, const jchar text[], 695626d3c228116103e95d4429b06dad70f9812561aVictoria Lease int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured, 69657c4fed236cbec0944824b534fb9c828ac0d1f81Derek Sollenberger const bool forwardScan) { 697a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye size_t measuredCount = 0; 698a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye float measured = 0; 699a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye 700a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye Layout layout; 70163c5c78a72a21d57913e8601cc2a1ab72a424a02Behdad Esfahbod MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, 0, count, count); 702a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye float* advances = new float[count]; 703a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye layout.getAdvances(advances); 70457c4fed236cbec0944824b534fb9c828ac0d1f81Derek Sollenberger 705a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye for (int i = 0; i < count; i++) { 706a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye // traverse in the given direction 707a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye int index = forwardScan ? i : (count - i - 1); 708a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye float width = advances[index]; 709a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye if (measured + width > maxWidth) { 710a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye break; 711a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye } 712a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye // properly handle clusters when scanning backwards 713a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye if (forwardScan || width != 0.0f) { 714a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye measuredCount = i + 1; 715a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye } 716a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye measured += width; 717a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye } 718a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye delete[] advances; 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jmeasured && env->GetArrayLength(jmeasured) > 0) { 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaFloatArray autoMeasured(env, jmeasured, 1); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat* array = autoMeasured.ptr(); 723a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye array[0] = measured; 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 725a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye return measuredCount; 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 728a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye static jint breakTextC(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jcharArray jtext, 72936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jint index, jint count, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) { 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jtext); 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7326ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 733a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 734a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye 73557c4fed236cbec0944824b534fb9c828ac0d1f81Derek Sollenberger bool forwardTextDirection; 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count < 0) { 73757c4fed236cbec0944824b534fb9c828ac0d1f81Derek Sollenberger forwardTextDirection = false; 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count = -count; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 74157c4fed236cbec0944824b534fb9c828ac0d1f81Derek Sollenberger forwardTextDirection = true; 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((index < 0) || (index + count > env->GetArrayLength(jtext))) { 7458451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowAIOOBE(env); 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const jchar* text = env->GetCharArrayElements(jtext, NULL); 750a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye count = breakText(env, *paint, typeface, text + index, count, maxWidth, 75157c4fed236cbec0944824b534fb9c828ac0d1f81Derek Sollenberger bidiFlags, jmeasuredWidth, forwardTextDirection); 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text), 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNI_ABORT); 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return count; 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 757a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye static jint breakTextS(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring jtext, 75836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, jtext); 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7616ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 762a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 763a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = env->GetStringLength(jtext); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const jchar* text = env->GetStringChars(jtext, NULL); 76657c4fed236cbec0944824b534fb9c828ac0d1f81Derek Sollenberger count = breakText(env, *paint, typeface, text, count, maxWidth, bidiFlags, jmeasuredWidth, forwards); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseStringChars(jtext, text); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return count; 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 771854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien static void doTextBounds(JNIEnv* env, const jchar* text, int count, jobject bounds, 7726ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint& paint, TypefaceImpl* typeface, jint bidiFlags) { 773059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy SkRect r; 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkIRect ir; 7758451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 776854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien Layout layout; 77763c5c78a72a21d57913e8601cc2a1ab72a424a02Behdad Esfahbod MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, 0, count, count); 778854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien MinikinRect rect; 779854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien layout.getBounds(&rect); 780854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien r.fLeft = rect.mLeft; 781854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien r.fTop = rect.mTop; 782854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien r.fRight = rect.mRight; 783854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien r.fBottom = rect.mBottom; 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.roundOut(&ir); 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsJNI::irect_to_jrect(ir, env, bounds); 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 788854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle, 78936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jstring text, jint start, jint end, jint bidiFlags, jobject bounds) { 790dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 791854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const jchar* textArray = env->GetStringChars(text, NULL); 793854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien doTextBounds(env, textArray + start, end - start, bounds, *paint, typeface, bidiFlags); 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseStringChars(text, textArray); 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7968451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 797854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle, 79836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) { 7996ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 800854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const jchar* textArray = env->GetCharArrayElements(text, NULL); 802854363e3d2fb2a9e41d8719f4a2f0f8b89440a46Raph Levien doTextBounds(env, textArray + index, count, bounds, *paint, typeface, bidiFlags); 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNI_ABORT); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8068451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 807f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien static jboolean layoutContainsNotdef(const Layout& layout) { 808f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien for (size_t i = 0; i < layout.nGlyphs(); i++) { 809f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien if (layout.getGlyphId(i) == 0) { 810f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien return true; 811f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 812f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 813f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien return false; 814f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 815f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien 816f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien static jboolean hasGlyphVariation(const Paint* paint, TypefaceImpl* typeface, jint bidiFlags, 817f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien const jchar* chars, size_t size) { 818f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien // TODO: query font for whether character has variation selector; requires a corresponding 819f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien // function in Minikin. 820f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien return false; 821f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 822f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien 823f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien static jboolean hasGlyph(JNIEnv *env, jclass, jlong paintHandle, jlong typefaceHandle, 824f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien jint bidiFlags, jstring string) { 825f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 826f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 827f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien ScopedStringChars str(env, string); 828f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien 829f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien /* start by rejecting variation selectors (not supported yet) */ 830f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien size_t nChars = 0; 831f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien for (size_t i = 0; i < str.size(); i++) { 832f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien jchar c = str[i]; 833f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien if (0xDC00 <= c && c <= 0xDFFF) { 834f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien // invalid UTF-16, unpaired trailing surrogate 835f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien return false; 836f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } else if (0xD800 <= c && c <= 0xDBFF) { 837f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien if (i + 1 == str.size()) { 838f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien // invalid UTF-16, unpaired leading surrogate at end of string 839f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien return false; 840f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 841f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien i++; 842f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien jchar c2 = str[i]; 843f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien if (!(0xDC00 <= c2 && c2 <= 0xDFFF)) { 844f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien // invalid UTF-16, unpaired leading surrogate 845f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien return false; 846f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 847f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien // UTF-16 encoding of range U+E0100..U+E01EF is DB40 DD00 .. DB40 DDEF 848f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien if (c == 0xDB40 && 0xDD00 <= c2 && c2 <= 0xDDEF) { 849f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien return hasGlyphVariation(paint, typeface, bidiFlags, str.get(), str.size()); 850f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 851f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } else if (0xFE00 <= c && c <= 0xFE0F) { 852f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien return hasGlyphVariation(paint, typeface, bidiFlags, str.get(), str.size()); 853f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 854f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien nChars++; 855f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 856f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien Layout layout; 857f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, str.get(), 0, str.size(), 858f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien str.size()); 859f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien size_t nGlyphs = layout.nGlyphs(); 860f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien if (nGlyphs != 1 && nChars > 1) { 861f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien // multiple-character input, and was not a ligature 862f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien // TODO: handle ZWJ/ZWNJ characters specially so we can detect certain ligatures 863f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien // in joining scripts, such as Arabic and Mongolian. 864f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien return false; 865f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 866f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien return nGlyphs > 0 && !layoutContainsNotdef(layout); 867f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 868f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien 869a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien static jfloat doRunAdvance(const Paint* paint, TypefaceImpl* typeface, const jchar buf[], 870a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien jint start, jint count, jint bufSize, jboolean isRtl, jint offset) { 871a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien Layout layout; 872a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; 873a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, buf, start, count, bufSize); 874a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien return getRunAdvance(layout, buf, start, count, offset); 875a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien } 876a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien 877a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien static jfloat getRunAdvance___CIIIIZI_F(JNIEnv *env, jclass, jlong paintHandle, 878a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien jlong typefaceHandle, jcharArray text, jint start, jint end, jint contextStart, 879a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien jint contextEnd, jboolean isRtl, jint offset) { 880a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 881a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 882c6024cdd3553760aa99bfbabecc6a3d8443f5c47John Reck jchar* textArray = (jchar*) env->GetPrimitiveArrayCritical(text, NULL); 883a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien jfloat result = doRunAdvance(paint, typeface, textArray + contextStart, 88436ff86c9a3d61dfab43b7f35631bf86d65150252Raph Levien start - contextStart, end - start, contextEnd - contextStart, isRtl, 88536ff86c9a3d61dfab43b7f35631bf86d65150252Raph Levien offset - contextStart); 886c6024cdd3553760aa99bfbabecc6a3d8443f5c47John Reck env->ReleasePrimitiveArrayCritical(text, textArray, JNI_ABORT); 887a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien return result; 888a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien } 889a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien 890a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien static jint doOffsetForAdvance(const Paint* paint, TypefaceImpl* typeface, const jchar buf[], 891a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien jint start, jint count, jint bufSize, jboolean isRtl, jfloat advance) { 892a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien Layout layout; 893a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; 894a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, buf, start, count, bufSize); 895a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien return getOffsetForAdvance(layout, buf, start, count, advance); 896a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien } 897a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien static jint getOffsetForAdvance___CIIIIZF_I(JNIEnv *env, jclass, jlong paintHandle, 898a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien jlong typefaceHandle, jcharArray text, jint start, jint end, jint contextStart, 899a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien jint contextEnd, jboolean isRtl, jfloat advance) { 900a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 901a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); 902c6024cdd3553760aa99bfbabecc6a3d8443f5c47John Reck jchar* textArray = (jchar*) env->GetPrimitiveArrayCritical(text, NULL); 903a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien jint result = doOffsetForAdvance(paint, typeface, textArray + contextStart, 904a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien start - contextStart, end - start, contextEnd - contextStart, isRtl, advance); 905a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien result += contextStart; 906c6024cdd3553760aa99bfbabecc6a3d8443f5c47John Reck env->ReleasePrimitiveArrayCritical(text, textArray, JNI_ABORT); 907a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien return result; 908a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien } 909a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien 910dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck}; // namespace PaintGlue 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 91276f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod methods[] = { 913dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nFinalizer", "(J)V", (void*) PaintGlue::finalizer}, 914dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nInit","()J", (void*) PaintGlue::init}, 915dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nInitWithPaint","(J)J", (void*) PaintGlue::initWithPaint}, 916dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck 917dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nReset","!(J)V", (void*) PaintGlue::reset}, 918dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSet","!(JJ)V", (void*) PaintGlue::assign}, 919dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetFlags","!(J)I", (void*) PaintGlue::getFlags}, 920dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetFlags","!(JI)V", (void*) PaintGlue::setFlags}, 921dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetHinting","!(J)I", (void*) PaintGlue::getHinting}, 922dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetHinting","!(JI)V", (void*) PaintGlue::setHinting}, 923dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetAntiAlias","!(JZ)V", (void*) PaintGlue::setAntiAlias}, 924dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetSubpixelText","!(JZ)V", (void*) PaintGlue::setSubpixelText}, 925dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetLinearText","!(JZ)V", (void*) PaintGlue::setLinearText}, 926dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetUnderlineText","!(JZ)V", (void*) PaintGlue::setUnderlineText}, 927dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetStrikeThruText","!(JZ)V", (void*) PaintGlue::setStrikeThruText}, 928dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetFakeBoldText","!(JZ)V", (void*) PaintGlue::setFakeBoldText}, 929dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetFilterBitmap","!(JZ)V", (void*) PaintGlue::setFilterBitmap}, 930dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetDither","!(JZ)V", (void*) PaintGlue::setDither}, 931dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetStyle","!(J)I", (void*) PaintGlue::getStyle}, 932dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetStyle","!(JI)V", (void*) PaintGlue::setStyle}, 933dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetColor","!(J)I", (void*) PaintGlue::getColor}, 934dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetColor","!(JI)V", (void*) PaintGlue::setColor}, 935dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetAlpha","!(J)I", (void*) PaintGlue::getAlpha}, 936dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetAlpha","!(JI)V", (void*) PaintGlue::setAlpha}, 937dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetStrokeWidth","!(J)F", (void*) PaintGlue::getStrokeWidth}, 938dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetStrokeWidth","!(JF)V", (void*) PaintGlue::setStrokeWidth}, 939dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetStrokeMiter","!(J)F", (void*) PaintGlue::getStrokeMiter}, 940dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetStrokeMiter","!(JF)V", (void*) PaintGlue::setStrokeMiter}, 941dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetStrokeCap","!(J)I", (void*) PaintGlue::getStrokeCap}, 942dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetStrokeCap","!(JI)V", (void*) PaintGlue::setStrokeCap}, 943dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetStrokeJoin","!(J)I", (void*) PaintGlue::getStrokeJoin}, 944dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetStrokeJoin","!(JI)V", (void*) PaintGlue::setStrokeJoin}, 945dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetFillPath","!(JJJ)Z", (void*) PaintGlue::getFillPath}, 946dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetShader","!(JJ)J", (void*) PaintGlue::setShader}, 947dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetColorFilter","!(JJ)J", (void*) PaintGlue::setColorFilter}, 948dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetXfermode","!(JJ)J", (void*) PaintGlue::setXfermode}, 949dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetPathEffect","!(JJ)J", (void*) PaintGlue::setPathEffect}, 950dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetMaskFilter","!(JJ)J", (void*) PaintGlue::setMaskFilter}, 951dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetTypeface","!(JJ)J", (void*) PaintGlue::setTypeface}, 952dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetRasterizer","!(JJ)J", (void*) PaintGlue::setRasterizer}, 953dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextAlign","!(J)I", (void*) PaintGlue::getTextAlign}, 954dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetTextAlign","!(JI)V", (void*) PaintGlue::setTextAlign}, 955dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetTextLocale","!(JLjava/lang/String;)V", (void*) PaintGlue::setTextLocale}, 956dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nIsElegantTextHeight","!(J)Z", (void*) PaintGlue::isElegantTextHeight}, 957dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetElegantTextHeight","!(JZ)V", (void*) PaintGlue::setElegantTextHeight}, 958dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextSize","!(J)F", (void*) PaintGlue::getTextSize}, 959dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetTextSize","!(JF)V", (void*) PaintGlue::setTextSize}, 960dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextScaleX","!(J)F", (void*) PaintGlue::getTextScaleX}, 961dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetTextScaleX","!(JF)V", (void*) PaintGlue::setTextScaleX}, 962dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextSkewX","!(J)F", (void*) PaintGlue::getTextSkewX}, 963dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetTextSkewX","!(JF)V", (void*) PaintGlue::setTextSkewX}, 964dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetLetterSpacing","!(J)F", (void*) PaintGlue::getLetterSpacing}, 965dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetLetterSpacing","!(JF)V", (void*) PaintGlue::setLetterSpacing}, 966dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetFontFeatureSettings","(JLjava/lang/String;)V", 967a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*) PaintGlue::setFontFeatureSettings}, 968dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetHyphenEdit", "!(J)I", (void*) PaintGlue::getHyphenEdit}, 969dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetHyphenEdit", "!(JI)V", (void*) PaintGlue::setHyphenEdit}, 970dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nAscent","!(JJ)F", (void*) PaintGlue::ascent}, 971dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nDescent","!(JJ)F", (void*) PaintGlue::descent}, 9724136a0aeac9bb95aa615d4fc1f12378829d26c80Chris Craik 973dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetFontMetrics", "!(JJLandroid/graphics/Paint$FontMetrics;)F", 974a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*)PaintGlue::getFontMetrics}, 975dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetFontMetricsInt", "!(JJLandroid/graphics/Paint$FontMetricsInt;)I", 976a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*)PaintGlue::getFontMetricsInt}, 977536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi 978dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nBreakText","(JJ[CIIFI[F)I", (void*) PaintGlue::breakTextC}, 979dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nBreakText","(JJLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS}, 980dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextAdvances","(JJ[CIIIII[FI)F", 981536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi (void*) PaintGlue::getTextAdvances___CIIIII_FI}, 982dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextAdvances","(JJLjava/lang/String;IIIII[FI)F", 983536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi (void*) PaintGlue::getTextAdvances__StringIIIII_FI}, 984da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio 985dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C}, 986dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextRunCursor", "(JLjava/lang/String;IIIII)I", 987a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*) PaintGlue::getTextRunCursor__String}, 988dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextPath", "(JJI[CIIFFJ)V", (void*) PaintGlue::getTextPath___C}, 989dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextPath", "(JJILjava/lang/String;IIFFJ)V", (void*) PaintGlue::getTextPath__String}, 990dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetStringBounds", "(JJLjava/lang/String;IIILandroid/graphics/Rect;)V", 991a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*) PaintGlue::getStringBounds }, 992dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V", 993a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*) PaintGlue::getCharArrayBounds }, 994dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nHasGlyph", "(JJILjava/lang/String;)Z", (void*) PaintGlue::hasGlyph }, 995dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetRunAdvance", "(JJ[CIIIIZI)F", (void*) PaintGlue::getRunAdvance___CIIIIZI_F}, 996dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetOffsetForAdvance", "(JJ[CIIIIZF)I", 997a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*) PaintGlue::getOffsetForAdvance___CIIIIZF_I}, 9984136a0aeac9bb95aa615d4fc1f12378829d26c80Chris Craik 999dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nSetShadowLayer", "!(JFFFI)V", (void*)PaintGlue::setShadowLayer}, 1000dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nHasShadowLayer", "!(J)Z", (void*)PaintGlue::hasShadowLayer} 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_graphics_Paint(JNIEnv* env) { 1004ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_class = FindClassOrDie(env, "android/graphics/Paint$FontMetrics"); 1005ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_class = MakeGlobalRefOrDie(env, gFontMetrics_class); 1006ab22c1c792bc5f422a029a4ab6a23861e44136d8Derek Sollenberger 1007ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_fieldID.top = GetFieldIDOrDie(env, gFontMetrics_class, "top", "F"); 1008ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_fieldID.ascent = GetFieldIDOrDie(env, gFontMetrics_class, "ascent", "F"); 1009ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_fieldID.descent = GetFieldIDOrDie(env, gFontMetrics_class, "descent", "F"); 1010ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_fieldID.bottom = GetFieldIDOrDie(env, gFontMetrics_class, "bottom", "F"); 1011ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_fieldID.leading = GetFieldIDOrDie(env, gFontMetrics_class, "leading", "F"); 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1013ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_class = FindClassOrDie(env, "android/graphics/Paint$FontMetricsInt"); 1014ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_class = MakeGlobalRefOrDie(env, gFontMetricsInt_class); 1015ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 1016ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_fieldID.top = GetFieldIDOrDie(env, gFontMetricsInt_class, "top", "I"); 1017ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_fieldID.ascent = GetFieldIDOrDie(env, gFontMetricsInt_class, "ascent", "I"); 1018ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_fieldID.descent = GetFieldIDOrDie(env, gFontMetricsInt_class, "descent", "I"); 1019ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_fieldID.bottom = GetFieldIDOrDie(env, gFontMetricsInt_class, "bottom", "I"); 1020ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_fieldID.leading = GetFieldIDOrDie(env, gFontMetricsInt_class, "leading", "I"); 1021ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 1022ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return RegisterMethodsOrDie(env, "android/graphics/Paint", methods, NELEM(methods)); 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1026