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" 252279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/ScopedStringChars.h> 262279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/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" 31eba81d0f88f52ca097204ca526e796a83fdd57d5Derek Sollenberger#include "SkPath.h" 32260ab726486317496bc12a57d599ea96dcde3284Mike Reed#include "SkPathEffect.h" 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkShader.h" 34c2f31df8b3b9a237e9abffc59c61804ad8495073Mike Reed#include "SkBlendMode.h" 35ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett#include "unicode/uloc.h" 360c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt#include "unicode/ushape.h" 37c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger#include "utils/Blur.h" 380c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 39dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/MinikinSkia.h> 40dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/MinikinUtils.h> 41dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/Paint.h> 42bad99183916ba2bac6659efc8a28273e344ba511sergeyv#include <hwui/Typeface.h> 43e368b6bcfd499543a876b4cae02f1ca563ff1cb6Raph Levien#include <minikin/GraphemeBreak.h> 44a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien#include <minikin/Measurement.h> 45bb1a96647a82df5a134bf631fc9db342e7ef61deSeigo Nonaka#include <unicode/utf16.h> 461a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 47f036ead2a218ffa43697fcaa999b666a4c6d13cfRoozbeh Pournader#include <cassert> 48f036ead2a218ffa43697fcaa999b666a4c6d13cfRoozbeh Pournader#include <cstring> 49536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi#include <memory> 50f036ead2a218ffa43697fcaa999b666a4c6d13cfRoozbeh Pournader#include <vector> 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct JMetricsID { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID top; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID ascent; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID descent; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID bottom; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID leading; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gFontMetrics_class; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JMetricsID gFontMetrics_fieldID; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gFontMetricsInt_class; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JMetricsID gFontMetricsInt_fieldID; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 686ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbodstatic void defaultSettingsForAndroid(Paint* paint) { 69c511bee87cda99a252d1a62487f47c8f05aee78cFabrice Di Meglio // GlyphID encoding is required because we are using Harfbuzz shaping 706ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod paint->setTextEncoding(Paint::kGlyphID_TextEncoding); 713d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed} 723d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed 73dbffd250003e60c0f11ac3ad2b63f91f67962610John Recknamespace PaintGlue { 740c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt enum MoveOpt { 750c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT 760c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt }; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler static void deletePaint(Paint* paint) { 79775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler delete paint; 80775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler } 81775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler 82775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler static jlong getNativeFinalizer(JNIEnv*, jobject) { 83775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler return static_cast<jlong>(reinterpret_cast<uintptr_t>(&deletePaint)); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 86dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jlong init(JNIEnv* env, jobject) { 87b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed static_assert(1 << 0 == SkPaint::kAntiAlias_Flag, "paint_flags_mismatch"); 88b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed static_assert(1 << 2 == SkPaint::kDither_Flag, "paint_flags_mismatch"); 89b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed static_assert(1 << 3 == SkPaint::kUnderlineText_ReserveFlag, "paint_flags_mismatch"); 90b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed static_assert(1 << 4 == SkPaint::kStrikeThruText_ReserveFlag, "paint_flags_mismatch"); 91b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed static_assert(1 << 5 == SkPaint::kFakeBoldText_Flag, "paint_flags_mismatch"); 92b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed static_assert(1 << 6 == SkPaint::kLinearText_Flag, "paint_flags_mismatch"); 93b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed static_assert(1 << 7 == SkPaint::kSubpixelText_Flag, "paint_flags_mismatch"); 94b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed static_assert(1 << 8 == SkPaint::kDevKernText_Flag, "paint_flags_mismatch"); 95b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed static_assert(1 << 10 == SkPaint::kEmbeddedBitmapText_Flag, "paint_flags_mismatch"); 960b8606266c1afc69cbeb73acda67c85d87943318Derek Sollenberger 976ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = new Paint(); 983d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed defaultSettingsForAndroid(obj); 9936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(obj); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat static jlong initWithPaint(JNIEnv* env, jobject clazz, jlong paintHandle) { 1036ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 1046ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = new Paint(*paint); 10536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(obj); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1078451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 108f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static int breakText(JNIEnv* env, const Paint& paint, Typeface* typeface, const jchar text[], 109f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured, 110f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const bool forwardScan) { 111f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck size_t measuredCount = 0; 112f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck float measured = 0; 1138451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 114f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck std::unique_ptr<float[]> advancesArray(new float[count]); 115f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck MinikinUtils::measureText(&paint, bidiFlags, typeface, text, 0, count, count, 116f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck advancesArray.get()); 1174c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed 118f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck for (int i = 0; i < count; i++) { 119f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // traverse in the given direction 120f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck int index = forwardScan ? i : (count - i - 1); 121f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck float width = advancesArray[index]; 122f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (measured + width > maxWidth) { 123f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck break; 124f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 125f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // properly handle clusters when scanning backwards 126f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (forwardScan || width != 0.0f) { 127f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck measuredCount = i + 1; 128f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 129f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck measured += width; 1304c9355c35a0f62805739823a62ad41ca1cbc6502Mike Reed } 1318451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 132f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (jmeasured && env->GetArrayLength(jmeasured) > 0) { 133f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck AutoJavaFloatArray autoMeasured(env, jmeasured, 1); 134f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jfloat* array = autoMeasured.ptr(); 135f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck array[0] = measured; 136f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 137f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return measuredCount; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1398451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 140f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint breakTextC(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, 141f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jcharArray jtext, jint index, jint count, jfloat maxWidth, jint bidiFlags, 142f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jfloatArray jmeasuredWidth) { 143f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck NPE_CHECK_RETURN_ZERO(env, jtext); 144f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn 145f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 146f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 147f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn 148f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck bool forwardTextDirection; 149f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (count < 0) { 150f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck forwardTextDirection = false; 151f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck count = -count; 152f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 153f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck else { 154f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck forwardTextDirection = true; 155f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 1568451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 157f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if ((index < 0) || (index + count > env->GetArrayLength(jtext))) { 158f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck doThrowAIOOBE(env); 159f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return 0; 160f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 1618451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 162f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar* text = env->GetCharArrayElements(jtext, nullptr); 163f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck count = breakText(env, *paint, typeface, text + index, count, maxWidth, 164f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck bidiFlags, jmeasuredWidth, forwardTextDirection); 165f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text), 166f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck JNI_ABORT); 167f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return count; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1698451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 170f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint breakTextS(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring jtext, 171f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) { 172f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck NPE_CHECK_RETURN_ZERO(env, jtext); 1738451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 174f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 175f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 1768451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 177f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck int count = env->GetStringLength(jtext); 178f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar* text = env->GetStringChars(jtext, nullptr); 179f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck count = breakText(env, *paint, typeface, text, count, maxWidth, bidiFlags, jmeasuredWidth, forwards); 180f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleaseStringChars(jtext, text); 181f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return count; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1838451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 184f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat doTextAdvances(JNIEnv *env, Paint *paint, Typeface* typeface, 185f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar *text, jint start, jint count, jint contextCount, jint bidiFlags, 186f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jfloatArray advances, jint advancesIndex) { 187f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck NPE_CHECK_RETURN_ZERO(env, text); 1888451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 189f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if ((start | count | contextCount | advancesIndex) < 0 || contextCount < count) { 190f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck doThrowAIOOBE(env); 191f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return 0; 192f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 193f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (count == 0) { 194f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return 0; 195f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 196f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (advances) { 197f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck size_t advancesLength = env->GetArrayLength(advances); 198f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if ((size_t)(count + advancesIndex) > advancesLength) { 199f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck doThrowAIOOBE(env); 200f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return 0; 201f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 202f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 203f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck std::unique_ptr<jfloat[]> advancesArray; 204f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (advances) { 205f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck advancesArray.reset(new jfloat[count]); 206f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 207f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const float advance = MinikinUtils::measureText(paint, bidiFlags, typeface, text, 208f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck start, count, contextCount, advancesArray.get()); 209f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (advances) { 210f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray.get()); 211f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 212f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return advance; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2148451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 215f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat getTextAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle, 216f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jlong typefaceHandle, 217f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jcharArray text, jint index, jint count, jint contextIndex, jint contextCount, 218f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jint bidiFlags, jfloatArray advances, jint advancesIndex) { 219f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 220f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 221f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jchar* textArray = env->GetCharArrayElements(text, nullptr); 222f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jfloat result = doTextAdvances(env, paint, typeface, textArray + contextIndex, 223f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck index - contextIndex, count, contextCount, bidiFlags, advances, advancesIndex); 224f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 225f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return result; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2278451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 228f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat getTextAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle, 229f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jlong typefaceHandle, 230f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint bidiFlags, 231f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jfloatArray advances, jint advancesIndex) { 232f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 233f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 234f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar* textArray = env->GetStringChars(text, nullptr); 235f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jfloat result = doTextAdvances(env, paint, typeface, textArray + contextStart, 236f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck start - contextStart, end - start, contextEnd - contextStart, bidiFlags, 237f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck advances, advancesIndex); 238f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleaseStringChars(text, textArray); 239f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return result; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2418451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 2425d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader static jint doTextRunCursor(JNIEnv *env, Paint* paint, Typeface* typeface, const jchar *text, 2435d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader jint start, jint count, jint dir, jint offset, jint opt) { 244f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck minikin::GraphemeBreak::MoveOpt moveOpt = minikin::GraphemeBreak::MoveOpt(opt); 2455d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader int bidiFlags = dir == 1 ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR; 2465d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader std::unique_ptr<float[]> advancesArray(new float[count]); 2475d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader MinikinUtils::measureText(paint, bidiFlags, typeface, text, start, count, start + count, 2485d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader advancesArray.get()); 2495d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader size_t result = minikin::GraphemeBreak::getTextRunCursor(advancesArray.get(), text, 2505d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader start, count, offset, moveOpt); 251f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return static_cast<jint>(result); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2538451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 2545d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, 2555d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader jlong typefaceHandle, jcharArray text, jint contextStart, jint contextCount, jint dir, 2565d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader jint offset, jint cursorOpt) { 257f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2585d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 259f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jchar* textArray = env->GetCharArrayElements(text, nullptr); 2605d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader jint result = doTextRunCursor(env, paint, typeface, textArray, 2615d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader contextStart, contextCount, dir, offset, cursorOpt); 262f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 263f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return result; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2658451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 2665d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, 2675d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader jlong typefaceHandle, jstring text, jint contextStart, jint contextEnd, jint dir, 2685d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader jint offset, jint cursorOpt) { 269f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 2705d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 271f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar* textArray = env->GetStringChars(text, nullptr); 2725d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader jint result = doTextRunCursor(env, paint, typeface, textArray, 2735d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader contextStart, contextEnd - contextStart, dir, offset, cursorOpt); 274f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleaseStringChars(text, textArray); 275f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return result; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2778451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 278f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck class GetTextFunctor { 279f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck public: 280f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck GetTextFunctor(const minikin::Layout& layout, SkPath* path, jfloat x, jfloat y, 281f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint, uint16_t* glyphs, SkPoint* pos) 282f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck : layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) { 283f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 2848451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 285f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck void operator()(size_t start, size_t end) { 286f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck for (size_t i = start; i < end; i++) { 287f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck glyphs[i] = layout.getGlyphId(i); 288f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck pos[i].fX = x + layout.getX(i); 289f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck pos[i].fY = y + layout.getY(i); 290f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 291f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (start == 0) { 292f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, path); 293f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } else { 294f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, &tmpPath); 295f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck path->addPath(tmpPath); 296f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 297f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 298f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck private: 299f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const minikin::Layout& layout; 300f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkPath* path; 301f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jfloat x; 302f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jfloat y; 303f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint; 304f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck uint16_t* glyphs; 305f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkPoint* pos; 306f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkPath tmpPath; 307f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck }; 3088451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 309f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void getTextPath(JNIEnv* env, Paint* paint, Typeface* typeface, const jchar* text, 310f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) { 311c7064146f959caec058980ced144942c8044a169Seigo Nonaka minikin::Layout layout = MinikinUtils::doLayout( 312c7064146f959caec058980ced144942c8044a169Seigo Nonaka paint, bidiFlags, typeface, text, 0, count, count); 313f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck size_t nGlyphs = layout.nGlyphs(); 314f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck uint16_t* glyphs = new uint16_t[nGlyphs]; 315f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkPoint* pos = new SkPoint[nGlyphs]; 3168451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 317f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck x += MinikinUtils::xOffsetForTextAlign(paint, layout); 318f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint::Align align = paint->getTextAlign(); 319f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck paint->setTextAlign(Paint::kLeft_Align); 320f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck paint->setTextEncoding(Paint::kGlyphID_TextEncoding); 321f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck GetTextFunctor f(layout, path, x, y, paint, glyphs, pos); 322f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck MinikinUtils::forFontRun(layout, paint, f); 323f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck paint->setTextAlign(align); 324f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck delete[] glyphs; 325f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck delete[] pos; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3278451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 328f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, 329f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jlong typefaceHandle, jint bidiFlags, 330f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) { 331f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 332f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 333f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkPath* path = reinterpret_cast<SkPath*>(pathHandle); 334f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar* textArray = env->GetCharArrayElements(text, nullptr); 335f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck getTextPath(env, paint, typeface, textArray + index, count, bidiFlags, x, y, path); 336f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3388451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 339f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, 340f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jlong typefaceHandle, jint bidiFlags, 341f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) { 342f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 343f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 344f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkPath* path = reinterpret_cast<SkPath*>(pathHandle); 345f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar* textArray = env->GetStringChars(text, nullptr); 346f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck getTextPath(env, paint, typeface, textArray + start, end - start, bidiFlags, x, y, path); 347f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleaseStringChars(text, textArray); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3498451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 350f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void doTextBounds(JNIEnv* env, const jchar* text, int count, jobject bounds, 351f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const Paint& paint, Typeface* typeface, jint bidiFlags) { 352f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkRect r; 353f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkIRect ir; 354f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 355c7064146f959caec058980ced144942c8044a169Seigo Nonaka minikin::Layout layout = MinikinUtils::doLayout( 356c7064146f959caec058980ced144942c8044a169Seigo Nonaka &paint, bidiFlags, typeface, text, 0, count, count); 357f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck minikin::MinikinRect rect; 358f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck layout.getBounds(&rect); 359f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck r.fLeft = rect.mLeft; 360f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck r.fTop = rect.mTop; 361f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck r.fRight = rect.mRight; 362f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck r.fBottom = rect.mBottom; 363f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck r.roundOut(&ir); 364f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck GraphicsJNI::irect_to_jrect(ir, env, bounds); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3668451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 367f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle, 368f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jstring text, jint start, jint end, jint bidiFlags, jobject bounds) { 369f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 370f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 371f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar* textArray = env->GetStringChars(text, nullptr); 372f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck doTextBounds(env, textArray + start, end - start, bounds, *paint, typeface, bidiFlags); 373f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleaseStringChars(text, textArray); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3758451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 376f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle, 377f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) { 378f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 379f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 380f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar* textArray = env->GetCharArrayElements(text, nullptr); 381f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck doTextBounds(env, textArray + index, count, bounds, *paint, typeface, bidiFlags); 382f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), 383f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck JNI_ABORT); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3858451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 386f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // Returns true if the given string is exact one pair of regional indicators. 387f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static bool isFlag(const jchar* str, size_t length) { 388f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar RI_LEAD_SURROGATE = 0xD83C; 389f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar RI_TRAIL_SURROGATE_MIN = 0xDDE6; 390f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const jchar RI_TRAIL_SURROGATE_MAX = 0xDDFF; 391f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 392f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (length != 4) { 393f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return false; 394f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 395f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (str[0] != RI_LEAD_SURROGATE || str[2] != RI_LEAD_SURROGATE) { 396f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return false; 397f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 398f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return RI_TRAIL_SURROGATE_MIN <= str[1] && str[1] <= RI_TRAIL_SURROGATE_MAX && 399f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck RI_TRAIL_SURROGATE_MIN <= str[3] && str[3] <= RI_TRAIL_SURROGATE_MAX; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4018451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 402f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jboolean layoutContainsNotdef(const minikin::Layout& layout) { 403f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck for (size_t i = 0; i < layout.nGlyphs(); i++) { 404f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (layout.getGlyphId(i) == 0) { 405f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return true; 406f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 407f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 408f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return false; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4108451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 411f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // Don't count glyphs that are the recommended "space" glyph and are zero width. 412f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // This logic makes assumptions about HarfBuzz layout, but does correctly handle 413f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // cases where ligatures form and zero width space glyphs are left in as 414f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // placeholders. 415f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static size_t countNonSpaceGlyphs(const minikin::Layout& layout) { 416f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck size_t count = 0; 417f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static unsigned int kSpaceGlyphId = 3; 418f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck for (size_t i = 0; i < layout.nGlyphs(); i++) { 419f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (layout.getGlyphId(i) != kSpaceGlyphId || layout.getCharAdvance(i) != 0.0) { 420f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck count++; 421f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 422f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 423f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return count; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4258451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 426f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jboolean hasGlyph(JNIEnv *env, jclass, jlong paintHandle, jlong typefaceHandle, 427f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jint bidiFlags, jstring string) { 428f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 429f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 430f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck ScopedStringChars str(env, string); 4315d31a293ad0a832c7b8b445c1a67fb1800e5da32John Reck 432f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck /* Start by rejecting unsupported base code point and variation selector pairs. */ 433f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck size_t nChars = 0; 434f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const uint32_t kStartOfString = 0xFFFFFFFF; 435f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck uint32_t prevCp = kStartOfString; 436f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck for (size_t i = 0; i < str.size(); i++) { 437f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jchar cu = str[i]; 438f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck uint32_t cp = cu; 439f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (U16_IS_TRAIL(cu)) { 440f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // invalid UTF-16, unpaired trailing surrogate 441f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return false; 442f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } else if (U16_IS_LEAD(cu)) { 443f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (i + 1 == str.size()) { 444f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // invalid UTF-16, unpaired leading surrogate at end of string 445f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return false; 446f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 447f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck i++; 448f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jchar cu2 = str[i]; 449f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (!U16_IS_TRAIL(cu2)) { 450f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // invalid UTF-16, unpaired leading surrogate 451f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return false; 452f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 453f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck cp = U16_GET_SUPPLEMENTARY(cu, cu2); 454f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 4558451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 456f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (prevCp != kStartOfString && 457f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck ((0xFE00 <= cp && cp <= 0xFE0F) || (0xE0100 <= cp && cp <= 0xE01EF))) { 458f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck bool hasVS = MinikinUtils::hasVariationSelector(typeface, prevCp, cp); 459f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (!hasVS) { 460f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // No font has a glyph for the code point and variation selector pair. 461f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return false; 462f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } else if (nChars == 1 && i + 1 == str.size()) { 463f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // The string is just a codepoint and a VS, we have an authoritative answer 464f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return true; 465f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 466f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 467f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck nChars++; 468f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck prevCp = cp; 469f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 470c7064146f959caec058980ced144942c8044a169Seigo Nonaka minikin::Layout layout = MinikinUtils::doLayout( 471c7064146f959caec058980ced144942c8044a169Seigo Nonaka paint, bidiFlags, typeface, str.get(), 0, str.size(), str.size()); 472f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck size_t nGlyphs = countNonSpaceGlyphs(layout); 473f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (nGlyphs != 1 && nChars > 1) { 474f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // multiple-character input, and was not a ligature 475f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // TODO: handle ZWJ/ZWNJ characters specially so we can detect certain ligatures 476f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // in joining scripts, such as Arabic and Mongolian. 477f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return false; 478f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 4798451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 480f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (nGlyphs == 0 || layoutContainsNotdef(layout)) { 481f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return false; // The collection doesn't have a glyph. 482f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 483f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 484f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (nChars == 2 && isFlag(str.get(), str.size())) { 485f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // Some font may have a special glyph for unsupported regional indicator pairs. 486f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // To return false for this case, need to compare the glyph id with the one of ZZ 487f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // since ZZ is reserved for unknown or invalid territory. 488f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // U+1F1FF (REGIONAL INDICATOR SYMBOL LETTER Z) is \uD83C\uDDFF in UTF16. 489f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static const jchar ZZ_FLAG_STR[] = { 0xD83C, 0xDDFF, 0xD83C, 0xDDFF }; 490c7064146f959caec058980ced144942c8044a169Seigo Nonaka minikin::Layout zzLayout = MinikinUtils::doLayout( 491c7064146f959caec058980ced144942c8044a169Seigo Nonaka paint, bidiFlags, typeface, ZZ_FLAG_STR, 0, 4, 4); 492f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (zzLayout.nGlyphs() != 1 || layoutContainsNotdef(zzLayout)) { 493f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // The font collection doesn't have a glyph for unknown flag. Just return true. 494f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return true; 495f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 496f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return zzLayout.getGlyphId(0) != layout.getGlyphId(0); 497f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 498f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return true; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5008451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 501f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat doRunAdvance(const Paint* paint, Typeface* typeface, const jchar buf[], 502f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jint start, jint count, jint bufSize, jboolean isRtl, jint offset) { 503f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck int bidiFlags = isRtl ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR; 504f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (offset == start + count) { 505f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, 506f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck bufSize, nullptr); 507f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 508f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck std::unique_ptr<float[]> advancesArray(new float[count]); 509f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, bufSize, 510f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck advancesArray.get()); 511f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return minikin::getRunAdvance(advancesArray.get(), buf, start, count, offset); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5138451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 514f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat getRunAdvance___CIIIIZI_F(JNIEnv *env, jclass, jlong paintHandle, 515f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jlong typefaceHandle, jcharArray text, jint start, jint end, jint contextStart, 516f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jint contextEnd, jboolean isRtl, jint offset) { 517f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 518f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 519f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jchar* textArray = (jchar*) env->GetPrimitiveArrayCritical(text, nullptr); 520f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jfloat result = doRunAdvance(paint, typeface, textArray + contextStart, 521f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck start - contextStart, end - start, contextEnd - contextStart, isRtl, 522f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck offset - contextStart); 523f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleasePrimitiveArrayCritical(text, textArray, JNI_ABORT); 524f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return result; 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5268451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 527f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint doOffsetForAdvance(const Paint* paint, Typeface* typeface, const jchar buf[], 528f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jint start, jint count, jint bufSize, jboolean isRtl, jfloat advance) { 529f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck int bidiFlags = isRtl ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR; 530f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck std::unique_ptr<float[]> advancesArray(new float[count]); 531f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, bufSize, 532f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck advancesArray.get()); 533f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return minikin::getOffsetForAdvance(advancesArray.get(), buf, start, count, advance); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5358451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 536f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint getOffsetForAdvance___CIIIIZF_I(JNIEnv *env, jclass, jlong paintHandle, 537f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jlong typefaceHandle, jcharArray text, jint start, jint end, jint contextStart, 538f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jint contextEnd, jboolean isRtl, jfloat advance) { 539f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const Paint* paint = reinterpret_cast<Paint*>(paintHandle); 540f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 541f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jchar* textArray = (jchar*) env->GetPrimitiveArrayCritical(text, nullptr); 542f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jint result = doOffsetForAdvance(paint, typeface, textArray + contextStart, 543f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck start - contextStart, end - start, contextEnd - contextStart, isRtl, advance); 544f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck result += contextStart; 545f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->ReleasePrimitiveArrayCritical(text, textArray, JNI_ABORT); 546f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return result; 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5488451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 549f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // ------------------ @FastNative --------------------------- 550f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 551cfc607cf57d453f977c9c4bf09b41ac481c4bbecSeigo Nonaka static jint setTextLocales(JNIEnv* env, jobject clazz, jlong objHandle, jstring locales) { 5526ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* obj = reinterpret_cast<Paint*>(objHandle); 553f036ead2a218ffa43697fcaa999b666a4c6d13cfRoozbeh Pournader ScopedUtfChars localesChars(env, locales); 554ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka jint minikinLangListId = minikin::FontStyle::registerLanguageList(localesChars.c_str()); 555cfc607cf57d453f977c9c4bf09b41ac481c4bbecSeigo Nonaka obj->setMinikinLangListId(minikinLangListId); 556cfc607cf57d453f977c9c4bf09b41ac481c4bbecSeigo Nonaka return minikinLangListId; 557cfc607cf57d453f977c9c4bf09b41ac481c4bbecSeigo Nonaka } 558d7a80774f0a2175f9ee81a7741f9a171c78e0b8bDerek Sollenberger 559805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod static void setFontFeatureSettings(JNIEnv* env, jobject clazz, jlong paintHandle, jstring settings) { 560805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 561e9ad3931fae71c8a8cd000fd52d5df4be79b0895Behdad Esfahbod if (!settings) { 562805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod paint->setFontFeatureSettings(std::string()); 563e9ad3931fae71c8a8cd000fd52d5df4be79b0895Behdad Esfahbod } else { 564805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod ScopedUtfChars settingsChars(env, settings); 565805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod paint->setFontFeatureSettings(std::string(settingsChars.c_str(), settingsChars.size())); 566805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod } 567805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod } 568805f6ebf17e2791624bb1a30834b4c1cc65583bfBehdad Esfahbod 569dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static SkScalar getMetricsInternal(jlong paintHandle, jlong typefaceHandle, 570dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck Paint::FontMetrics *metrics) { 57153c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien const int kElegantTop = 2500; 57253c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien const int kElegantBottom = -1000; 573817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien const int kElegantAscent = 1900; 574817ef4ae79bd39b5e55fc6ca4e3b8e47e114579fRaph Levien const int kElegantDescent = -500; 57553c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien const int kElegantLeading = 0; 576dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 577bad99183916ba2bac6659efc8a28273e344ba511sergeyv Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); 578bad99183916ba2bac6659efc8a28273e344ba511sergeyv typeface = Typeface::resolveDefault(typeface); 579ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka minikin::FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle); 5800627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien float saveSkewX = paint->getTextSkewX(); 5810627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien bool savefakeBold = paint->isFakeBoldText(); 5821fc0fa87d42ce9268ece76b85b9edc834593e53aRaph Levien MinikinFontSkia::populateSkPaint(paint, baseFont.font, baseFont.fakery); 58353c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien SkScalar spacing = paint->getFontMetrics(metrics); 5840627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien // The populateSkPaint call may have changed fake bold / text skew 5850627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien // because we want to measure with those effects applied, so now 5860627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien // restore the original settings. 5870627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien paint->setTextSkewX(saveSkewX); 5880627ec08dcc2e87c17e9b85f045dfb27dc4884b3Raph Levien paint->setFakeBoldText(savefakeBold); 589ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka if (paint->getFontVariant() == minikin::VARIANT_ELEGANT) { 59053c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien SkScalar size = paint->getTextSize(); 59153c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien metrics->fTop = -size * kElegantTop / 2048; 59253c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien metrics->fBottom = -size * kElegantBottom / 2048; 59353c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien metrics->fAscent = -size * kElegantAscent / 2048; 59453c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien metrics->fDescent = -size * kElegantDescent / 2048; 59553c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien metrics->fLeading = size * kElegantLeading / 2048; 59653c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien spacing = metrics->fDescent - metrics->fAscent + metrics->fLeading; 59753c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien } 59853c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien return spacing; 59953c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien } 60053c0077256afebb0312f01ef4f60a7445da1f5d9Raph Levien 601dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jfloat getFontMetrics(JNIEnv* env, jobject, jlong paintHandle, 602dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck jlong typefaceHandle, jobject metricsObj) { 6036ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::FontMetrics metrics; 604dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck SkScalar spacing = getMetricsInternal(paintHandle, typefaceHandle, &metrics); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (metricsObj) { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class)); 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop)); 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent)); 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent)); 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom)); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading)); 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SkScalarToFloat(spacing); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6168451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 617dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck static jint getFontMetricsInt(JNIEnv* env, jobject, jlong paintHandle, 618dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck jlong typefaceHandle, jobject metricsObj) { 6196ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint::FontMetrics metrics; 6208451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 621dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck getMetricsInternal(paintHandle, typefaceHandle, &metrics); 62246cb9bdbf56b27cbf2ab878b41d21e30896a4feaLeon Scroggins int ascent = SkScalarRoundToInt(metrics.fAscent); 62346cb9bdbf56b27cbf2ab878b41d21e30896a4feaLeon Scroggins int descent = SkScalarRoundToInt(metrics.fDescent); 62446cb9bdbf56b27cbf2ab878b41d21e30896a4feaLeon Scroggins int leading = SkScalarRoundToInt(metrics.fLeading); 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 626f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (metricsObj) { 627f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class)); 628f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloorToInt(metrics.fTop)); 629f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent); 630f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent); 631f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeilToInt(metrics.fBottom)); 632f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading); 633f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 634f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return descent - ascent + leading; 635f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 636f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 637f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 638f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // ------------------ @CriticalNative --------------------------- 639f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 640f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void reset(jlong objHandle) { 641f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 642f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck obj->reset(); 643f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck defaultSettingsForAndroid(obj); 644f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 645f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 646f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void assign(jlong dstPaintHandle, jlong srcPaintHandle) { 647f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* dst = reinterpret_cast<Paint*>(dstPaintHandle); 648f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const Paint* src = reinterpret_cast<Paint*>(srcPaintHandle); 649f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck *dst = *src; 650f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 651f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 652f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // Equivalent to the Java Paint's FILTER_BITMAP_FLAG. 653f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static const uint32_t sFilterBitmapFlag = 0x02; 654f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 655f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint getFlags(jlong paintHandle) { 656f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* nativePaint = reinterpret_cast<Paint*>(paintHandle); 657f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck uint32_t result = nativePaint->getFlags(); 658f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck result &= ~sFilterBitmapFlag; // Filtering no longer stored in this bit. Mask away. 659f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (nativePaint->getFilterQuality() != kNone_SkFilterQuality) { 660f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck result |= sFilterBitmapFlag; 661f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 662f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return static_cast<jint>(result); 663f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 664f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 665f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setFlags(jlong paintHandle, jint flags) { 666f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* nativePaint = reinterpret_cast<Paint*>(paintHandle); 667f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // Instead of modifying 0x02, change the filter level. 668f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck nativePaint->setFilterQuality(flags & sFilterBitmapFlag 669f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck ? kLow_SkFilterQuality 670f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck : kNone_SkFilterQuality); 671f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // Don't pass through filter flag, which is no longer stored in paint's flags. 672f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck flags &= ~sFilterBitmapFlag; 673f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // Use the existing value for 0x02. 674f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck const uint32_t existing0x02Flag = nativePaint->getFlags() & sFilterBitmapFlag; 675f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck flags |= existing0x02Flag; 676f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck nativePaint->setFlags(flags); 677f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 678f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 679f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint getHinting(jlong paintHandle) { 680f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return reinterpret_cast<Paint*>(paintHandle)->getHinting() 681f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck == Paint::kNo_Hinting ? 0 : 1; 682f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 683f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 684f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setHinting(jlong paintHandle, jint mode) { 685f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setHinting( 686f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck mode == 0 ? Paint::kNo_Hinting : Paint::kNormal_Hinting); 687f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 688f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 689f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setAntiAlias(jlong paintHandle, jboolean aa) { 690f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setAntiAlias(aa); 691f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 692f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 693f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setLinearText(jlong paintHandle, jboolean linearText) { 694f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setLinearText(linearText); 695f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 696f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 697f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setSubpixelText(jlong paintHandle, jboolean subpixelText) { 698f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setSubpixelText(subpixelText); 699f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 700f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 701f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setUnderlineText(jlong paintHandle, jboolean underlineText) { 702b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed Paint* paint = reinterpret_cast<Paint*>(paintHandle); 703b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed uint32_t flags = paint->getFlags(); 704b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed if (underlineText) { 705b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed flags |= Paint::kUnderlineText_ReserveFlag; 706b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed } else { 707b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed flags &= ~Paint::kUnderlineText_ReserveFlag; 708b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed } 709b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed paint->setFlags(flags); 710f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 711f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 712f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setStrikeThruText(jlong paintHandle, jboolean strikeThruText) { 713b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed Paint* paint = reinterpret_cast<Paint*>(paintHandle); 714b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed uint32_t flags = paint->getFlags(); 715b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed if (strikeThruText) { 716b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed flags |= Paint::kStrikeThruText_ReserveFlag; 717b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed } else { 718b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed flags &= ~Paint::kStrikeThruText_ReserveFlag; 719b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed } 720b216c21acdbcb0e8a2b970d6ff9f72e9bf185623Mike Reed paint->setFlags(flags); 721f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 722f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 723f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setFakeBoldText(jlong paintHandle, jboolean fakeBoldText) { 724f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setFakeBoldText(fakeBoldText); 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 727f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setFilterBitmap(jlong paintHandle, jboolean filterBitmap) { 728f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setFilterQuality( 729f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck filterBitmap ? kLow_SkFilterQuality : kNone_SkFilterQuality); 730f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 7316ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 732f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setDither(jlong paintHandle, jboolean dither) { 733f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setDither(dither); 7340c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 7350c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 736f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint getStyle(jlong objHandle) { 737f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 738f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return static_cast<jint>(obj->getStyle()); 7390c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 7400c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 741f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setStyle(jlong objHandle, jint styleHandle) { 742f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 743f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint::Style style = static_cast<Paint::Style>(styleHandle); 744f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck obj->setStyle(style); 745eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio } 746eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio 747f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint getColor(jlong paintHandle) { 748f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck int color; 749f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck color = reinterpret_cast<Paint*>(paintHandle)->getColor(); 750f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return static_cast<jint>(color); 7510c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 7520c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 753f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint getAlpha(jlong paintHandle) { 754f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck int alpha; 755f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck alpha = reinterpret_cast<Paint*>(paintHandle)->getAlpha(); 756f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return static_cast<jint>(alpha); 7570c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 7580c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 759f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setColor(jlong paintHandle, jint color) { 760f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setColor(color); 7610c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 7620c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 763f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setAlpha(jlong paintHandle, jint a) { 764f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setAlpha(a); 765f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 766f2114d5646194100242206b267ddd6e7194b7da9Raph Levien 767f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat getStrokeWidth(jlong paintHandle) { 768f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return SkScalarToFloat(reinterpret_cast<Paint*>(paintHandle)->getStrokeWidth()); 769f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 770f2114d5646194100242206b267ddd6e7194b7da9Raph Levien 771f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setStrokeWidth(jlong paintHandle, jfloat width) { 772f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setStrokeWidth(width); 773f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 774f2114d5646194100242206b267ddd6e7194b7da9Raph Levien 775f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat getStrokeMiter(jlong paintHandle) { 776f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return SkScalarToFloat(reinterpret_cast<Paint*>(paintHandle)->getStrokeMiter()); 777f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt } 778f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt 779f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setStrokeMiter(jlong paintHandle, jfloat miter) { 780f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setStrokeMiter(miter); 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 782f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt 783f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint getStrokeCap(jlong objHandle) { 784f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 785f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return static_cast<jint>(obj->getStrokeCap()); 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 787f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt 788f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setStrokeCap(jlong objHandle, jint capHandle) { 789f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 790f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint::Cap cap = static_cast<Paint::Cap>(capHandle); 791f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck obj->setStrokeCap(cap); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 794f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint getStrokeJoin(jlong objHandle) { 795f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 796f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return static_cast<jint>(obj->getStrokeJoin()); 797c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger } 798c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger 799f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setStrokeJoin(jlong objHandle, jint joinHandle) { 800f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 801f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint::Join join = (Paint::Join) joinHandle; 802f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck obj->setStrokeJoin(join); 803f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 804a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye 805f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jboolean getFillPath(jlong objHandle, jlong srcHandle, jlong dstHandle) { 806f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 807f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkPath* src = reinterpret_cast<SkPath*>(srcHandle); 808f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkPath* dst = reinterpret_cast<SkPath*>(dstHandle); 809f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE; 810f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 81157c4fed236cbec0944824b534fb9c828ac0d1f81Derek Sollenberger 812f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jlong setShader(jlong objHandle, jlong shaderHandle) { 813f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 814f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); 815260ab726486317496bc12a57d599ea96dcde3284Mike Reed obj->setShader(sk_ref_sp(shader)); 816260ab726486317496bc12a57d599ea96dcde3284Mike Reed return reinterpret_cast<jlong>(obj->getShader()); 817f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jlong setColorFilter(jlong objHandle, jlong filterHandle) { 820f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint *>(objHandle); 821f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(filterHandle); 822260ab726486317496bc12a57d599ea96dcde3284Mike Reed obj->setColorFilter(sk_ref_sp(filter)); 823260ab726486317496bc12a57d599ea96dcde3284Mike Reed return reinterpret_cast<jlong>(obj->getColorFilter()); 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 826f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setXfermode(jlong paintHandle, jint xfermodeHandle) { 827f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // validate that the Java enum values match our expectations 828260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(0 == static_cast<int>(SkBlendMode::kClear), "xfermode_mismatch"); 829260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(1 == static_cast<int>(SkBlendMode::kSrc), "xfermode_mismatch"); 830260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(2 == static_cast<int>(SkBlendMode::kDst), "xfermode_mismatch"); 831260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(3 == static_cast<int>(SkBlendMode::kSrcOver), "xfermode_mismatch"); 832260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(4 == static_cast<int>(SkBlendMode::kDstOver), "xfermode_mismatch"); 833260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(5 == static_cast<int>(SkBlendMode::kSrcIn), "xfermode_mismatch"); 834260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(6 == static_cast<int>(SkBlendMode::kDstIn), "xfermode_mismatch"); 835260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(7 == static_cast<int>(SkBlendMode::kSrcOut), "xfermode_mismatch"); 836260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(8 == static_cast<int>(SkBlendMode::kDstOut), "xfermode_mismatch"); 837260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(9 == static_cast<int>(SkBlendMode::kSrcATop), "xfermode_mismatch"); 838260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(10 == static_cast<int>(SkBlendMode::kDstATop), "xfermode_mismatch"); 839260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(11 == static_cast<int>(SkBlendMode::kXor), "xfermode_mismatch"); 840260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(16 == static_cast<int>(SkBlendMode::kDarken), "xfermode_mismatch"); 841260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(17 == static_cast<int>(SkBlendMode::kLighten), "xfermode_mismatch"); 842260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(13 == static_cast<int>(SkBlendMode::kModulate), "xfermode_mismatch"); 843260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(14 == static_cast<int>(SkBlendMode::kScreen), "xfermode_mismatch"); 844260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(12 == static_cast<int>(SkBlendMode::kPlus), "xfermode_mismatch"); 845260ab726486317496bc12a57d599ea96dcde3284Mike Reed static_assert(15 == static_cast<int>(SkBlendMode::kOverlay), "xfermode_mismatch"); 846260ab726486317496bc12a57d599ea96dcde3284Mike Reed 847260ab726486317496bc12a57d599ea96dcde3284Mike Reed SkBlendMode mode = static_cast<SkBlendMode>(xfermodeHandle); 8486ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod Paint* paint = reinterpret_cast<Paint*>(paintHandle); 849260ab726486317496bc12a57d599ea96dcde3284Mike Reed paint->setBlendMode(mode); 850f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 851a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye 852f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jlong setPathEffect(jlong objHandle, jlong effectHandle) { 853f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 854f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkPathEffect* effect = reinterpret_cast<SkPathEffect*>(effectHandle); 855260ab726486317496bc12a57d599ea96dcde3284Mike Reed obj->setPathEffect(sk_ref_sp(effect)); 856260ab726486317496bc12a57d599ea96dcde3284Mike Reed return reinterpret_cast<jlong>(obj->getPathEffect()); 857f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jlong setMaskFilter(jlong objHandle, jlong maskfilterHandle) { 860f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 861f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkMaskFilter* maskfilter = reinterpret_cast<SkMaskFilter*>(maskfilterHandle); 862260ab726486317496bc12a57d599ea96dcde3284Mike Reed obj->setMaskFilter(sk_ref_sp(maskfilter)); 863260ab726486317496bc12a57d599ea96dcde3284Mike Reed return reinterpret_cast<jlong>(obj->getMaskFilter()); 864f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 866f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jlong setTypeface(jlong objHandle, jlong typefaceHandle) { 867f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // TODO: in Paint refactoring, set typeface on android Paint, not Paint 868f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return 0; 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 871f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint getTextAlign(jlong objHandle) { 872f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 873f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return static_cast<jint>(obj->getTextAlign()); 874f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 875a7aa1b0aa566b2ff310cb89fbc9437de4819f583Anish Athalye 876f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setTextAlign(jlong objHandle, jint alignHandle) { 877f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 878f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint::Align align = static_cast<Paint::Align>(alignHandle); 879f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck obj->setTextAlign(align); 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 882f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setTextLocalesByMinikinLangListId(jlong objHandle, 883f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jint minikinLangListId) { 884f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(objHandle); 885f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck obj->setMinikinLangListId(minikinLangListId); 886f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 8878451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 888f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jboolean isElegantTextHeight(jlong paintHandle) { 889f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(paintHandle); 890f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return obj->getFontVariant() == minikin::VARIANT_ELEGANT; 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 893f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setElegantTextHeight(jlong paintHandle, jboolean aa) { 894f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* obj = reinterpret_cast<Paint*>(paintHandle); 895f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck obj->setFontVariant(aa ? minikin::VARIANT_ELEGANT : minikin::VARIANT_DEFAULT); 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8978451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 898f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat getTextSize(jlong paintHandle) { 899f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return SkScalarToFloat(reinterpret_cast<Paint*>(paintHandle)->getTextSize()); 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9018451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 902f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setTextSize(jlong paintHandle, jfloat textSize) { 903f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setTextSize(textSize); 904f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 905f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien 906f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat getTextScaleX(jlong paintHandle) { 907f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return SkScalarToFloat(reinterpret_cast<Paint*>(paintHandle)->getTextScaleX()); 9086141db3846356efbdea093756701c89bd5155421Raph Levien } 9096141db3846356efbdea093756701c89bd5155421Raph Levien 910f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setTextScaleX(jlong paintHandle, jfloat scaleX) { 911f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setTextScaleX(scaleX); 912f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 913589cddc034f87fcd02adb24e168ef6b2ed851b82Seigo Nonaka 914f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat getTextSkewX(jlong paintHandle) { 915f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return SkScalarToFloat(reinterpret_cast<Paint*>(paintHandle)->getTextSkewX()); 916589cddc034f87fcd02adb24e168ef6b2ed851b82Seigo Nonaka } 917589cddc034f87fcd02adb24e168ef6b2ed851b82Seigo Nonaka 918f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setTextSkewX(jlong paintHandle, jfloat skewX) { 919f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck reinterpret_cast<Paint*>(paintHandle)->setTextSkewX(skewX); 920f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 921f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien 922f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat getLetterSpacing(jlong paintHandle) { 923f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 924f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return paint->getLetterSpacing(); 925f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 926bb1a96647a82df5a134bf631fc9db342e7ef61deSeigo Nonaka 927f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setLetterSpacing(jlong paintHandle, jfloat letterSpacing) { 928f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 929f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck paint->setLetterSpacing(letterSpacing); 930f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 931589cddc034f87fcd02adb24e168ef6b2ed851b82Seigo Nonaka 932219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka static jfloat getWordSpacing(jlong paintHandle) { 933219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka Paint* paint = reinterpret_cast<Paint*>(paintHandle); 934219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka return paint->getWordSpacing(); 935219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka } 936219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka 937219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka static void setWordSpacing(jlong paintHandle, jfloat wordSpacing) { 938219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka Paint* paint = reinterpret_cast<Paint*>(paintHandle); 939219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka paint->setWordSpacing(wordSpacing); 940219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka } 941219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka 942f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jint getHyphenEdit(jlong paintHandle, jint hyphen) { 943f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 944f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return paint->getHyphenEdit(); 945f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 946589cddc034f87fcd02adb24e168ef6b2ed851b82Seigo Nonaka 947f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setHyphenEdit(jlong paintHandle, jint hyphen) { 948f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 949f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck paint->setHyphenEdit((uint32_t)hyphen); 950f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien } 951f7f969e67e9ab420404807b1b103dcd18d7aa7b7Raph Levien 952f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat ascent(jlong paintHandle, jlong typefaceHandle) { 953f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint::FontMetrics metrics; 954f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck getMetricsInternal(paintHandle, typefaceHandle, &metrics); 955f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return SkScalarToFloat(metrics.fAscent); 956a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien } 957a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien 958f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jfloat descent(jlong paintHandle, jlong typefaceHandle) { 959f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint::FontMetrics metrics; 960f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck getMetricsInternal(paintHandle, typefaceHandle, &metrics); 961f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return SkScalarToFloat(metrics.fDescent); 962a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien } 963a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien 964ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader static jfloat getUnderlinePosition(jlong paintHandle, jlong typefaceHandle) { 965ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader Paint::FontMetrics metrics; 966ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader getMetricsInternal(paintHandle, typefaceHandle, &metrics); 967ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader SkScalar position; 968ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader if (metrics.hasUnderlinePosition(&position)) { 969ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader return SkScalarToFloat(position); 970ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader } else { 971ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader const SkScalar textSize = reinterpret_cast<Paint*>(paintHandle)->getTextSize(); 972ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader return SkScalarToFloat(Paint::kStdUnderline_Top * textSize); 973ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader } 974ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader } 975ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader 976ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader static jfloat getUnderlineThickness(jlong paintHandle, jlong typefaceHandle) { 977ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader Paint::FontMetrics metrics; 978ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader getMetricsInternal(paintHandle, typefaceHandle, &metrics); 979ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader SkScalar thickness; 980ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader if (metrics.hasUnderlineThickness(&thickness)) { 981ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader return SkScalarToFloat(thickness); 982ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader } else { 983ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader const SkScalar textSize = reinterpret_cast<Paint*>(paintHandle)->getTextSize(); 984ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader return SkScalarToFloat(Paint::kStdUnderline_Thickness * textSize); 985ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader } 986ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader } 987ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader 9881378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader static jfloat getStrikeThruPosition(jlong paintHandle, jlong typefaceHandle) { 9891378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader const SkScalar textSize = reinterpret_cast<Paint*>(paintHandle)->getTextSize(); 9901378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader return SkScalarToFloat(Paint::kStdStrikeThru_Top * textSize); 9911378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader } 9921378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader 9931378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader static jfloat getStrikeThruThickness(jlong paintHandle, jlong typefaceHandle) { 9941378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader const SkScalar textSize = reinterpret_cast<Paint*>(paintHandle)->getTextSize(); 9951378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader return SkScalarToFloat(Paint::kStdStrikeThru_Thickness * textSize); 9961378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader } 9971378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader 998f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static void setShadowLayer(jlong paintHandle, jfloat radius, 999f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck jfloat dx, jfloat dy, jint color) { 1000f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 1001f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck if (radius <= 0) { 1002f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck paint->setLooper(nullptr); 1003f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 1004f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck else { 1005f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck SkScalar sigma = android::uirenderer::Blur::convertRadiusToSigma(radius); 1006260ab726486317496bc12a57d599ea96dcde3284Mike Reed paint->setLooper(SkBlurDrawLooper::Make((SkColor)color, sigma, dx, dy)); 1007f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck } 1008a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien } 10094c8a52647814badd361ebd13813180b8db9b923eKeisuke Kuroyanagi 1010f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck static jboolean hasShadowLayer(jlong paintHandle) { 1011f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck Paint* paint = reinterpret_cast<Paint*>(paintHandle); 1012f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck return paint->getLooper() && paint->getLooper()->asABlurShadow(nullptr); 1013a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien } 1014a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien 1015dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck}; // namespace PaintGlue 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 101776f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod methods[] = { 1018775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler {"nGetNativeFinalizer", "()J", (void*) PaintGlue::getNativeFinalizer}, 1019dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nInit","()J", (void*) PaintGlue::init}, 1020dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nInitWithPaint","(J)J", (void*) PaintGlue::initWithPaint}, 1021dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nBreakText","(JJ[CIIFI[F)I", (void*) PaintGlue::breakTextC}, 1022dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nBreakText","(JJLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS}, 1023dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextAdvances","(JJ[CIIIII[FI)F", 1024536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi (void*) PaintGlue::getTextAdvances___CIIIII_FI}, 1025dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextAdvances","(JJLjava/lang/String;IIIII[FI)F", 1026536afe6ef79a663e59c3b9781c561f7029ee9319Keisuke Kuroyanagi (void*) PaintGlue::getTextAdvances__StringIIIII_FI}, 1027da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio 10285d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader {"nGetTextRunCursor", "(JJ[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C}, 10295d74b1c76f5da4510a1d70d8d3b0e8c15765f231Roozbeh Pournader {"nGetTextRunCursor", "(JJLjava/lang/String;IIIII)I", 1030a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*) PaintGlue::getTextRunCursor__String}, 1031dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextPath", "(JJI[CIIFFJ)V", (void*) PaintGlue::getTextPath___C}, 1032dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetTextPath", "(JJILjava/lang/String;IIFFJ)V", (void*) PaintGlue::getTextPath__String}, 1033dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetStringBounds", "(JJLjava/lang/String;IIILandroid/graphics/Rect;)V", 1034a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*) PaintGlue::getStringBounds }, 1035dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V", 1036a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*) PaintGlue::getCharArrayBounds }, 1037dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nHasGlyph", "(JJILjava/lang/String;)Z", (void*) PaintGlue::hasGlyph }, 1038dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetRunAdvance", "(JJ[CIIIIZI)F", (void*) PaintGlue::getRunAdvance___CIIIIZI_F}, 1039dbffd250003e60c0f11ac3ad2b63f91f67962610John Reck {"nGetOffsetForAdvance", "(JJ[CIIIIZF)I", 1040a027ec5c2dbfbbf10cac9ea538f5e230b093be2fRaph Levien (void*) PaintGlue::getOffsetForAdvance___CIIIIZF_I}, 10414136a0aeac9bb95aa615d4fc1f12378829d26c80Chris Craik 1042f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // --------------- @FastNative ---------------------- 1043f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 1044f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetTextLocales","(JLjava/lang/String;)I", (void*) PaintGlue::setTextLocales}, 1045f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetFontFeatureSettings","(JLjava/lang/String;)V", 1046f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck (void*) PaintGlue::setFontFeatureSettings}, 1047f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetFontMetrics", "(JJLandroid/graphics/Paint$FontMetrics;)F", 1048f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck (void*)PaintGlue::getFontMetrics}, 1049f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetFontMetricsInt", "(JJLandroid/graphics/Paint$FontMetricsInt;)I", 1050f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck (void*)PaintGlue::getFontMetricsInt}, 1051f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 1052f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck // --------------- @CriticalNative ------------------ 1053f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck 1054f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nReset","(J)V", (void*) PaintGlue::reset}, 1055f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSet","(JJ)V", (void*) PaintGlue::assign}, 1056f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetFlags","(J)I", (void*) PaintGlue::getFlags}, 1057f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetFlags","(JI)V", (void*) PaintGlue::setFlags}, 1058f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetHinting","(J)I", (void*) PaintGlue::getHinting}, 1059f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetHinting","(JI)V", (void*) PaintGlue::setHinting}, 1060f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetAntiAlias","(JZ)V", (void*) PaintGlue::setAntiAlias}, 1061f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetSubpixelText","(JZ)V", (void*) PaintGlue::setSubpixelText}, 1062f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetLinearText","(JZ)V", (void*) PaintGlue::setLinearText}, 1063f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetUnderlineText","(JZ)V", (void*) PaintGlue::setUnderlineText}, 1064f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetStrikeThruText","(JZ)V", (void*) PaintGlue::setStrikeThruText}, 1065f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetFakeBoldText","(JZ)V", (void*) PaintGlue::setFakeBoldText}, 1066f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetFilterBitmap","(JZ)V", (void*) PaintGlue::setFilterBitmap}, 1067f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetDither","(JZ)V", (void*) PaintGlue::setDither}, 1068f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetStyle","(J)I", (void*) PaintGlue::getStyle}, 1069f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetStyle","(JI)V", (void*) PaintGlue::setStyle}, 1070f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetColor","(J)I", (void*) PaintGlue::getColor}, 1071f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetColor","(JI)V", (void*) PaintGlue::setColor}, 1072f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetAlpha","(J)I", (void*) PaintGlue::getAlpha}, 1073f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetAlpha","(JI)V", (void*) PaintGlue::setAlpha}, 1074f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetStrokeWidth","(J)F", (void*) PaintGlue::getStrokeWidth}, 1075f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetStrokeWidth","(JF)V", (void*) PaintGlue::setStrokeWidth}, 1076f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetStrokeMiter","(J)F", (void*) PaintGlue::getStrokeMiter}, 1077f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetStrokeMiter","(JF)V", (void*) PaintGlue::setStrokeMiter}, 1078f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetStrokeCap","(J)I", (void*) PaintGlue::getStrokeCap}, 1079f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetStrokeCap","(JI)V", (void*) PaintGlue::setStrokeCap}, 1080f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetStrokeJoin","(J)I", (void*) PaintGlue::getStrokeJoin}, 1081f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetStrokeJoin","(JI)V", (void*) PaintGlue::setStrokeJoin}, 1082f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetFillPath","(JJJ)Z", (void*) PaintGlue::getFillPath}, 1083f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetShader","(JJ)J", (void*) PaintGlue::setShader}, 1084f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetColorFilter","(JJ)J", (void*) PaintGlue::setColorFilter}, 1085f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetXfermode","(JI)V", (void*) PaintGlue::setXfermode}, 1086f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetPathEffect","(JJ)J", (void*) PaintGlue::setPathEffect}, 1087f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetMaskFilter","(JJ)J", (void*) PaintGlue::setMaskFilter}, 1088f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetTypeface","(JJ)J", (void*) PaintGlue::setTypeface}, 1089f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetTextAlign","(J)I", (void*) PaintGlue::getTextAlign}, 1090f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetTextAlign","(JI)V", (void*) PaintGlue::setTextAlign}, 1091f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetTextLocalesByMinikinLangListId","(JI)V", 1092f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck (void*) PaintGlue::setTextLocalesByMinikinLangListId}, 1093f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nIsElegantTextHeight","(J)Z", (void*) PaintGlue::isElegantTextHeight}, 1094f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetElegantTextHeight","(JZ)V", (void*) PaintGlue::setElegantTextHeight}, 1095f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetTextSize","(J)F", (void*) PaintGlue::getTextSize}, 1096f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetTextSize","(JF)V", (void*) PaintGlue::setTextSize}, 1097f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetTextScaleX","(J)F", (void*) PaintGlue::getTextScaleX}, 1098f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetTextScaleX","(JF)V", (void*) PaintGlue::setTextScaleX}, 1099f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetTextSkewX","(J)F", (void*) PaintGlue::getTextSkewX}, 1100f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetTextSkewX","(JF)V", (void*) PaintGlue::setTextSkewX}, 1101f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing}, 1102f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing}, 1103219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka {"nGetWordSpacing","(J)F", (void*) PaintGlue::getWordSpacing}, 1104219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka {"nSetWordSpacing","(JF)V", (void*) PaintGlue::setWordSpacing}, 1105f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nGetHyphenEdit", "(J)I", (void*) PaintGlue::getHyphenEdit}, 1106f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetHyphenEdit", "(JI)V", (void*) PaintGlue::setHyphenEdit}, 1107f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nAscent","(JJ)F", (void*) PaintGlue::ascent}, 1108f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nDescent","(JJ)F", (void*) PaintGlue::descent}, 1109ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader {"nGetUnderlinePosition","(JJ)F", (void*) PaintGlue::getUnderlinePosition}, 1110ca8a04a36640eb227a556ad9ced925c48ced2495Roozbeh Pournader {"nGetUnderlineThickness","(JJ)F", (void*) PaintGlue::getUnderlineThickness}, 11111378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader {"nGetStrikeThruPosition","(JJ)F", (void*) PaintGlue::getStrikeThruPosition}, 11121378a9d72cb4a9f7a939f0a28a78fcfb87fb7879Roozbeh Pournader {"nGetStrikeThruThickness","(JJ)F", (void*) PaintGlue::getStrikeThruThickness}, 1113f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nSetShadowLayer", "(JFFFI)V", (void*)PaintGlue::setShadowLayer}, 1114f22859757b7981cdb3e05579bbb5f782965b5ca9John Reck {"nHasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer} 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_graphics_Paint(JNIEnv* env) { 1118ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_class = FindClassOrDie(env, "android/graphics/Paint$FontMetrics"); 1119ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_class = MakeGlobalRefOrDie(env, gFontMetrics_class); 1120ab22c1c792bc5f422a029a4ab6a23861e44136d8Derek Sollenberger 1121ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_fieldID.top = GetFieldIDOrDie(env, gFontMetrics_class, "top", "F"); 1122ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_fieldID.ascent = GetFieldIDOrDie(env, gFontMetrics_class, "ascent", "F"); 1123ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_fieldID.descent = GetFieldIDOrDie(env, gFontMetrics_class, "descent", "F"); 1124ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_fieldID.bottom = GetFieldIDOrDie(env, gFontMetrics_class, "bottom", "F"); 1125ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetrics_fieldID.leading = GetFieldIDOrDie(env, gFontMetrics_class, "leading", "F"); 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1127ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_class = FindClassOrDie(env, "android/graphics/Paint$FontMetricsInt"); 1128ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_class = MakeGlobalRefOrDie(env, gFontMetricsInt_class); 1129ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 1130ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_fieldID.top = GetFieldIDOrDie(env, gFontMetricsInt_class, "top", "I"); 1131ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_fieldID.ascent = GetFieldIDOrDie(env, gFontMetricsInt_class, "ascent", "I"); 1132ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_fieldID.descent = GetFieldIDOrDie(env, gFontMetricsInt_class, "descent", "I"); 1133ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_fieldID.bottom = GetFieldIDOrDie(env, gFontMetricsInt_class, "bottom", "I"); 1134ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe gFontMetricsInt_fieldID.leading = GetFieldIDOrDie(env, gFontMetricsInt_class, "leading", "I"); 1135ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 1136ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return RegisterMethodsOrDie(env, "android/graphics/Paint", methods, NELEM(methods)); 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1140