diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 315dd6bf32df7..4b1530a17e8f8 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -105,392 +105,80 @@ namespace PaintGlue { return reinterpret_cast(obj); } - static void reset(JNIEnv* env, jobject clazz, jlong objHandle) { - Paint* obj = reinterpret_cast(objHandle); - obj->reset(); - defaultSettingsForAndroid(obj); - } + static int breakText(JNIEnv* env, const Paint& paint, Typeface* typeface, const jchar text[], + int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured, + const bool forwardScan) { + size_t measuredCount = 0; + float measured = 0; - static void assign(JNIEnv* env, jobject clazz, jlong dstPaintHandle, jlong srcPaintHandle) { - Paint* dst = reinterpret_cast(dstPaintHandle); - const Paint* src = reinterpret_cast(srcPaintHandle); - *dst = *src; - } + std::unique_ptr advancesArray(new float[count]); + MinikinUtils::measureText(&paint, bidiFlags, typeface, text, 0, count, count, + advancesArray.get()); - // Equivalent to the Java Paint's FILTER_BITMAP_FLAG. - static const uint32_t sFilterBitmapFlag = 0x02; - - static jint getFlags(JNIEnv* env, jobject, jlong paintHandle) { - Paint* nativePaint = reinterpret_cast(paintHandle); - uint32_t result = nativePaint->getFlags(); - result &= ~sFilterBitmapFlag; // Filtering no longer stored in this bit. Mask away. - if (nativePaint->getFilterQuality() != kNone_SkFilterQuality) { - result |= sFilterBitmapFlag; + for (int i = 0; i < count; i++) { + // traverse in the given direction + int index = forwardScan ? i : (count - i - 1); + float width = advancesArray[index]; + if (measured + width > maxWidth) { + break; + } + // properly handle clusters when scanning backwards + if (forwardScan || width != 0.0f) { + measuredCount = i + 1; + } + measured += width; } - return static_cast(result); - } - static void setFlags(JNIEnv* env, jobject, jlong paintHandle, jint flags) { - Paint* nativePaint = reinterpret_cast(paintHandle); - // Instead of modifying 0x02, change the filter level. - nativePaint->setFilterQuality(flags & sFilterBitmapFlag - ? kLow_SkFilterQuality - : kNone_SkFilterQuality); - // Don't pass through filter flag, which is no longer stored in paint's flags. - flags &= ~sFilterBitmapFlag; - // Use the existing value for 0x02. - const uint32_t existing0x02Flag = nativePaint->getFlags() & sFilterBitmapFlag; - flags |= existing0x02Flag; - nativePaint->setFlags(flags); - } - - static jint getHinting(JNIEnv* env, jobject, jlong paintHandle) { - return reinterpret_cast(paintHandle)->getHinting() - == Paint::kNo_Hinting ? 0 : 1; - } - - static void setHinting(JNIEnv* env, jobject, jlong paintHandle, jint mode) { - reinterpret_cast(paintHandle)->setHinting( - mode == 0 ? Paint::kNo_Hinting : Paint::kNormal_Hinting); - } - - static void setAntiAlias(JNIEnv* env, jobject, jlong paintHandle, jboolean aa) { - reinterpret_cast(paintHandle)->setAntiAlias(aa); - } - - static void setLinearText(JNIEnv* env, jobject, jlong paintHandle, jboolean linearText) { - reinterpret_cast(paintHandle)->setLinearText(linearText); - } - - static void setSubpixelText(JNIEnv* env, jobject, jlong paintHandle, jboolean subpixelText) { - reinterpret_cast(paintHandle)->setSubpixelText(subpixelText); - } - - static void setUnderlineText(JNIEnv* env, jobject, jlong paintHandle, jboolean underlineText) { - reinterpret_cast(paintHandle)->setUnderlineText(underlineText); - } - - static void setStrikeThruText(JNIEnv* env, jobject, jlong paintHandle, jboolean strikeThruText) { - reinterpret_cast(paintHandle)->setStrikeThruText(strikeThruText); - } - - static void setFakeBoldText(JNIEnv* env, jobject, jlong paintHandle, jboolean fakeBoldText) { - reinterpret_cast(paintHandle)->setFakeBoldText(fakeBoldText); - } - - static void setFilterBitmap(JNIEnv* env, jobject, jlong paintHandle, jboolean filterBitmap) { - reinterpret_cast(paintHandle)->setFilterQuality( - filterBitmap ? kLow_SkFilterQuality : kNone_SkFilterQuality); - } - - static void setDither(JNIEnv* env, jobject, jlong paintHandle, jboolean dither) { - reinterpret_cast(paintHandle)->setDither(dither); - } - - static jint getStyle(JNIEnv* env, jobject clazz,jlong objHandle) { - Paint* obj = reinterpret_cast(objHandle); - return static_cast(obj->getStyle()); - } - - static void setStyle(JNIEnv* env, jobject clazz, jlong objHandle, jint styleHandle) { - Paint* obj = reinterpret_cast(objHandle); - Paint::Style style = static_cast(styleHandle); - obj->setStyle(style); - } - - static jint getColor(JNIEnv* env, jobject, jlong paintHandle) { - int color; - color = reinterpret_cast(paintHandle)->getColor(); - return static_cast(color); - } - - static jint getAlpha(JNIEnv* env, jobject, jlong paintHandle) { - int alpha; - alpha = reinterpret_cast(paintHandle)->getAlpha(); - return static_cast(alpha); - } - - static void setColor(JNIEnv* env, jobject, jlong paintHandle, jint color) { - reinterpret_cast(paintHandle)->setColor(color); - } - - static void setAlpha(JNIEnv* env, jobject, jlong paintHandle, jint a) { - reinterpret_cast(paintHandle)->setAlpha(a); - } - - static jfloat getStrokeWidth(JNIEnv* env, jobject, jlong paintHandle) { - return SkScalarToFloat(reinterpret_cast(paintHandle)->getStrokeWidth()); - } - - static void setStrokeWidth(JNIEnv* env, jobject, jlong paintHandle, jfloat width) { - reinterpret_cast(paintHandle)->setStrokeWidth(width); - } - - static jfloat getStrokeMiter(JNIEnv* env, jobject, jlong paintHandle) { - return SkScalarToFloat(reinterpret_cast(paintHandle)->getStrokeMiter()); - } - - static void setStrokeMiter(JNIEnv* env, jobject, jlong paintHandle, jfloat miter) { - reinterpret_cast(paintHandle)->setStrokeMiter(miter); - } - - static jint getStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle) { - Paint* obj = reinterpret_cast(objHandle); - return static_cast(obj->getStrokeCap()); - } - - static void setStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle, jint capHandle) { - Paint* obj = reinterpret_cast(objHandle); - Paint::Cap cap = static_cast(capHandle); - obj->setStrokeCap(cap); - } - - static jint getStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle) { - Paint* obj = reinterpret_cast(objHandle); - return static_cast(obj->getStrokeJoin()); - } - - static void setStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle, jint joinHandle) { - Paint* obj = reinterpret_cast(objHandle); - Paint::Join join = (Paint::Join) joinHandle; - obj->setStrokeJoin(join); - } - - static jboolean getFillPath(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jlong dstHandle) { - Paint* obj = reinterpret_cast(objHandle); - SkPath* src = reinterpret_cast(srcHandle); - SkPath* dst = reinterpret_cast(dstHandle); - return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE; - } - - static jlong setShader(JNIEnv* env, jobject clazz, jlong objHandle, jlong shaderHandle) { - Paint* obj = reinterpret_cast(objHandle); - SkShader* shader = reinterpret_cast(shaderHandle); - return reinterpret_cast(obj->setShader(shader)); - } - - static jlong setColorFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong filterHandle) { - Paint* obj = reinterpret_cast(objHandle); - SkColorFilter* filter = reinterpret_cast(filterHandle); - return reinterpret_cast(obj->setColorFilter(filter)); - } - - static void setXfermode(JNIEnv* env, jobject clazz, jlong paintHandle, jint xfermodeHandle) { - // validate that the Java enum values match our expectations - static_assert(0 == SkXfermode::kClear_Mode, "xfermode_mismatch"); - static_assert(1 == SkXfermode::kSrc_Mode, "xfermode_mismatch"); - static_assert(2 == SkXfermode::kDst_Mode, "xfermode_mismatch"); - static_assert(3 == SkXfermode::kSrcOver_Mode, "xfermode_mismatch"); - static_assert(4 == SkXfermode::kDstOver_Mode, "xfermode_mismatch"); - static_assert(5 == SkXfermode::kSrcIn_Mode, "xfermode_mismatch"); - static_assert(6 == SkXfermode::kDstIn_Mode, "xfermode_mismatch"); - static_assert(7 == SkXfermode::kSrcOut_Mode, "xfermode_mismatch"); - static_assert(8 == SkXfermode::kDstOut_Mode, "xfermode_mismatch"); - static_assert(9 == SkXfermode::kSrcATop_Mode, "xfermode_mismatch"); - static_assert(10 == SkXfermode::kDstATop_Mode, "xfermode_mismatch"); - static_assert(11 == SkXfermode::kXor_Mode, "xfermode_mismatch"); - static_assert(16 == SkXfermode::kDarken_Mode, "xfermode_mismatch"); - static_assert(17 == SkXfermode::kLighten_Mode, "xfermode_mismatch"); - static_assert(13 == SkXfermode::kModulate_Mode, "xfermode_mismatch"); - static_assert(14 == SkXfermode::kScreen_Mode, "xfermode_mismatch"); - static_assert(12 == SkXfermode::kPlus_Mode, "xfermode_mismatch"); - static_assert(15 == SkXfermode::kOverlay_Mode, "xfermode_mismatch"); - - SkXfermode::Mode mode = static_cast(xfermodeHandle); - Paint* paint = reinterpret_cast(paintHandle); - paint->setXfermodeMode(mode); - } - - static jlong setPathEffect(JNIEnv* env, jobject clazz, jlong objHandle, jlong effectHandle) { - Paint* obj = reinterpret_cast(objHandle); - SkPathEffect* effect = reinterpret_cast(effectHandle); - return reinterpret_cast(obj->setPathEffect(effect)); - } - - static jlong setMaskFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong maskfilterHandle) { - Paint* obj = reinterpret_cast(objHandle); - SkMaskFilter* maskfilter = reinterpret_cast(maskfilterHandle); - return reinterpret_cast(obj->setMaskFilter(maskfilter)); - } - - static jlong setTypeface(JNIEnv* env, jobject clazz, jlong objHandle, jlong typefaceHandle) { - // TODO: in Paint refactoring, set typeface on android Paint, not Paint - return NULL; - } - - static jlong setRasterizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong rasterizerHandle) { - Paint* obj = reinterpret_cast(objHandle); - SkAutoTUnref rasterizer(GraphicsJNI::refNativeRasterizer(rasterizerHandle)); - return reinterpret_cast(obj->setRasterizer(rasterizer)); - } - - static jint getTextAlign(JNIEnv* env, jobject clazz, jlong objHandle) { - Paint* obj = reinterpret_cast(objHandle); - return static_cast(obj->getTextAlign()); - } - - static void setTextAlign(JNIEnv* env, jobject clazz, jlong objHandle, jint alignHandle) { - Paint* obj = reinterpret_cast(objHandle); - Paint::Align align = static_cast(alignHandle); - obj->setTextAlign(align); - } - - static jint setTextLocales(JNIEnv* env, jobject clazz, jlong objHandle, jstring locales) { - Paint* obj = reinterpret_cast(objHandle); - ScopedUtfChars localesChars(env, locales); - jint minikinLangListId = minikin::FontStyle::registerLanguageList(localesChars.c_str()); - obj->setMinikinLangListId(minikinLangListId); - return minikinLangListId; - } - - static void setTextLocalesByMinikinLangListId(JNIEnv* env, jobject clazz, jlong objHandle, - jint minikinLangListId) { - Paint* obj = reinterpret_cast(objHandle); - obj->setMinikinLangListId(minikinLangListId); - } - - static jboolean isElegantTextHeight(JNIEnv* env, jobject, jlong paintHandle) { - Paint* obj = reinterpret_cast(paintHandle); - return obj->getFontVariant() == minikin::VARIANT_ELEGANT; - } - - static void setElegantTextHeight(JNIEnv* env, jobject, jlong paintHandle, jboolean aa) { - Paint* obj = reinterpret_cast(paintHandle); - obj->setFontVariant(aa ? minikin::VARIANT_ELEGANT : minikin::VARIANT_DEFAULT); - } - - static jfloat getTextSize(JNIEnv* env, jobject, jlong paintHandle) { - return SkScalarToFloat(reinterpret_cast(paintHandle)->getTextSize()); - } - - static void setTextSize(JNIEnv* env, jobject, jlong paintHandle, jfloat textSize) { - reinterpret_cast(paintHandle)->setTextSize(textSize); - } - - static jfloat getTextScaleX(JNIEnv* env, jobject, jlong paintHandle) { - return SkScalarToFloat(reinterpret_cast(paintHandle)->getTextScaleX()); - } - - static void setTextScaleX(JNIEnv* env, jobject, jlong paintHandle, jfloat scaleX) { - reinterpret_cast(paintHandle)->setTextScaleX(scaleX); - } - - static jfloat getTextSkewX(JNIEnv* env, jobject, jlong paintHandle) { - return SkScalarToFloat(reinterpret_cast(paintHandle)->getTextSkewX()); - } - - static void setTextSkewX(JNIEnv* env, jobject, jlong paintHandle, jfloat skewX) { - reinterpret_cast(paintHandle)->setTextSkewX(skewX); - } - - static jfloat getLetterSpacing(JNIEnv* env, jobject clazz, jlong paintHandle) { - Paint* paint = reinterpret_cast(paintHandle); - return paint->getLetterSpacing(); - } - - static void setLetterSpacing(JNIEnv* env, jobject clazz, jlong paintHandle, jfloat letterSpacing) { - Paint* paint = reinterpret_cast(paintHandle); - paint->setLetterSpacing(letterSpacing); - } - - static void setFontFeatureSettings(JNIEnv* env, jobject clazz, jlong paintHandle, jstring settings) { - Paint* paint = reinterpret_cast(paintHandle); - if (!settings) { - paint->setFontFeatureSettings(std::string()); - } else { - ScopedUtfChars settingsChars(env, settings); - paint->setFontFeatureSettings(std::string(settingsChars.c_str(), settingsChars.size())); + if (jmeasured && env->GetArrayLength(jmeasured) > 0) { + AutoJavaFloatArray autoMeasured(env, jmeasured, 1); + jfloat* array = autoMeasured.ptr(); + array[0] = measured; } + return measuredCount; } - static jint getHyphenEdit(JNIEnv* env, jobject clazz, jlong paintHandle, jint hyphen) { - Paint* paint = reinterpret_cast(paintHandle); - return paint->getHyphenEdit(); - } + static jint breakTextC(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, + jcharArray jtext, jint index, jint count, jfloat maxWidth, jint bidiFlags, + jfloatArray jmeasuredWidth) { + NPE_CHECK_RETURN_ZERO(env, jtext); - static void setHyphenEdit(JNIEnv* env, jobject clazz, jlong paintHandle, jint hyphen) { - Paint* paint = reinterpret_cast(paintHandle); - paint->setHyphenEdit((uint32_t)hyphen); - } - - static SkScalar getMetricsInternal(jlong paintHandle, jlong typefaceHandle, - Paint::FontMetrics *metrics) { - const int kElegantTop = 2500; - const int kElegantBottom = -1000; - const int kElegantAscent = 1900; - const int kElegantDescent = -500; - const int kElegantLeading = 0; Paint* paint = reinterpret_cast(paintHandle); Typeface* typeface = reinterpret_cast(typefaceHandle); - typeface = Typeface::resolveDefault(typeface); - minikin::FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle); - float saveSkewX = paint->getTextSkewX(); - bool savefakeBold = paint->isFakeBoldText(); - MinikinFontSkia::populateSkPaint(paint, baseFont.font, baseFont.fakery); - SkScalar spacing = paint->getFontMetrics(metrics); - // The populateSkPaint call may have changed fake bold / text skew - // because we want to measure with those effects applied, so now - // restore the original settings. - paint->setTextSkewX(saveSkewX); - paint->setFakeBoldText(savefakeBold); - if (paint->getFontVariant() == minikin::VARIANT_ELEGANT) { - SkScalar size = paint->getTextSize(); - metrics->fTop = -size * kElegantTop / 2048; - metrics->fBottom = -size * kElegantBottom / 2048; - metrics->fAscent = -size * kElegantAscent / 2048; - metrics->fDescent = -size * kElegantDescent / 2048; - metrics->fLeading = size * kElegantLeading / 2048; - spacing = metrics->fDescent - metrics->fAscent + metrics->fLeading; + + bool forwardTextDirection; + if (count < 0) { + forwardTextDirection = false; + count = -count; } - return spacing; - } - - static jfloat ascent(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle) { - Paint::FontMetrics metrics; - getMetricsInternal(paintHandle, typefaceHandle, &metrics); - return SkScalarToFloat(metrics.fAscent); - } - - static jfloat descent(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle) { - Paint::FontMetrics metrics; - getMetricsInternal(paintHandle, typefaceHandle, &metrics); - return SkScalarToFloat(metrics.fDescent); - } - - static jfloat getFontMetrics(JNIEnv* env, jobject, jlong paintHandle, - jlong typefaceHandle, jobject metricsObj) { - Paint::FontMetrics metrics; - SkScalar spacing = getMetricsInternal(paintHandle, typefaceHandle, &metrics); - - if (metricsObj) { - SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class)); - env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop)); - env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent)); - env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent)); - env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom)); - env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading)); + else { + forwardTextDirection = true; } - return SkScalarToFloat(spacing); + + if ((index < 0) || (index + count > env->GetArrayLength(jtext))) { + doThrowAIOOBE(env); + return 0; + } + + const jchar* text = env->GetCharArrayElements(jtext, nullptr); + count = breakText(env, *paint, typeface, text + index, count, maxWidth, + bidiFlags, jmeasuredWidth, forwardTextDirection); + env->ReleaseCharArrayElements(jtext, const_cast(text), + JNI_ABORT); + return count; } - static jint getFontMetricsInt(JNIEnv* env, jobject, jlong paintHandle, - jlong typefaceHandle, jobject metricsObj) { - Paint::FontMetrics metrics; + static jint breakTextS(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring jtext, + jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) { + NPE_CHECK_RETURN_ZERO(env, jtext); - getMetricsInternal(paintHandle, typefaceHandle, &metrics); - int ascent = SkScalarRoundToInt(metrics.fAscent); - int descent = SkScalarRoundToInt(metrics.fDescent); - int leading = SkScalarRoundToInt(metrics.fLeading); + Paint* paint = reinterpret_cast(paintHandle); + Typeface* typeface = reinterpret_cast(typefaceHandle); - if (metricsObj) { - SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class)); - env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloorToInt(metrics.fTop)); - env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent); - env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent); - env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeilToInt(metrics.fBottom)); - env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading); - } - return descent - ascent + leading; + int count = env->GetStringLength(jtext); + const jchar* text = env->GetStringChars(jtext, nullptr); + count = breakText(env, *paint, typeface, text, count, maxWidth, bidiFlags, jmeasuredWidth, forwards); + env->ReleaseStringChars(jtext, text); + return count; } static jfloat doTextAdvances(JNIEnv *env, Paint *paint, Typeface* typeface, @@ -530,7 +218,7 @@ namespace PaintGlue { jint bidiFlags, jfloatArray advances, jint advancesIndex) { Paint* paint = reinterpret_cast(paintHandle); Typeface* typeface = reinterpret_cast(typefaceHandle); - jchar* textArray = env->GetCharArrayElements(text, NULL); + jchar* textArray = env->GetCharArrayElements(text, nullptr); jfloat result = doTextAdvances(env, paint, typeface, textArray + contextIndex, index - contextIndex, count, contextCount, bidiFlags, advances, advancesIndex); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); @@ -543,7 +231,7 @@ namespace PaintGlue { jfloatArray advances, jint advancesIndex) { Paint* paint = reinterpret_cast(paintHandle); Typeface* typeface = reinterpret_cast(typefaceHandle); - const jchar* textArray = env->GetStringChars(text, NULL); + const jchar* textArray = env->GetStringChars(text, nullptr); jfloat result = doTextAdvances(env, paint, typeface, textArray + contextStart, start - contextStart, end - start, contextEnd - contextStart, bidiFlags, advances, advancesIndex); @@ -562,7 +250,7 @@ namespace PaintGlue { static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text, jint contextStart, jint contextCount, jint dir, jint offset, jint cursorOpt) { Paint* paint = reinterpret_cast(paintHandle); - jchar* textArray = env->GetCharArrayElements(text, NULL); + jchar* textArray = env->GetCharArrayElements(text, nullptr); jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, dir, offset, cursorOpt); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); @@ -572,7 +260,7 @@ namespace PaintGlue { static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text, jint contextStart, jint contextEnd, jint dir, jint offset, jint cursorOpt) { Paint* paint = reinterpret_cast(paintHandle); - const jchar* textArray = env->GetStringChars(text, NULL); + const jchar* textArray = env->GetStringChars(text, nullptr); jint result = doTextRunCursor(env, paint, textArray, contextStart, contextEnd - contextStart, dir, offset, cursorOpt); env->ReleaseStringChars(text, textArray); @@ -635,7 +323,7 @@ namespace PaintGlue { Paint* paint = reinterpret_cast(paintHandle); Typeface* typeface = reinterpret_cast(typefaceHandle); SkPath* path = reinterpret_cast(pathHandle); - const jchar* textArray = env->GetCharArrayElements(text, NULL); + const jchar* textArray = env->GetCharArrayElements(text, nullptr); getTextPath(env, paint, typeface, textArray + index, count, bidiFlags, x, y, path); env->ReleaseCharArrayElements(text, const_cast(textArray), JNI_ABORT); } @@ -646,103 +334,11 @@ namespace PaintGlue { Paint* paint = reinterpret_cast(paintHandle); Typeface* typeface = reinterpret_cast(typefaceHandle); SkPath* path = reinterpret_cast(pathHandle); - const jchar* textArray = env->GetStringChars(text, NULL); + const jchar* textArray = env->GetStringChars(text, nullptr); getTextPath(env, paint, typeface, textArray + start, end - start, bidiFlags, x, y, path); env->ReleaseStringChars(text, textArray); } - static void setShadowLayer(JNIEnv* env, jobject clazz, jlong paintHandle, jfloat radius, - jfloat dx, jfloat dy, jint color) { - Paint* paint = reinterpret_cast(paintHandle); - if (radius <= 0) { - paint->setLooper(NULL); - } - else { - SkScalar sigma = android::uirenderer::Blur::convertRadiusToSigma(radius); - paint->setLooper(SkBlurDrawLooper::Create((SkColor)color, sigma, dx, dy))->unref(); - } - } - - static jboolean hasShadowLayer(JNIEnv* env, jobject clazz, jlong paintHandle) { - Paint* paint = reinterpret_cast(paintHandle); - return paint->getLooper() && paint->getLooper()->asABlurShadow(NULL); - } - - static int breakText(JNIEnv* env, const Paint& paint, Typeface* typeface, const jchar text[], - int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured, - const bool forwardScan) { - size_t measuredCount = 0; - float measured = 0; - - std::unique_ptr advancesArray(new float[count]); - MinikinUtils::measureText(&paint, bidiFlags, typeface, text, 0, count, count, - advancesArray.get()); - - for (int i = 0; i < count; i++) { - // traverse in the given direction - int index = forwardScan ? i : (count - i - 1); - float width = advancesArray[index]; - if (measured + width > maxWidth) { - break; - } - // properly handle clusters when scanning backwards - if (forwardScan || width != 0.0f) { - measuredCount = i + 1; - } - measured += width; - } - - if (jmeasured && env->GetArrayLength(jmeasured) > 0) { - AutoJavaFloatArray autoMeasured(env, jmeasured, 1); - jfloat* array = autoMeasured.ptr(); - array[0] = measured; - } - return measuredCount; - } - - static jint breakTextC(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jcharArray jtext, - jint index, jint count, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) { - NPE_CHECK_RETURN_ZERO(env, jtext); - - Paint* paint = reinterpret_cast(paintHandle); - Typeface* typeface = reinterpret_cast(typefaceHandle); - - bool forwardTextDirection; - if (count < 0) { - forwardTextDirection = false; - count = -count; - } - else { - forwardTextDirection = true; - } - - if ((index < 0) || (index + count > env->GetArrayLength(jtext))) { - doThrowAIOOBE(env); - return 0; - } - - const jchar* text = env->GetCharArrayElements(jtext, NULL); - count = breakText(env, *paint, typeface, text + index, count, maxWidth, - bidiFlags, jmeasuredWidth, forwardTextDirection); - env->ReleaseCharArrayElements(jtext, const_cast(text), - JNI_ABORT); - return count; - } - - static jint breakTextS(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring jtext, - jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) { - NPE_CHECK_RETURN_ZERO(env, jtext); - - Paint* paint = reinterpret_cast(paintHandle); - Typeface* typeface = reinterpret_cast(typefaceHandle); - - int count = env->GetStringLength(jtext); - const jchar* text = env->GetStringChars(jtext, NULL); - count = breakText(env, *paint, typeface, text, count, maxWidth, bidiFlags, jmeasuredWidth, forwards); - env->ReleaseStringChars(jtext, text); - return count; - } - static void doTextBounds(JNIEnv* env, const jchar* text, int count, jobject bounds, const Paint& paint, Typeface* typeface, jint bidiFlags) { SkRect r; @@ -764,7 +360,7 @@ namespace PaintGlue { jstring text, jint start, jint end, jint bidiFlags, jobject bounds) { const Paint* paint = reinterpret_cast(paintHandle); Typeface* typeface = reinterpret_cast(typefaceHandle); - const jchar* textArray = env->GetStringChars(text, NULL); + const jchar* textArray = env->GetStringChars(text, nullptr); doTextBounds(env, textArray + start, end - start, bounds, *paint, typeface, bidiFlags); env->ReleaseStringChars(text, textArray); } @@ -773,12 +369,28 @@ namespace PaintGlue { jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) { const Paint* paint = reinterpret_cast(paintHandle); Typeface* typeface = reinterpret_cast(typefaceHandle); - const jchar* textArray = env->GetCharArrayElements(text, NULL); + const jchar* textArray = env->GetCharArrayElements(text, nullptr); doTextBounds(env, textArray + index, count, bounds, *paint, typeface, bidiFlags); env->ReleaseCharArrayElements(text, const_cast(textArray), JNI_ABORT); } + // Returns true if the given string is exact one pair of regional indicators. + static bool isFlag(const jchar* str, size_t length) { + const jchar RI_LEAD_SURROGATE = 0xD83C; + const jchar RI_TRAIL_SURROGATE_MIN = 0xDDE6; + const jchar RI_TRAIL_SURROGATE_MAX = 0xDDFF; + + if (length != 4) { + return false; + } + if (str[0] != RI_LEAD_SURROGATE || str[2] != RI_LEAD_SURROGATE) { + return false; + } + return RI_TRAIL_SURROGATE_MIN <= str[1] && str[1] <= RI_TRAIL_SURROGATE_MAX && + RI_TRAIL_SURROGATE_MIN <= str[3] && str[3] <= RI_TRAIL_SURROGATE_MAX; + } + static jboolean layoutContainsNotdef(const minikin::Layout& layout) { for (size_t i = 0; i < layout.nGlyphs(); i++) { if (layout.getGlyphId(i) == 0) { @@ -803,22 +415,6 @@ namespace PaintGlue { return count; } - // Returns true if the given string is exact one pair of regional indicators. - static bool isFlag(const jchar* str, size_t length) { - const jchar RI_LEAD_SURROGATE = 0xD83C; - const jchar RI_TRAIL_SURROGATE_MIN = 0xDDE6; - const jchar RI_TRAIL_SURROGATE_MAX = 0xDDFF; - - if (length != 4) { - return false; - } - if (str[0] != RI_LEAD_SURROGATE || str[2] != RI_LEAD_SURROGATE) { - return false; - } - return RI_TRAIL_SURROGATE_MIN <= str[1] && str[1] <= RI_TRAIL_SURROGATE_MAX && - RI_TRAIL_SURROGATE_MIN <= str[3] && str[3] <= RI_TRAIL_SURROGATE_MAX; - } - static jboolean hasGlyph(JNIEnv *env, jclass, jlong paintHandle, jlong typefaceHandle, jint bidiFlags, jstring string) { const Paint* paint = reinterpret_cast(paintHandle); @@ -913,7 +509,7 @@ namespace PaintGlue { jint contextEnd, jboolean isRtl, jint offset) { const Paint* paint = reinterpret_cast(paintHandle); Typeface* typeface = reinterpret_cast(typefaceHandle); - jchar* textArray = (jchar*) env->GetPrimitiveArrayCritical(text, NULL); + jchar* textArray = (jchar*) env->GetPrimitiveArrayCritical(text, nullptr); jfloat result = doRunAdvance(paint, typeface, textArray + contextStart, start - contextStart, end - start, contextEnd - contextStart, isRtl, offset - contextStart); @@ -935,7 +531,7 @@ namespace PaintGlue { jint contextEnd, jboolean isRtl, jfloat advance) { const Paint* paint = reinterpret_cast(paintHandle); Typeface* typeface = reinterpret_cast(typefaceHandle); - jchar* textArray = (jchar*) env->GetPrimitiveArrayCritical(text, NULL); + jchar* textArray = (jchar*) env->GetPrimitiveArrayCritical(text, nullptr); jint result = doOffsetForAdvance(paint, typeface, textArray + contextStart, start - contextStart, end - start, contextEnd - contextStart, isRtl, advance); result += contextStart; @@ -943,76 +539,422 @@ namespace PaintGlue { return result; } + // ------------------ @FastNative --------------------------- + + static jint setTextLocales(JNIEnv* env, jobject clazz, jlong objHandle, jstring locales) { + Paint* obj = reinterpret_cast(objHandle); + ScopedUtfChars localesChars(env, locales); + jint minikinLangListId = minikin::FontStyle::registerLanguageList(localesChars.c_str()); + obj->setMinikinLangListId(minikinLangListId); + return minikinLangListId; + } + + static void setFontFeatureSettings(JNIEnv* env, jobject clazz, jlong paintHandle, jstring settings) { + Paint* paint = reinterpret_cast(paintHandle); + if (!settings) { + paint->setFontFeatureSettings(std::string()); + } else { + ScopedUtfChars settingsChars(env, settings); + paint->setFontFeatureSettings(std::string(settingsChars.c_str(), settingsChars.size())); + } + } + + static SkScalar getMetricsInternal(jlong paintHandle, jlong typefaceHandle, + Paint::FontMetrics *metrics) { + const int kElegantTop = 2500; + const int kElegantBottom = -1000; + const int kElegantAscent = 1900; + const int kElegantDescent = -500; + const int kElegantLeading = 0; + Paint* paint = reinterpret_cast(paintHandle); + Typeface* typeface = reinterpret_cast(typefaceHandle); + typeface = Typeface::resolveDefault(typeface); + minikin::FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle); + float saveSkewX = paint->getTextSkewX(); + bool savefakeBold = paint->isFakeBoldText(); + MinikinFontSkia::populateSkPaint(paint, baseFont.font, baseFont.fakery); + SkScalar spacing = paint->getFontMetrics(metrics); + // The populateSkPaint call may have changed fake bold / text skew + // because we want to measure with those effects applied, so now + // restore the original settings. + paint->setTextSkewX(saveSkewX); + paint->setFakeBoldText(savefakeBold); + if (paint->getFontVariant() == minikin::VARIANT_ELEGANT) { + SkScalar size = paint->getTextSize(); + metrics->fTop = -size * kElegantTop / 2048; + metrics->fBottom = -size * kElegantBottom / 2048; + metrics->fAscent = -size * kElegantAscent / 2048; + metrics->fDescent = -size * kElegantDescent / 2048; + metrics->fLeading = size * kElegantLeading / 2048; + spacing = metrics->fDescent - metrics->fAscent + metrics->fLeading; + } + return spacing; + } + + static jfloat getFontMetrics(JNIEnv* env, jobject, jlong paintHandle, + jlong typefaceHandle, jobject metricsObj) { + Paint::FontMetrics metrics; + SkScalar spacing = getMetricsInternal(paintHandle, typefaceHandle, &metrics); + + if (metricsObj) { + SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class)); + env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop)); + env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent)); + env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent)); + env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom)); + env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading)); + } + return SkScalarToFloat(spacing); + } + + static jint getFontMetricsInt(JNIEnv* env, jobject, jlong paintHandle, + jlong typefaceHandle, jobject metricsObj) { + Paint::FontMetrics metrics; + + getMetricsInternal(paintHandle, typefaceHandle, &metrics); + int ascent = SkScalarRoundToInt(metrics.fAscent); + int descent = SkScalarRoundToInt(metrics.fDescent); + int leading = SkScalarRoundToInt(metrics.fLeading); + + if (metricsObj) { + SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class)); + env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloorToInt(metrics.fTop)); + env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent); + env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent); + env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeilToInt(metrics.fBottom)); + env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading); + } + return descent - ascent + leading; + } + + + // ------------------ @CriticalNative --------------------------- + + static void reset(jlong objHandle) { + Paint* obj = reinterpret_cast(objHandle); + obj->reset(); + defaultSettingsForAndroid(obj); + } + + static void assign(jlong dstPaintHandle, jlong srcPaintHandle) { + Paint* dst = reinterpret_cast(dstPaintHandle); + const Paint* src = reinterpret_cast(srcPaintHandle); + *dst = *src; + } + + // Equivalent to the Java Paint's FILTER_BITMAP_FLAG. + static const uint32_t sFilterBitmapFlag = 0x02; + + static jint getFlags(jlong paintHandle) { + Paint* nativePaint = reinterpret_cast(paintHandle); + uint32_t result = nativePaint->getFlags(); + result &= ~sFilterBitmapFlag; // Filtering no longer stored in this bit. Mask away. + if (nativePaint->getFilterQuality() != kNone_SkFilterQuality) { + result |= sFilterBitmapFlag; + } + return static_cast(result); + } + + static void setFlags(jlong paintHandle, jint flags) { + Paint* nativePaint = reinterpret_cast(paintHandle); + // Instead of modifying 0x02, change the filter level. + nativePaint->setFilterQuality(flags & sFilterBitmapFlag + ? kLow_SkFilterQuality + : kNone_SkFilterQuality); + // Don't pass through filter flag, which is no longer stored in paint's flags. + flags &= ~sFilterBitmapFlag; + // Use the existing value for 0x02. + const uint32_t existing0x02Flag = nativePaint->getFlags() & sFilterBitmapFlag; + flags |= existing0x02Flag; + nativePaint->setFlags(flags); + } + + static jint getHinting(jlong paintHandle) { + return reinterpret_cast(paintHandle)->getHinting() + == Paint::kNo_Hinting ? 0 : 1; + } + + static void setHinting(jlong paintHandle, jint mode) { + reinterpret_cast(paintHandle)->setHinting( + mode == 0 ? Paint::kNo_Hinting : Paint::kNormal_Hinting); + } + + static void setAntiAlias(jlong paintHandle, jboolean aa) { + reinterpret_cast(paintHandle)->setAntiAlias(aa); + } + + static void setLinearText(jlong paintHandle, jboolean linearText) { + reinterpret_cast(paintHandle)->setLinearText(linearText); + } + + static void setSubpixelText(jlong paintHandle, jboolean subpixelText) { + reinterpret_cast(paintHandle)->setSubpixelText(subpixelText); + } + + static void setUnderlineText(jlong paintHandle, jboolean underlineText) { + reinterpret_cast(paintHandle)->setUnderlineText(underlineText); + } + + static void setStrikeThruText(jlong paintHandle, jboolean strikeThruText) { + reinterpret_cast(paintHandle)->setStrikeThruText(strikeThruText); + } + + static void setFakeBoldText(jlong paintHandle, jboolean fakeBoldText) { + reinterpret_cast(paintHandle)->setFakeBoldText(fakeBoldText); + } + + static void setFilterBitmap(jlong paintHandle, jboolean filterBitmap) { + reinterpret_cast(paintHandle)->setFilterQuality( + filterBitmap ? kLow_SkFilterQuality : kNone_SkFilterQuality); + } + + static void setDither(jlong paintHandle, jboolean dither) { + reinterpret_cast(paintHandle)->setDither(dither); + } + + static jint getStyle(jlong objHandle) { + Paint* obj = reinterpret_cast(objHandle); + return static_cast(obj->getStyle()); + } + + static void setStyle(jlong objHandle, jint styleHandle) { + Paint* obj = reinterpret_cast(objHandle); + Paint::Style style = static_cast(styleHandle); + obj->setStyle(style); + } + + static jint getColor(jlong paintHandle) { + int color; + color = reinterpret_cast(paintHandle)->getColor(); + return static_cast(color); + } + + static jint getAlpha(jlong paintHandle) { + int alpha; + alpha = reinterpret_cast(paintHandle)->getAlpha(); + return static_cast(alpha); + } + + static void setColor(jlong paintHandle, jint color) { + reinterpret_cast(paintHandle)->setColor(color); + } + + static void setAlpha(jlong paintHandle, jint a) { + reinterpret_cast(paintHandle)->setAlpha(a); + } + + static jfloat getStrokeWidth(jlong paintHandle) { + return SkScalarToFloat(reinterpret_cast(paintHandle)->getStrokeWidth()); + } + + static void setStrokeWidth(jlong paintHandle, jfloat width) { + reinterpret_cast(paintHandle)->setStrokeWidth(width); + } + + static jfloat getStrokeMiter(jlong paintHandle) { + return SkScalarToFloat(reinterpret_cast(paintHandle)->getStrokeMiter()); + } + + static void setStrokeMiter(jlong paintHandle, jfloat miter) { + reinterpret_cast(paintHandle)->setStrokeMiter(miter); + } + + static jint getStrokeCap(jlong objHandle) { + Paint* obj = reinterpret_cast(objHandle); + return static_cast(obj->getStrokeCap()); + } + + static void setStrokeCap(jlong objHandle, jint capHandle) { + Paint* obj = reinterpret_cast(objHandle); + Paint::Cap cap = static_cast(capHandle); + obj->setStrokeCap(cap); + } + + static jint getStrokeJoin(jlong objHandle) { + Paint* obj = reinterpret_cast(objHandle); + return static_cast(obj->getStrokeJoin()); + } + + static void setStrokeJoin(jlong objHandle, jint joinHandle) { + Paint* obj = reinterpret_cast(objHandle); + Paint::Join join = (Paint::Join) joinHandle; + obj->setStrokeJoin(join); + } + + static jboolean getFillPath(jlong objHandle, jlong srcHandle, jlong dstHandle) { + Paint* obj = reinterpret_cast(objHandle); + SkPath* src = reinterpret_cast(srcHandle); + SkPath* dst = reinterpret_cast(dstHandle); + return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE; + } + + static jlong setShader(jlong objHandle, jlong shaderHandle) { + Paint* obj = reinterpret_cast(objHandle); + SkShader* shader = reinterpret_cast(shaderHandle); + return reinterpret_cast(obj->setShader(shader)); + } + + static jlong setColorFilter(jlong objHandle, jlong filterHandle) { + Paint* obj = reinterpret_cast(objHandle); + SkColorFilter* filter = reinterpret_cast(filterHandle); + return reinterpret_cast(obj->setColorFilter(filter)); + } + + static void setXfermode(jlong paintHandle, jint xfermodeHandle) { + // validate that the Java enum values match our expectations + static_assert(0 == SkXfermode::kClear_Mode, "xfermode_mismatch"); + static_assert(1 == SkXfermode::kSrc_Mode, "xfermode_mismatch"); + static_assert(2 == SkXfermode::kDst_Mode, "xfermode_mismatch"); + static_assert(3 == SkXfermode::kSrcOver_Mode, "xfermode_mismatch"); + static_assert(4 == SkXfermode::kDstOver_Mode, "xfermode_mismatch"); + static_assert(5 == SkXfermode::kSrcIn_Mode, "xfermode_mismatch"); + static_assert(6 == SkXfermode::kDstIn_Mode, "xfermode_mismatch"); + static_assert(7 == SkXfermode::kSrcOut_Mode, "xfermode_mismatch"); + static_assert(8 == SkXfermode::kDstOut_Mode, "xfermode_mismatch"); + static_assert(9 == SkXfermode::kSrcATop_Mode, "xfermode_mismatch"); + static_assert(10 == SkXfermode::kDstATop_Mode, "xfermode_mismatch"); + static_assert(11 == SkXfermode::kXor_Mode, "xfermode_mismatch"); + static_assert(16 == SkXfermode::kDarken_Mode, "xfermode_mismatch"); + static_assert(17 == SkXfermode::kLighten_Mode, "xfermode_mismatch"); + static_assert(13 == SkXfermode::kModulate_Mode, "xfermode_mismatch"); + static_assert(14 == SkXfermode::kScreen_Mode, "xfermode_mismatch"); + static_assert(12 == SkXfermode::kPlus_Mode, "xfermode_mismatch"); + static_assert(15 == SkXfermode::kOverlay_Mode, "xfermode_mismatch"); + + SkXfermode::Mode mode = static_cast(xfermodeHandle); + Paint* paint = reinterpret_cast(paintHandle); + paint->setXfermodeMode(mode); + } + + static jlong setPathEffect(jlong objHandle, jlong effectHandle) { + Paint* obj = reinterpret_cast(objHandle); + SkPathEffect* effect = reinterpret_cast(effectHandle); + return reinterpret_cast(obj->setPathEffect(effect)); + } + + static jlong setMaskFilter(jlong objHandle, jlong maskfilterHandle) { + Paint* obj = reinterpret_cast(objHandle); + SkMaskFilter* maskfilter = reinterpret_cast(maskfilterHandle); + return reinterpret_cast(obj->setMaskFilter(maskfilter)); + } + + static jlong setTypeface(jlong objHandle, jlong typefaceHandle) { + // TODO: in Paint refactoring, set typeface on android Paint, not Paint + return 0; + } + + static jlong setRasterizer(jlong objHandle, jlong rasterizerHandle) { + Paint* obj = reinterpret_cast(objHandle); + SkAutoTUnref rasterizer(GraphicsJNI::refNativeRasterizer(rasterizerHandle)); + return reinterpret_cast(obj->setRasterizer(rasterizer)); + } + + static jint getTextAlign(jlong objHandle) { + Paint* obj = reinterpret_cast(objHandle); + return static_cast(obj->getTextAlign()); + } + + static void setTextAlign(jlong objHandle, jint alignHandle) { + Paint* obj = reinterpret_cast(objHandle); + Paint::Align align = static_cast(alignHandle); + obj->setTextAlign(align); + } + + static void setTextLocalesByMinikinLangListId(jlong objHandle, + jint minikinLangListId) { + Paint* obj = reinterpret_cast(objHandle); + obj->setMinikinLangListId(minikinLangListId); + } + + static jboolean isElegantTextHeight(jlong paintHandle) { + Paint* obj = reinterpret_cast(paintHandle); + return obj->getFontVariant() == minikin::VARIANT_ELEGANT; + } + + static void setElegantTextHeight(jlong paintHandle, jboolean aa) { + Paint* obj = reinterpret_cast(paintHandle); + obj->setFontVariant(aa ? minikin::VARIANT_ELEGANT : minikin::VARIANT_DEFAULT); + } + + static jfloat getTextSize(jlong paintHandle) { + return SkScalarToFloat(reinterpret_cast(paintHandle)->getTextSize()); + } + + static void setTextSize(jlong paintHandle, jfloat textSize) { + reinterpret_cast(paintHandle)->setTextSize(textSize); + } + + static jfloat getTextScaleX(jlong paintHandle) { + return SkScalarToFloat(reinterpret_cast(paintHandle)->getTextScaleX()); + } + + static void setTextScaleX(jlong paintHandle, jfloat scaleX) { + reinterpret_cast(paintHandle)->setTextScaleX(scaleX); + } + + static jfloat getTextSkewX(jlong paintHandle) { + return SkScalarToFloat(reinterpret_cast(paintHandle)->getTextSkewX()); + } + + static void setTextSkewX(jlong paintHandle, jfloat skewX) { + reinterpret_cast(paintHandle)->setTextSkewX(skewX); + } + + static jfloat getLetterSpacing(jlong paintHandle) { + Paint* paint = reinterpret_cast(paintHandle); + return paint->getLetterSpacing(); + } + + static void setLetterSpacing(jlong paintHandle, jfloat letterSpacing) { + Paint* paint = reinterpret_cast(paintHandle); + paint->setLetterSpacing(letterSpacing); + } + + static jint getHyphenEdit(jlong paintHandle, jint hyphen) { + Paint* paint = reinterpret_cast(paintHandle); + return paint->getHyphenEdit(); + } + + static void setHyphenEdit(jlong paintHandle, jint hyphen) { + Paint* paint = reinterpret_cast(paintHandle); + paint->setHyphenEdit((uint32_t)hyphen); + } + + static jfloat ascent(jlong paintHandle, jlong typefaceHandle) { + Paint::FontMetrics metrics; + getMetricsInternal(paintHandle, typefaceHandle, &metrics); + return SkScalarToFloat(metrics.fAscent); + } + + static jfloat descent(jlong paintHandle, jlong typefaceHandle) { + Paint::FontMetrics metrics; + getMetricsInternal(paintHandle, typefaceHandle, &metrics); + return SkScalarToFloat(metrics.fDescent); + } + + static void setShadowLayer(jlong paintHandle, jfloat radius, + jfloat dx, jfloat dy, jint color) { + Paint* paint = reinterpret_cast(paintHandle); + if (radius <= 0) { + paint->setLooper(nullptr); + } + else { + SkScalar sigma = android::uirenderer::Blur::convertRadiusToSigma(radius); + paint->setLooper(SkBlurDrawLooper::Create((SkColor)color, sigma, dx, dy))->unref(); + } + } + + static jboolean hasShadowLayer(jlong paintHandle) { + Paint* paint = reinterpret_cast(paintHandle); + return paint->getLooper() && paint->getLooper()->asABlurShadow(nullptr); + } + }; // namespace PaintGlue static const JNINativeMethod methods[] = { {"nGetNativeFinalizer", "()J", (void*) PaintGlue::getNativeFinalizer}, {"nInit","()J", (void*) PaintGlue::init}, {"nInitWithPaint","(J)J", (void*) PaintGlue::initWithPaint}, - - {"nReset","!(J)V", (void*) PaintGlue::reset}, - {"nSet","!(JJ)V", (void*) PaintGlue::assign}, - {"nGetFlags","!(J)I", (void*) PaintGlue::getFlags}, - {"nSetFlags","!(JI)V", (void*) PaintGlue::setFlags}, - {"nGetHinting","!(J)I", (void*) PaintGlue::getHinting}, - {"nSetHinting","!(JI)V", (void*) PaintGlue::setHinting}, - {"nSetAntiAlias","!(JZ)V", (void*) PaintGlue::setAntiAlias}, - {"nSetSubpixelText","!(JZ)V", (void*) PaintGlue::setSubpixelText}, - {"nSetLinearText","!(JZ)V", (void*) PaintGlue::setLinearText}, - {"nSetUnderlineText","!(JZ)V", (void*) PaintGlue::setUnderlineText}, - {"nSetStrikeThruText","!(JZ)V", (void*) PaintGlue::setStrikeThruText}, - {"nSetFakeBoldText","!(JZ)V", (void*) PaintGlue::setFakeBoldText}, - {"nSetFilterBitmap","!(JZ)V", (void*) PaintGlue::setFilterBitmap}, - {"nSetDither","!(JZ)V", (void*) PaintGlue::setDither}, - {"nGetStyle","!(J)I", (void*) PaintGlue::getStyle}, - {"nSetStyle","!(JI)V", (void*) PaintGlue::setStyle}, - {"nGetColor","!(J)I", (void*) PaintGlue::getColor}, - {"nSetColor","!(JI)V", (void*) PaintGlue::setColor}, - {"nGetAlpha","!(J)I", (void*) PaintGlue::getAlpha}, - {"nSetAlpha","!(JI)V", (void*) PaintGlue::setAlpha}, - {"nGetStrokeWidth","!(J)F", (void*) PaintGlue::getStrokeWidth}, - {"nSetStrokeWidth","!(JF)V", (void*) PaintGlue::setStrokeWidth}, - {"nGetStrokeMiter","!(J)F", (void*) PaintGlue::getStrokeMiter}, - {"nSetStrokeMiter","!(JF)V", (void*) PaintGlue::setStrokeMiter}, - {"nGetStrokeCap","!(J)I", (void*) PaintGlue::getStrokeCap}, - {"nSetStrokeCap","!(JI)V", (void*) PaintGlue::setStrokeCap}, - {"nGetStrokeJoin","!(J)I", (void*) PaintGlue::getStrokeJoin}, - {"nSetStrokeJoin","!(JI)V", (void*) PaintGlue::setStrokeJoin}, - {"nGetFillPath","!(JJJ)Z", (void*) PaintGlue::getFillPath}, - {"nSetShader","!(JJ)J", (void*) PaintGlue::setShader}, - {"nSetColorFilter","!(JJ)J", (void*) PaintGlue::setColorFilter}, - {"nSetXfermode","!(JI)V", (void*) PaintGlue::setXfermode}, - {"nSetPathEffect","!(JJ)J", (void*) PaintGlue::setPathEffect}, - {"nSetMaskFilter","!(JJ)J", (void*) PaintGlue::setMaskFilter}, - {"nSetTypeface","!(JJ)J", (void*) PaintGlue::setTypeface}, - {"nSetRasterizer","!(JJ)J", (void*) PaintGlue::setRasterizer}, - {"nGetTextAlign","!(J)I", (void*) PaintGlue::getTextAlign}, - {"nSetTextAlign","!(JI)V", (void*) PaintGlue::setTextAlign}, - {"nSetTextLocales","!(JLjava/lang/String;)I", (void*) PaintGlue::setTextLocales}, - {"nSetTextLocalesByMinikinLangListId","!(JI)V", - (void*) PaintGlue::setTextLocalesByMinikinLangListId}, - {"nIsElegantTextHeight","!(J)Z", (void*) PaintGlue::isElegantTextHeight}, - {"nSetElegantTextHeight","!(JZ)V", (void*) PaintGlue::setElegantTextHeight}, - {"nGetTextSize","!(J)F", (void*) PaintGlue::getTextSize}, - {"nSetTextSize","!(JF)V", (void*) PaintGlue::setTextSize}, - {"nGetTextScaleX","!(J)F", (void*) PaintGlue::getTextScaleX}, - {"nSetTextScaleX","!(JF)V", (void*) PaintGlue::setTextScaleX}, - {"nGetTextSkewX","!(J)F", (void*) PaintGlue::getTextSkewX}, - {"nSetTextSkewX","!(JF)V", (void*) PaintGlue::setTextSkewX}, - {"nGetLetterSpacing","!(J)F", (void*) PaintGlue::getLetterSpacing}, - {"nSetLetterSpacing","!(JF)V", (void*) PaintGlue::setLetterSpacing}, - {"nSetFontFeatureSettings","(JLjava/lang/String;)V", - (void*) PaintGlue::setFontFeatureSettings}, - {"nGetHyphenEdit", "!(J)I", (void*) PaintGlue::getHyphenEdit}, - {"nSetHyphenEdit", "!(JI)V", (void*) PaintGlue::setHyphenEdit}, - {"nAscent","!(JJ)F", (void*) PaintGlue::ascent}, - {"nDescent","!(JJ)F", (void*) PaintGlue::descent}, - - {"nGetFontMetrics", "!(JJLandroid/graphics/Paint$FontMetrics;)F", - (void*)PaintGlue::getFontMetrics}, - {"nGetFontMetricsInt", "!(JJLandroid/graphics/Paint$FontMetricsInt;)I", - (void*)PaintGlue::getFontMetricsInt}, - {"nBreakText","(JJ[CIIFI[F)I", (void*) PaintGlue::breakTextC}, {"nBreakText","(JJLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS}, {"nGetTextAdvances","(JJ[CIIIII[FI)F", @@ -1034,8 +976,74 @@ static const JNINativeMethod methods[] = { {"nGetOffsetForAdvance", "(JJ[CIIIIZF)I", (void*) PaintGlue::getOffsetForAdvance___CIIIIZF_I}, - {"nSetShadowLayer", "!(JFFFI)V", (void*)PaintGlue::setShadowLayer}, - {"nHasShadowLayer", "!(J)Z", (void*)PaintGlue::hasShadowLayer} + // --------------- @FastNative ---------------------- + + {"nSetTextLocales","(JLjava/lang/String;)I", (void*) PaintGlue::setTextLocales}, + {"nSetFontFeatureSettings","(JLjava/lang/String;)V", + (void*) PaintGlue::setFontFeatureSettings}, + {"nGetFontMetrics", "(JJLandroid/graphics/Paint$FontMetrics;)F", + (void*)PaintGlue::getFontMetrics}, + {"nGetFontMetricsInt", "(JJLandroid/graphics/Paint$FontMetricsInt;)I", + (void*)PaintGlue::getFontMetricsInt}, + + // --------------- @CriticalNative ------------------ + + {"nReset","(J)V", (void*) PaintGlue::reset}, + {"nSet","(JJ)V", (void*) PaintGlue::assign}, + {"nGetFlags","(J)I", (void*) PaintGlue::getFlags}, + {"nSetFlags","(JI)V", (void*) PaintGlue::setFlags}, + {"nGetHinting","(J)I", (void*) PaintGlue::getHinting}, + {"nSetHinting","(JI)V", (void*) PaintGlue::setHinting}, + {"nSetAntiAlias","(JZ)V", (void*) PaintGlue::setAntiAlias}, + {"nSetSubpixelText","(JZ)V", (void*) PaintGlue::setSubpixelText}, + {"nSetLinearText","(JZ)V", (void*) PaintGlue::setLinearText}, + {"nSetUnderlineText","(JZ)V", (void*) PaintGlue::setUnderlineText}, + {"nSetStrikeThruText","(JZ)V", (void*) PaintGlue::setStrikeThruText}, + {"nSetFakeBoldText","(JZ)V", (void*) PaintGlue::setFakeBoldText}, + {"nSetFilterBitmap","(JZ)V", (void*) PaintGlue::setFilterBitmap}, + {"nSetDither","(JZ)V", (void*) PaintGlue::setDither}, + {"nGetStyle","(J)I", (void*) PaintGlue::getStyle}, + {"nSetStyle","(JI)V", (void*) PaintGlue::setStyle}, + {"nGetColor","(J)I", (void*) PaintGlue::getColor}, + {"nSetColor","(JI)V", (void*) PaintGlue::setColor}, + {"nGetAlpha","(J)I", (void*) PaintGlue::getAlpha}, + {"nSetAlpha","(JI)V", (void*) PaintGlue::setAlpha}, + {"nGetStrokeWidth","(J)F", (void*) PaintGlue::getStrokeWidth}, + {"nSetStrokeWidth","(JF)V", (void*) PaintGlue::setStrokeWidth}, + {"nGetStrokeMiter","(J)F", (void*) PaintGlue::getStrokeMiter}, + {"nSetStrokeMiter","(JF)V", (void*) PaintGlue::setStrokeMiter}, + {"nGetStrokeCap","(J)I", (void*) PaintGlue::getStrokeCap}, + {"nSetStrokeCap","(JI)V", (void*) PaintGlue::setStrokeCap}, + {"nGetStrokeJoin","(J)I", (void*) PaintGlue::getStrokeJoin}, + {"nSetStrokeJoin","(JI)V", (void*) PaintGlue::setStrokeJoin}, + {"nGetFillPath","(JJJ)Z", (void*) PaintGlue::getFillPath}, + {"nSetShader","(JJ)J", (void*) PaintGlue::setShader}, + {"nSetColorFilter","(JJ)J", (void*) PaintGlue::setColorFilter}, + {"nSetXfermode","(JI)V", (void*) PaintGlue::setXfermode}, + {"nSetPathEffect","(JJ)J", (void*) PaintGlue::setPathEffect}, + {"nSetMaskFilter","(JJ)J", (void*) PaintGlue::setMaskFilter}, + {"nSetTypeface","(JJ)J", (void*) PaintGlue::setTypeface}, + {"nSetRasterizer","(JJ)J", (void*) PaintGlue::setRasterizer}, + {"nGetTextAlign","(J)I", (void*) PaintGlue::getTextAlign}, + {"nSetTextAlign","(JI)V", (void*) PaintGlue::setTextAlign}, + {"nSetTextLocalesByMinikinLangListId","(JI)V", + (void*) PaintGlue::setTextLocalesByMinikinLangListId}, + {"nIsElegantTextHeight","(J)Z", (void*) PaintGlue::isElegantTextHeight}, + {"nSetElegantTextHeight","(JZ)V", (void*) PaintGlue::setElegantTextHeight}, + {"nGetTextSize","(J)F", (void*) PaintGlue::getTextSize}, + {"nSetTextSize","(JF)V", (void*) PaintGlue::setTextSize}, + {"nGetTextScaleX","(J)F", (void*) PaintGlue::getTextScaleX}, + {"nSetTextScaleX","(JF)V", (void*) PaintGlue::setTextScaleX}, + {"nGetTextSkewX","(J)F", (void*) PaintGlue::getTextSkewX}, + {"nSetTextSkewX","(JF)V", (void*) PaintGlue::setTextSkewX}, + {"nGetLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing}, + {"nSetLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing}, + {"nGetHyphenEdit", "(J)I", (void*) PaintGlue::getHyphenEdit}, + {"nSetHyphenEdit", "(JI)V", (void*) PaintGlue::setHyphenEdit}, + {"nAscent","(JJ)F", (void*) PaintGlue::ascent}, + {"nDescent","(JJ)F", (void*) PaintGlue::descent}, + {"nSetShadowLayer", "(JFFFI)V", (void*)PaintGlue::setShadowLayer}, + {"nHasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer} }; int register_android_graphics_Paint(JNIEnv* env) { diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 4abe50f4335d2..98d45dc33ead4 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -27,6 +27,9 @@ import android.text.TextUtils; import com.android.internal.annotations.GuardedBy; +import dalvik.annotation.optimization.CriticalNative; +import dalvik.annotation.optimization.FastNative; + import java.util.HashMap; import java.util.Locale; @@ -604,8 +607,6 @@ public class Paint { return nGetFlags(mNativePaint); } - private native int nGetFlags(long paintPtr); - /** * Set the paint's flags. Use the Flag enum to specific flag values. * @@ -615,8 +616,6 @@ public class Paint { nSetFlags(mNativePaint, flags); } - private native void nSetFlags(long paintPtr, int flags); - /** * Return the paint's hinting mode. Returns either * {@link #HINTING_OFF} or {@link #HINTING_ON}. @@ -625,8 +624,6 @@ public class Paint { return nGetHinting(mNativePaint); } - private native int nGetHinting(long paintPtr); - /** * Set the paint's hinting mode. May be either * {@link #HINTING_OFF} or {@link #HINTING_ON}. @@ -635,8 +632,6 @@ public class Paint { nSetHinting(mNativePaint, mode); } - private native void nSetHinting(long paintPtr, int mode); - /** * Helper for getFlags(), returning true if ANTI_ALIAS_FLAG bit is set * AntiAliasing smooths out the edges of what is being drawn, but is has @@ -661,8 +656,6 @@ public class Paint { nSetAntiAlias(mNativePaint, aa); } - private native void nSetAntiAlias(long paintPtr, boolean aa); - /** * Helper for getFlags(), returning true if DITHER_FLAG bit is set * Dithering affects how colors that are higher precision than the device @@ -691,8 +684,6 @@ public class Paint { nSetDither(mNativePaint, dither); } - private native void nSetDither(long paintPtr, boolean dither); - /** * Helper for getFlags(), returning true if LINEAR_TEXT_FLAG bit is set * @@ -712,8 +703,6 @@ public class Paint { nSetLinearText(mNativePaint, linearText); } - private native void nSetLinearText(long paintPtr, boolean linearText); - /** * Helper for getFlags(), returning true if SUBPIXEL_TEXT_FLAG bit is set * @@ -733,8 +722,6 @@ public class Paint { nSetSubpixelText(mNativePaint, subpixelText); } - private native void nSetSubpixelText(long paintPtr, boolean subpixelText); - /** * Helper for getFlags(), returning true if UNDERLINE_TEXT_FLAG bit is set * @@ -754,8 +741,6 @@ public class Paint { nSetUnderlineText(mNativePaint, underlineText); } - private native void nSetUnderlineText(long paintPtr, boolean underlineText); - /** * Helper for getFlags(), returning true if STRIKE_THRU_TEXT_FLAG bit is set * @@ -775,8 +760,6 @@ public class Paint { nSetStrikeThruText(mNativePaint, strikeThruText); } - private native void nSetStrikeThruText(long paintPtr, boolean strikeThruText); - /** * Helper for getFlags(), returning true if FAKE_BOLD_TEXT_FLAG bit is set * @@ -796,8 +779,6 @@ public class Paint { nSetFakeBoldText(mNativePaint, fakeBoldText); } - private native void nSetFakeBoldText(long paintPtr, boolean fakeBoldText); - /** * Whether or not the bitmap filter is activated. * Filtering affects the sampling of bitmaps when they are transformed. @@ -823,8 +804,6 @@ public class Paint { nSetFilterBitmap(mNativePaint, filter); } - private native void nSetFilterBitmap(long paintPtr, boolean filter); - /** * Return the paint's style, used for controlling how primitives' * geometries are interpreted (except for drawBitmap, which always assumes @@ -860,8 +839,6 @@ public class Paint { return nGetColor(mNativePaint); } - private native int nGetColor(long paintPtr); - /** * Set the paint's color. Note that the color is an int containing alpha * as well as r,g,b. This 32bit value is not premultiplied, meaning that @@ -874,8 +851,6 @@ public class Paint { nSetColor(mNativePaint, color); } - private native void nSetColor(long paintPtr, @ColorInt int color); - /** * Helper to getColor() that just returns the color's alpha value. This is * the same as calling getColor() >>> 24. It always returns a value between @@ -887,8 +862,6 @@ public class Paint { return nGetAlpha(mNativePaint); } - private native int nGetAlpha(long paintPtr); - /** * Helper to setColor(), that only assigns the color's alpha value, * leaving its r,g,b values unchanged. Results are undefined if the alpha @@ -900,8 +873,6 @@ public class Paint { nSetAlpha(mNativePaint, a); } - private native void nSetAlpha(long paintPtr, int a); - /** * Helper to setColor(), that takes a,r,g,b and constructs the color int * @@ -927,8 +898,6 @@ public class Paint { return nGetStrokeWidth(mNativePaint); } - private native float nGetStrokeWidth(long paintPtr); - /** * Set the width for stroking. * Pass 0 to stroke in hairline mode. @@ -941,8 +910,6 @@ public class Paint { nSetStrokeWidth(mNativePaint, width); } - private native void nSetStrokeWidth(long paintPtr, float width); - /** * Return the paint's stroke miter value. Used to control the behavior * of miter joins when the joins angle is sharp. @@ -954,8 +921,6 @@ public class Paint { return nGetStrokeMiter(mNativePaint); } - private native float nGetStrokeMiter(long paintPtr); - /** * Set the paint's stroke miter value. This is used to control the behavior * of miter joins when the joins angle is sharp. This value must be >= 0. @@ -967,8 +932,6 @@ public class Paint { nSetStrokeMiter(mNativePaint, miter); } - private native void nSetStrokeMiter(long paintPtr, float miter); - /** * Return the paint's Cap, controlling how the start and end of stroked * lines and paths are treated. @@ -1387,8 +1350,6 @@ public class Paint { return nIsElegantTextHeight(mNativePaint); } - private native boolean nIsElegantTextHeight(long paintPtr); - /** * Set the paint's elegant height metrics flag. This setting selects font * variants that have not been compacted to fit Latin-based vertical @@ -1400,8 +1361,6 @@ public class Paint { nSetElegantTextHeight(mNativePaint, elegant); } - private native void nSetElegantTextHeight(long paintPtr, boolean elegant); - /** * Return the paint's text size. * @@ -1411,8 +1370,6 @@ public class Paint { return nGetTextSize(mNativePaint); } - private native float nGetTextSize(long paintPtr); - /** * Set the paint's text size. This value must be > 0 * @@ -1422,8 +1379,6 @@ public class Paint { nSetTextSize(mNativePaint, textSize); } - private native void nSetTextSize(long paintPtr, float textSize); - /** * Return the paint's horizontal scale factor for text. The default value * is 1.0. @@ -1434,8 +1389,6 @@ public class Paint { return nGetTextScaleX(mNativePaint); } - private native float nGetTextScaleX(long paintPtr); - /** * Set the paint's horizontal scale factor for text. The default value * is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will @@ -1447,8 +1400,6 @@ public class Paint { nSetTextScaleX(mNativePaint, scaleX); } - private native void nSetTextScaleX(long paintPtr, float scaleX); - /** * Return the paint's horizontal skew factor for text. The default value * is 0. @@ -1459,8 +1410,6 @@ public class Paint { return nGetTextSkewX(mNativePaint); } - private native float nGetTextSkewX(long paintPtr); - /** * Set the paint's horizontal skew factor for text. The default value * is 0. For approximating oblique text, use values around -0.25. @@ -1471,8 +1420,6 @@ public class Paint { nSetTextSkewX(mNativePaint, skewX); } - private native void nSetTextSkewX(long paintPtr, float skewX); - /** * Return the paint's letter-spacing for text. The default value * is 0. @@ -1565,8 +1512,6 @@ public class Paint { return nAscent(mNativePaint, mNativeTypeface); } - private native float nAscent(long paintPtr, long typefacePtr); - /** * Return the distance below (positive) the baseline (descent) based on the * current typeface and text size. @@ -1578,8 +1523,6 @@ public class Paint { return nDescent(mNativePaint, mNativeTypeface); } - private native float nDescent(long paintPtr, long typefacePtr); - /** * Class that describes the various metrics for a font at a given text size. * Remember, Y values increase going down, so those values will be positive, @@ -1624,9 +1567,6 @@ public class Paint { return nGetFontMetrics(mNativePaint, mNativeTypeface, metrics); } - private native float nGetFontMetrics(long paintPtr, - long typefacePtr, FontMetrics metrics); - /** * Allocates a new FontMetrics object, and then calls getFontMetrics(fm) * with it, returning the object. @@ -1686,9 +1626,6 @@ public class Paint { return nGetFontMetricsInt(mNativePaint, mNativeTypeface, fmi); } - private native int nGetFontMetricsInt(long paintPtr, - long typefacePtr, FontMetricsInt fmi); - public FontMetricsInt getFontMetricsInt() { FontMetricsInt fm = new FontMetricsInt(); getFontMetricsInt(fm); @@ -1860,10 +1797,6 @@ public class Paint { return res; } - private static native int nBreakText(long nObject, long nTypeface, - char[] text, int index, int count, - float maxWidth, int bidiFlags, float[] measuredWidth); - /** * Measure the text, stopping early if the measured width exceeds maxWidth. * Return the number of chars that were measured, and if measuredWidth is @@ -1952,10 +1885,6 @@ public class Paint { return res; } - private static native int nBreakText(long nObject, long nTypeface, - String text, boolean measureForwards, - float maxWidth, int bidiFlags, float[] measuredWidth); - /** * Return the advance widths for the characters in the string. * @@ -2679,73 +2608,34 @@ public class Paint { return result; } + // regular JNI + private static native long nGetNativeFinalizer(); private static native long nInit(); private static native long nInitWithPaint(long paint); - private static native void nReset(long paintPtr); - private static native void nSet(long paintPtrDest, long paintPtrSrc); - private static native int nGetStyle(long paintPtr); - private static native void nSetStyle(long paintPtr, int style); - private static native int nGetStrokeCap(long paintPtr); - private static native void nSetStrokeCap(long paintPtr, int cap); - private static native int nGetStrokeJoin(long paintPtr); - private static native void nSetStrokeJoin(long paintPtr, - int join); - private static native boolean nGetFillPath(long paintPtr, - long src, long dst); - private static native long nSetShader(long paintPtr, long shader); - private static native long nSetColorFilter(long paintPtr, - long filter); - private static native void nSetXfermode(long paintPtr, int xfermode); - private static native long nSetPathEffect(long paintPtr, - long effect); - private static native long nSetMaskFilter(long paintPtr, - long maskfilter); - private static native long nSetTypeface(long paintPtr, - long typeface); - private static native long nSetRasterizer(long paintPtr, - long rasterizer); - - private static native int nGetTextAlign(long paintPtr); - private static native void nSetTextAlign(long paintPtr, - int align); - - private static native int nSetTextLocales(long paintPtr, String locales); - private static native void nSetTextLocalesByMinikinLangListId(long paintPtr, - int mMinikinLangListId); - + private static native int nBreakText(long nObject, long nTypeface, + char[] text, int index, int count, + float maxWidth, int bidiFlags, float[] measuredWidth); + private static native int nBreakText(long nObject, long nTypeface, + String text, boolean measureForwards, + float maxWidth, int bidiFlags, float[] measuredWidth); private static native float nGetTextAdvances(long paintPtr, long typefacePtr, char[] text, int index, int count, int contextIndex, int contextCount, int bidiFlags, float[] advances, int advancesIndex); private static native float nGetTextAdvances(long paintPtr, long typefacePtr, String text, int start, int end, int contextStart, int contextEnd, int bidiFlags, float[] advances, int advancesIndex); - private native int nGetTextRunCursor(long paintPtr, char[] text, int contextStart, int contextLength, int dir, int offset, int cursorOpt); private native int nGetTextRunCursor(long paintPtr, String text, int contextStart, int contextEnd, int dir, int offset, int cursorOpt); - private static native void nGetTextPath(long paintPtr, long typefacePtr, int bidiFlags, char[] text, int index, int count, float x, float y, long path); private static native void nGetTextPath(long paintPtr, long typefacePtr, int bidiFlags, String text, int start, int end, float x, float y, long path); private static native void nGetStringBounds(long nativePaint, long typefacePtr, - String text, int start, int end, int bidiFlags, Rect bounds); + String text, int start, int end, int bidiFlags, Rect bounds); private static native void nGetCharArrayBounds(long nativePaint, long typefacePtr, - char[] text, int index, int count, int bidiFlags, Rect bounds); - private static native long nGetNativeFinalizer(); - - private static native void nSetShadowLayer(long paintPtr, - float radius, float dx, float dy, int color); - private static native boolean nHasShadowLayer(long paintPtr); - - private static native float nGetLetterSpacing(long paintPtr); - private static native void nSetLetterSpacing(long paintPtr, - float letterSpacing); - private static native void nSetFontFeatureSettings(long paintPtr, - String settings); - private static native int nGetHyphenEdit(long paintPtr); - private static native void nSetHyphenEdit(long paintPtr, int hyphen); + char[] text, int index, int count, int bidiFlags, Rect bounds); private static native boolean nHasGlyph(long paintPtr, long typefacePtr, int bidiFlags, String string); private static native float nGetRunAdvance(long paintPtr, long typefacePtr, @@ -2754,4 +2644,134 @@ public class Paint { private static native int nGetOffsetForAdvance(long paintPtr, long typefacePtr, char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl, float advance); + + + // ---------------- @FastNative ------------------------ + + @FastNative + private static native int nSetTextLocales(long paintPtr, String locales); + @FastNative + private static native void nSetFontFeatureSettings(long paintPtr, String settings); + @FastNative + private static native float nGetFontMetrics(long paintPtr, + long typefacePtr, FontMetrics metrics); + @FastNative + private static native int nGetFontMetricsInt(long paintPtr, + long typefacePtr, FontMetricsInt fmi); + + + // ---------------- @CriticalNative ------------------------ + + @CriticalNative + private static native void nReset(long paintPtr); + @CriticalNative + private static native void nSet(long paintPtrDest, long paintPtrSrc); + @CriticalNative + private static native int nGetStyle(long paintPtr); + @CriticalNative + private static native void nSetStyle(long paintPtr, int style); + @CriticalNative + private static native int nGetStrokeCap(long paintPtr); + @CriticalNative + private static native void nSetStrokeCap(long paintPtr, int cap); + @CriticalNative + private static native int nGetStrokeJoin(long paintPtr); + @CriticalNative + private static native void nSetStrokeJoin(long paintPtr, int join); + @CriticalNative + private static native boolean nGetFillPath(long paintPtr, long src, long dst); + @CriticalNative + private static native long nSetShader(long paintPtr, long shader); + @CriticalNative + private static native long nSetColorFilter(long paintPtr, long filter); + @CriticalNative + private static native void nSetXfermode(long paintPtr, int xfermode); + @CriticalNative + private static native long nSetPathEffect(long paintPtr, long effect); + @CriticalNative + private static native long nSetMaskFilter(long paintPtr, long maskfilter); + @CriticalNative + private static native long nSetTypeface(long paintPtr, long typeface); + @CriticalNative + private static native long nSetRasterizer(long paintPtr, long rasterizer); + @CriticalNative + private static native int nGetTextAlign(long paintPtr); + @CriticalNative + private static native void nSetTextAlign(long paintPtr, int align); + @CriticalNative + private static native void nSetTextLocalesByMinikinLangListId(long paintPtr, + int mMinikinLangListId); + @CriticalNative + private static native void nSetShadowLayer(long paintPtr, + float radius, float dx, float dy, int color); + @CriticalNative + private static native boolean nHasShadowLayer(long paintPtr); + @CriticalNative + private static native float nGetLetterSpacing(long paintPtr); + @CriticalNative + private static native void nSetLetterSpacing(long paintPtr, float letterSpacing); + @CriticalNative + private static native int nGetHyphenEdit(long paintPtr); + @CriticalNative + private static native void nSetHyphenEdit(long paintPtr, int hyphen); + @CriticalNative + private static native void nSetStrokeMiter(long paintPtr, float miter); + @CriticalNative + private static native float nGetStrokeMiter(long paintPtr); + @CriticalNative + private static native void nSetStrokeWidth(long paintPtr, float width); + @CriticalNative + private static native float nGetStrokeWidth(long paintPtr); + @CriticalNative + private static native void nSetAlpha(long paintPtr, int a); + @CriticalNative + private static native void nSetDither(long paintPtr, boolean dither); + @CriticalNative + private static native int nGetFlags(long paintPtr); + @CriticalNative + private static native void nSetFlags(long paintPtr, int flags); + @CriticalNative + private static native int nGetHinting(long paintPtr); + @CriticalNative + private static native void nSetHinting(long paintPtr, int mode); + @CriticalNative + private static native void nSetAntiAlias(long paintPtr, boolean aa); + @CriticalNative + private static native void nSetLinearText(long paintPtr, boolean linearText); + @CriticalNative + private static native void nSetSubpixelText(long paintPtr, boolean subpixelText); + @CriticalNative + private static native void nSetUnderlineText(long paintPtr, boolean underlineText); + @CriticalNative + private static native void nSetFakeBoldText(long paintPtr, boolean fakeBoldText); + @CriticalNative + private static native void nSetFilterBitmap(long paintPtr, boolean filter); + @CriticalNative + private static native int nGetColor(long paintPtr); + @CriticalNative + private static native void nSetColor(long paintPtr, @ColorInt int color); + @CriticalNative + private static native int nGetAlpha(long paintPtr); + @CriticalNative + private static native void nSetStrikeThruText(long paintPtr, boolean strikeThruText); + @CriticalNative + private static native boolean nIsElegantTextHeight(long paintPtr); + @CriticalNative + private static native void nSetElegantTextHeight(long paintPtr, boolean elegant); + @CriticalNative + private static native float nGetTextSize(long paintPtr); + @CriticalNative + private static native float nGetTextScaleX(long paintPtr); + @CriticalNative + private static native void nSetTextScaleX(long paintPtr, float scaleX); + @CriticalNative + private static native float nGetTextSkewX(long paintPtr); + @CriticalNative + private static native void nSetTextSkewX(long paintPtr, float skewX); + @CriticalNative + private static native float nAscent(long paintPtr, long typefacePtr); + @CriticalNative + private static native float nDescent(long paintPtr, long typefacePtr); + @CriticalNative + private static native void nSetTextSize(long paintPtr, float textSize); }