Loading core/jni/android/graphics/Paint.cpp +24 −161 Original line number Original line Diff line number Diff line Loading @@ -44,6 +44,7 @@ #include "TypefaceImpl.h" #include "TypefaceImpl.h" #include <vector> #include <vector> #include <memory> // temporary for debugging // temporary for debugging #include <Caches.h> #include <Caches.h> Loading Loading @@ -569,136 +570,8 @@ public: return descent - ascent + leading; return descent - ascent + leading; } } static jfloat measureText_CIII(JNIEnv* env, jobject jpaint, jcharArray text, jint index, jint count, static jfloat doTextAdvances(JNIEnv *env, Paint *paint, TypefaceImpl* typeface, jint bidiFlags) { const jchar *text, jint start, jint count, jint contextCount, jint bidiFlags, NPE_CHECK_RETURN_ZERO(env, jpaint); NPE_CHECK_RETURN_ZERO(env, text); size_t textLength = env->GetArrayLength(text); if ((index | count) < 0 || (size_t)(index + count) > textLength) { doThrowAIOOBE(env); return 0; } if (count == 0) { return 0; } Paint* paint = getNativePaint(env, jpaint); const jchar* textArray = env->GetCharArrayElements(text, NULL); jfloat result = 0; Layout layout; TypefaceImpl* typeface = getNativeTypeface(env, jpaint); MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray + index, 0, count, count); result = layout.getAdvance(); env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT); return result; } static jfloat measureText_StringIII(JNIEnv* env, jobject jpaint, jstring text, jint start, jint end, jint bidiFlags) { NPE_CHECK_RETURN_ZERO(env, jpaint); NPE_CHECK_RETURN_ZERO(env, text); size_t textLength = env->GetStringLength(text); int count = end - start; if ((start | count) < 0 || (size_t)end > textLength) { doThrowAIOOBE(env); return 0; } if (count == 0) { return 0; } const jchar* textArray = env->GetStringChars(text, NULL); Paint* paint = getNativePaint(env, jpaint); jfloat width = 0; Layout layout; TypefaceImpl* typeface = getNativeTypeface(env, jpaint); // Only the substring is used for measurement, so no additional context is passed in. This // behavior is consistent between char[] and String specializations. MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray + start, 0, count, count); width = layout.getAdvance(); env->ReleaseStringChars(text, textArray); return width; } static jfloat measureText_StringI(JNIEnv* env, jobject jpaint, jstring text, jint bidiFlags) { NPE_CHECK_RETURN_ZERO(env, jpaint); NPE_CHECK_RETURN_ZERO(env, text); size_t textLength = env->GetStringLength(text); if (textLength == 0) { return 0; } const jchar* textArray = env->GetStringChars(text, NULL); Paint* paint = getNativePaint(env, jpaint); jfloat width = 0; Layout layout; TypefaceImpl* typeface = getNativeTypeface(env, jpaint); MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray, 0, textLength, textLength); width = layout.getAdvance(); env->ReleaseStringChars(text, textArray); return width; } static int dotextwidths(JNIEnv* env, Paint* paint, TypefaceImpl* typeface, const jchar text[], int count, jfloatArray widths, jint bidiFlags) { NPE_CHECK_RETURN_ZERO(env, paint); NPE_CHECK_RETURN_ZERO(env, text); if (count < 0 || !widths) { doThrowAIOOBE(env); return 0; } if (count == 0) { return 0; } size_t widthsLength = env->GetArrayLength(widths); if ((size_t)count > widthsLength) { doThrowAIOOBE(env); return 0; } AutoJavaFloatArray autoWidths(env, widths, count); jfloat* widthsArray = autoWidths.ptr(); Layout layout; MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count); layout.getAdvances(widthsArray); return count; } static jint getTextWidths___CIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jcharArray text, jint index, jint count, jint bidiFlags, jfloatArray widths) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); const jchar* textArray = env->GetCharArrayElements(text, NULL); count = dotextwidths(env, paint, typeface, textArray + index, count, widths, bidiFlags); env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT); return count; } static jint getTextWidths__StringIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring text, jint start, jint end, jint bidiFlags, jfloatArray widths) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); const jchar* textArray = env->GetStringChars(text, NULL); int count = dotextwidths(env, paint, typeface, textArray + start, end - start, widths, bidiFlags); env->ReleaseStringChars(text, textArray); return count; } static jfloat doTextRunAdvances(JNIEnv *env, Paint *paint, TypefaceImpl* typeface, const jchar *text, jint start, jint count, jint contextCount, jboolean isRtl, jfloatArray advances, jint advancesIndex) { jfloatArray advances, jint advancesIndex) { NPE_CHECK_RETURN_ZERO(env, paint); NPE_CHECK_RETURN_ZERO(env, paint); NPE_CHECK_RETURN_ZERO(env, text); NPE_CHECK_RETURN_ZERO(env, text); Loading @@ -712,50 +585,45 @@ public: } } if (advances) { if (advances) { size_t advancesLength = env->GetArrayLength(advances); size_t advancesLength = env->GetArrayLength(advances); if ((size_t)count > advancesLength) { if ((size_t)(count + advancesIndex) > advancesLength) { doThrowAIOOBE(env); doThrowAIOOBE(env); return 0; return 0; } } } } jfloat* advancesArray = new jfloat[count]; jfloat totalAdvance = 0; int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; Layout layout; Layout layout; MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count, contextCount); MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count, layout.getAdvances(advancesArray); contextCount); totalAdvance = layout.getAdvance(); if (advances != NULL) { if (advances != NULL) { env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray); std::unique_ptr<jfloat> advancesArray(new jfloat[count]); layout.getAdvances(advancesArray.get()); env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray.get()); } } delete [] advancesArray; return layout.getAdvance(); return totalAdvance; } } static jfloat getTextRunAdvances___CIIIIZ_FI(JNIEnv* env, jobject clazz, jlong paintHandle, static jfloat getTextAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jlong typefaceHandle, jcharArray text, jint index, jint count, jint contextIndex, jint contextCount, jcharArray text, jint index, jint count, jint contextIndex, jint contextCount, jboolean isRtl, jfloatArray advances, jint advancesIndex) { jint bidiFlags, jfloatArray advances, jint advancesIndex) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); jchar* textArray = env->GetCharArrayElements(text, NULL); jchar* textArray = env->GetCharArrayElements(text, NULL); jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextIndex, jfloat result = doTextAdvances(env, paint, typeface, textArray + contextIndex, index - contextIndex, count, contextCount, isRtl, advances, advancesIndex); index - contextIndex, count, contextCount, bidiFlags, advances, advancesIndex); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); return result; return result; } } static jfloat getTextRunAdvances__StringIIIIZ_FI(JNIEnv* env, jobject clazz, jlong paintHandle, static jfloat getTextAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jlong typefaceHandle, jstring text, jint start, jint end, jint contextStart, jint contextEnd, jboolean isRtl, jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint bidiFlags, jfloatArray advances, jint advancesIndex) { jfloatArray advances, jint advancesIndex) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); const jchar* textArray = env->GetStringChars(text, NULL); const jchar* textArray = env->GetStringChars(text, NULL); jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextStart, jfloat result = doTextAdvances(env, paint, typeface, textArray + contextStart, start - contextStart, end - start, contextEnd - contextStart, isRtl, start - contextStart, end - start, contextEnd - contextStart, bidiFlags, advances, advancesIndex); advances, advancesIndex); env->ReleaseStringChars(text, textArray); env->ReleaseStringChars(text, textArray); return result; return result; Loading Loading @@ -1160,18 +1028,13 @@ static JNINativeMethod methods[] = { (void*)PaintGlue::getFontMetrics}, (void*)PaintGlue::getFontMetrics}, {"getFontMetricsInt", "!(Landroid/graphics/Paint$FontMetricsInt;)I", {"getFontMetricsInt", "!(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)PaintGlue::getFontMetricsInt}, (void*)PaintGlue::getFontMetricsInt}, {"native_measureText","([CIII)F", (void*) PaintGlue::measureText_CIII}, {"native_measureText","(Ljava/lang/String;I)F", (void*) PaintGlue::measureText_StringI}, {"native_measureText","(Ljava/lang/String;III)F", (void*) PaintGlue::measureText_StringIII}, {"native_breakText","(JJ[CIIFI[F)I", (void*) PaintGlue::breakTextC}, {"native_breakText","(JJ[CIIFI[F)I", (void*) PaintGlue::breakTextC}, {"native_breakText","(JJLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS}, {"native_breakText","(JJLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS}, {"native_getTextWidths","(JJ[CIII[F)I", (void*) PaintGlue::getTextWidths___CIII_F}, {"native_getTextAdvances","(JJ[CIIIII[FI)F", {"native_getTextWidths","(JJLjava/lang/String;III[F)I", (void*) PaintGlue::getTextAdvances___CIIIII_FI}, (void*) PaintGlue::getTextWidths__StringIII_F}, {"native_getTextAdvances","(JJLjava/lang/String;IIIII[FI)F", {"native_getTextRunAdvances","(JJ[CIIIIZ[FI)F", (void*) PaintGlue::getTextAdvances__StringIIIII_FI}, (void*) PaintGlue::getTextRunAdvances___CIIIIZ_FI}, {"native_getTextRunAdvances","(JJLjava/lang/String;IIIIZ[FI)F", (void*) PaintGlue::getTextRunAdvances__StringIIIIZ_FI}, {"native_getTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C}, {"native_getTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C}, {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I", {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I", Loading graphics/java/android/graphics/Paint.java +46 −57 Original line number Original line Diff line number Diff line Loading @@ -1526,18 +1526,18 @@ public class Paint { return 0f; return 0f; } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return (float) Math.ceil(native_measureText(text, index, count, mBidiFlags)); return (float) Math.ceil(native_getTextAdvances(mNativePaint, mNativeTypeface, text, index, count, index, count, mBidiFlags, null, 0)); } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); float w = native_measureText(text, index, count, mBidiFlags); float w = native_getTextAdvances(mNativePaint, mNativeTypeface, text, index, count, index, count, mBidiFlags, null, 0); setTextSize(oldSize); setTextSize(oldSize); return (float) Math.ceil(w*mInvCompatScaling); return (float) Math.ceil(w*mInvCompatScaling); } } private native float native_measureText(char[] text, int index, int count, int bidiFlags); /** /** * Return the width of the text. * Return the width of the text. * * Loading @@ -1558,18 +1558,17 @@ public class Paint { return 0f; return 0f; } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return (float) Math.ceil(native_measureText(text, start, end, mBidiFlags)); return (float) Math.ceil(native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, start, end, mBidiFlags, null, 0)); } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); float w = native_measureText(text, start, end, mBidiFlags); float w = native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, start, end, mBidiFlags, null, 0); setTextSize(oldSize); setTextSize(oldSize); return (float) Math.ceil(w * mInvCompatScaling); return (float) Math.ceil(w * mInvCompatScaling); } } private native float native_measureText(String text, int start, int end, int bidiFlags); /** /** * Return the width of the text. * Return the width of the text. * * Loading @@ -1580,23 +1579,9 @@ public class Paint { if (text == null) { if (text == null) { throw new IllegalArgumentException("text cannot be null"); throw new IllegalArgumentException("text cannot be null"); } } return measureText(text, 0, text.length()); if (text.length() == 0) { return 0f; } } if (!mHasCompatScaling) { return (float) Math.ceil(native_measureText(text, mBidiFlags)); } final float oldSize = getTextSize(); setTextSize(oldSize*mCompatScaling); float w = native_measureText(text, mBidiFlags); setTextSize(oldSize); return (float) Math.ceil(w*mInvCompatScaling); } private native float native_measureText(String text, int bidiFlags); /** /** * Return the width of the text. * Return the width of the text. * * Loading Loading @@ -1795,17 +1780,20 @@ public class Paint { return 0; return 0; } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return native_getTextWidths(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags, widths); native_getTextAdvances(mNativePaint, mNativeTypeface, text, index, count, index, count, mBidiFlags, widths, 0); return count; } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); int res = native_getTextWidths(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags, widths); native_getTextAdvances(mNativePaint, mNativeTypeface, text, index, count, index, count, mBidiFlags, widths, 0); setTextSize(oldSize); setTextSize(oldSize); for (int i=0; i<res; i++) { for (int i = 0; i < count; i++) { widths[i] *= mInvCompatScaling; widths[i] *= mInvCompatScaling; } } return res; return count; } } /** /** Loading Loading @@ -1860,7 +1848,7 @@ public class Paint { * @param end The end of the text slice to measure * @param end The end of the text slice to measure * @param widths array to receive the advance widths of the characters. * @param widths array to receive the advance widths of the characters. * Must be at least a large as the text. * Must be at least a large as the text. * @return the number of unichars in the specified text. * @return the number of code units in the specified text. */ */ public int getTextWidths(String text, int start, int end, float[] widths) { public int getTextWidths(String text, int start, int end, float[] widths) { if (text == null) { if (text == null) { Loading @@ -1877,17 +1865,20 @@ public class Paint { return 0; return 0; } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return native_getTextWidths(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, widths); native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, start, end, mBidiFlags, widths, 0); return end - start; } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); int res = native_getTextWidths(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, widths); native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, start, end, mBidiFlags, widths, 0); setTextSize(oldSize); setTextSize(oldSize); for (int i=0; i<res; i++) { for (int i = 0; i < end - start; i++) { widths[i] *= mInvCompatScaling; widths[i] *= mInvCompatScaling; } } return res; return end - start; } } /** /** Loading @@ -1896,7 +1887,7 @@ public class Paint { * @param text The text to measure * @param text The text to measure * @param widths array to receive the advance widths of the characters. * @param widths array to receive the advance widths of the characters. * Must be at least a large as the text. * Must be at least a large as the text. * @return the number of unichars in the specified text. * @return the number of code units in the specified text. */ */ public int getTextWidths(String text, float[] widths) { public int getTextWidths(String text, float[] widths) { return getTextWidths(text, 0, text.length(), widths); return getTextWidths(text, 0, text.length(), widths); Loading Loading @@ -1929,14 +1920,16 @@ public class Paint { return 0f; return 0f; } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return native_getTextRunAdvances(mNativePaint, mNativeTypeface, chars, index, count, return native_getTextAdvances(mNativePaint, mNativeTypeface, chars, index, count, contextIndex, contextCount, isRtl, advances, advancesIndex); contextIndex, contextCount, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances, advancesIndex); } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); float res = native_getTextRunAdvances(mNativePaint, mNativeTypeface, chars, index, count, float res = native_getTextAdvances(mNativePaint, mNativeTypeface, chars, index, count, contextIndex, contextCount, isRtl, advances, advancesIndex); contextIndex, contextCount, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances, advancesIndex); setTextSize(oldSize); setTextSize(oldSize); if (advances != null) { if (advances != null) { Loading Loading @@ -2039,7 +2032,6 @@ public class Paint { */ */ public float getTextRunAdvances(String text, int start, int end, int contextStart, public float getTextRunAdvances(String text, int start, int end, int contextStart, int contextEnd, boolean isRtl, float[] advances, int advancesIndex) { int contextEnd, boolean isRtl, float[] advances, int advancesIndex) { if (text == null) { if (text == null) { throw new IllegalArgumentException("text cannot be null"); throw new IllegalArgumentException("text cannot be null"); } } Loading @@ -2056,14 +2048,16 @@ public class Paint { } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return native_getTextRunAdvances(mNativePaint, mNativeTypeface, text, start, end, return native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, contextStart, contextEnd, isRtl, advances, advancesIndex); contextStart, contextEnd, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances, advancesIndex); } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); float totalAdvance = native_getTextRunAdvances(mNativePaint, mNativeTypeface, text, start, end, float totalAdvance = native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, contextStart, contextEnd, isRtl, advances, advancesIndex); end, contextStart, contextEnd, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances, advancesIndex); setTextSize(oldSize); setTextSize(oldSize); if (advances != null) { if (advances != null) { Loading Loading @@ -2510,21 +2504,16 @@ public class Paint { private static native void native_setTextLocale(long native_object, private static native void native_setTextLocale(long native_object, String locale); String locale); private static native int native_getTextWidths(long native_object, long native_typeface, char[] text, int index, int count, int bidiFlags, float[] widths); private static native int native_getTextWidths(long native_object, long native_typeface, String text, int start, int end, int bidiFlags, float[] widths); private static native int native_getTextGlyphs(long native_object, private static native int native_getTextGlyphs(long native_object, String text, int start, int end, int contextStart, int contextEnd, String text, int start, int end, int contextStart, int contextEnd, int flags, char[] glyphs); int flags, char[] glyphs); private static native float native_getTextRunAdvances(long native_object, long native_typeface, private static native float native_getTextAdvances(long native_object, long native_typeface, char[] text, int index, int count, int contextIndex, int contextCount, char[] text, int index, int count, int contextIndex, int contextCount, boolean isRtl, float[] advances, int advancesIndex); int bidiFlags, float[] advances, int advancesIndex); private static native float native_getTextRunAdvances(long native_object, long native_typeface, private static native float native_getTextAdvances(long native_object, long native_typeface, String text, int start, int end, int contextStart, int contextEnd, String text, int start, int end, int contextStart, int contextEnd, boolean isRtl, float[] advances, int advancesIndex); int bidiFlags, float[] advances, int advancesIndex); private native int native_getTextRunCursor(long native_object, char[] text, private native int native_getTextRunCursor(long native_object, char[] text, int contextStart, int contextLength, int dir, int offset, int cursorOpt); int contextStart, int contextLength, int dir, int offset, int cursorOpt); Loading Loading
core/jni/android/graphics/Paint.cpp +24 −161 Original line number Original line Diff line number Diff line Loading @@ -44,6 +44,7 @@ #include "TypefaceImpl.h" #include "TypefaceImpl.h" #include <vector> #include <vector> #include <memory> // temporary for debugging // temporary for debugging #include <Caches.h> #include <Caches.h> Loading Loading @@ -569,136 +570,8 @@ public: return descent - ascent + leading; return descent - ascent + leading; } } static jfloat measureText_CIII(JNIEnv* env, jobject jpaint, jcharArray text, jint index, jint count, static jfloat doTextAdvances(JNIEnv *env, Paint *paint, TypefaceImpl* typeface, jint bidiFlags) { const jchar *text, jint start, jint count, jint contextCount, jint bidiFlags, NPE_CHECK_RETURN_ZERO(env, jpaint); NPE_CHECK_RETURN_ZERO(env, text); size_t textLength = env->GetArrayLength(text); if ((index | count) < 0 || (size_t)(index + count) > textLength) { doThrowAIOOBE(env); return 0; } if (count == 0) { return 0; } Paint* paint = getNativePaint(env, jpaint); const jchar* textArray = env->GetCharArrayElements(text, NULL); jfloat result = 0; Layout layout; TypefaceImpl* typeface = getNativeTypeface(env, jpaint); MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray + index, 0, count, count); result = layout.getAdvance(); env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT); return result; } static jfloat measureText_StringIII(JNIEnv* env, jobject jpaint, jstring text, jint start, jint end, jint bidiFlags) { NPE_CHECK_RETURN_ZERO(env, jpaint); NPE_CHECK_RETURN_ZERO(env, text); size_t textLength = env->GetStringLength(text); int count = end - start; if ((start | count) < 0 || (size_t)end > textLength) { doThrowAIOOBE(env); return 0; } if (count == 0) { return 0; } const jchar* textArray = env->GetStringChars(text, NULL); Paint* paint = getNativePaint(env, jpaint); jfloat width = 0; Layout layout; TypefaceImpl* typeface = getNativeTypeface(env, jpaint); // Only the substring is used for measurement, so no additional context is passed in. This // behavior is consistent between char[] and String specializations. MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray + start, 0, count, count); width = layout.getAdvance(); env->ReleaseStringChars(text, textArray); return width; } static jfloat measureText_StringI(JNIEnv* env, jobject jpaint, jstring text, jint bidiFlags) { NPE_CHECK_RETURN_ZERO(env, jpaint); NPE_CHECK_RETURN_ZERO(env, text); size_t textLength = env->GetStringLength(text); if (textLength == 0) { return 0; } const jchar* textArray = env->GetStringChars(text, NULL); Paint* paint = getNativePaint(env, jpaint); jfloat width = 0; Layout layout; TypefaceImpl* typeface = getNativeTypeface(env, jpaint); MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray, 0, textLength, textLength); width = layout.getAdvance(); env->ReleaseStringChars(text, textArray); return width; } static int dotextwidths(JNIEnv* env, Paint* paint, TypefaceImpl* typeface, const jchar text[], int count, jfloatArray widths, jint bidiFlags) { NPE_CHECK_RETURN_ZERO(env, paint); NPE_CHECK_RETURN_ZERO(env, text); if (count < 0 || !widths) { doThrowAIOOBE(env); return 0; } if (count == 0) { return 0; } size_t widthsLength = env->GetArrayLength(widths); if ((size_t)count > widthsLength) { doThrowAIOOBE(env); return 0; } AutoJavaFloatArray autoWidths(env, widths, count); jfloat* widthsArray = autoWidths.ptr(); Layout layout; MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count); layout.getAdvances(widthsArray); return count; } static jint getTextWidths___CIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jcharArray text, jint index, jint count, jint bidiFlags, jfloatArray widths) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); const jchar* textArray = env->GetCharArrayElements(text, NULL); count = dotextwidths(env, paint, typeface, textArray + index, count, widths, bidiFlags); env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT); return count; } static jint getTextWidths__StringIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring text, jint start, jint end, jint bidiFlags, jfloatArray widths) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); const jchar* textArray = env->GetStringChars(text, NULL); int count = dotextwidths(env, paint, typeface, textArray + start, end - start, widths, bidiFlags); env->ReleaseStringChars(text, textArray); return count; } static jfloat doTextRunAdvances(JNIEnv *env, Paint *paint, TypefaceImpl* typeface, const jchar *text, jint start, jint count, jint contextCount, jboolean isRtl, jfloatArray advances, jint advancesIndex) { jfloatArray advances, jint advancesIndex) { NPE_CHECK_RETURN_ZERO(env, paint); NPE_CHECK_RETURN_ZERO(env, paint); NPE_CHECK_RETURN_ZERO(env, text); NPE_CHECK_RETURN_ZERO(env, text); Loading @@ -712,50 +585,45 @@ public: } } if (advances) { if (advances) { size_t advancesLength = env->GetArrayLength(advances); size_t advancesLength = env->GetArrayLength(advances); if ((size_t)count > advancesLength) { if ((size_t)(count + advancesIndex) > advancesLength) { doThrowAIOOBE(env); doThrowAIOOBE(env); return 0; return 0; } } } } jfloat* advancesArray = new jfloat[count]; jfloat totalAdvance = 0; int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; Layout layout; Layout layout; MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count, contextCount); MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count, layout.getAdvances(advancesArray); contextCount); totalAdvance = layout.getAdvance(); if (advances != NULL) { if (advances != NULL) { env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray); std::unique_ptr<jfloat> advancesArray(new jfloat[count]); layout.getAdvances(advancesArray.get()); env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray.get()); } } delete [] advancesArray; return layout.getAdvance(); return totalAdvance; } } static jfloat getTextRunAdvances___CIIIIZ_FI(JNIEnv* env, jobject clazz, jlong paintHandle, static jfloat getTextAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jlong typefaceHandle, jcharArray text, jint index, jint count, jint contextIndex, jint contextCount, jcharArray text, jint index, jint count, jint contextIndex, jint contextCount, jboolean isRtl, jfloatArray advances, jint advancesIndex) { jint bidiFlags, jfloatArray advances, jint advancesIndex) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); jchar* textArray = env->GetCharArrayElements(text, NULL); jchar* textArray = env->GetCharArrayElements(text, NULL); jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextIndex, jfloat result = doTextAdvances(env, paint, typeface, textArray + contextIndex, index - contextIndex, count, contextCount, isRtl, advances, advancesIndex); index - contextIndex, count, contextCount, bidiFlags, advances, advancesIndex); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); return result; return result; } } static jfloat getTextRunAdvances__StringIIIIZ_FI(JNIEnv* env, jobject clazz, jlong paintHandle, static jfloat getTextAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jlong typefaceHandle, jstring text, jint start, jint end, jint contextStart, jint contextEnd, jboolean isRtl, jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint bidiFlags, jfloatArray advances, jint advancesIndex) { jfloatArray advances, jint advancesIndex) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); const jchar* textArray = env->GetStringChars(text, NULL); const jchar* textArray = env->GetStringChars(text, NULL); jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextStart, jfloat result = doTextAdvances(env, paint, typeface, textArray + contextStart, start - contextStart, end - start, contextEnd - contextStart, isRtl, start - contextStart, end - start, contextEnd - contextStart, bidiFlags, advances, advancesIndex); advances, advancesIndex); env->ReleaseStringChars(text, textArray); env->ReleaseStringChars(text, textArray); return result; return result; Loading Loading @@ -1160,18 +1028,13 @@ static JNINativeMethod methods[] = { (void*)PaintGlue::getFontMetrics}, (void*)PaintGlue::getFontMetrics}, {"getFontMetricsInt", "!(Landroid/graphics/Paint$FontMetricsInt;)I", {"getFontMetricsInt", "!(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)PaintGlue::getFontMetricsInt}, (void*)PaintGlue::getFontMetricsInt}, {"native_measureText","([CIII)F", (void*) PaintGlue::measureText_CIII}, {"native_measureText","(Ljava/lang/String;I)F", (void*) PaintGlue::measureText_StringI}, {"native_measureText","(Ljava/lang/String;III)F", (void*) PaintGlue::measureText_StringIII}, {"native_breakText","(JJ[CIIFI[F)I", (void*) PaintGlue::breakTextC}, {"native_breakText","(JJ[CIIFI[F)I", (void*) PaintGlue::breakTextC}, {"native_breakText","(JJLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS}, {"native_breakText","(JJLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS}, {"native_getTextWidths","(JJ[CIII[F)I", (void*) PaintGlue::getTextWidths___CIII_F}, {"native_getTextAdvances","(JJ[CIIIII[FI)F", {"native_getTextWidths","(JJLjava/lang/String;III[F)I", (void*) PaintGlue::getTextAdvances___CIIIII_FI}, (void*) PaintGlue::getTextWidths__StringIII_F}, {"native_getTextAdvances","(JJLjava/lang/String;IIIII[FI)F", {"native_getTextRunAdvances","(JJ[CIIIIZ[FI)F", (void*) PaintGlue::getTextAdvances__StringIIIII_FI}, (void*) PaintGlue::getTextRunAdvances___CIIIIZ_FI}, {"native_getTextRunAdvances","(JJLjava/lang/String;IIIIZ[FI)F", (void*) PaintGlue::getTextRunAdvances__StringIIIIZ_FI}, {"native_getTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C}, {"native_getTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C}, {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I", {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I", Loading
graphics/java/android/graphics/Paint.java +46 −57 Original line number Original line Diff line number Diff line Loading @@ -1526,18 +1526,18 @@ public class Paint { return 0f; return 0f; } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return (float) Math.ceil(native_measureText(text, index, count, mBidiFlags)); return (float) Math.ceil(native_getTextAdvances(mNativePaint, mNativeTypeface, text, index, count, index, count, mBidiFlags, null, 0)); } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); float w = native_measureText(text, index, count, mBidiFlags); float w = native_getTextAdvances(mNativePaint, mNativeTypeface, text, index, count, index, count, mBidiFlags, null, 0); setTextSize(oldSize); setTextSize(oldSize); return (float) Math.ceil(w*mInvCompatScaling); return (float) Math.ceil(w*mInvCompatScaling); } } private native float native_measureText(char[] text, int index, int count, int bidiFlags); /** /** * Return the width of the text. * Return the width of the text. * * Loading @@ -1558,18 +1558,17 @@ public class Paint { return 0f; return 0f; } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return (float) Math.ceil(native_measureText(text, start, end, mBidiFlags)); return (float) Math.ceil(native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, start, end, mBidiFlags, null, 0)); } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); float w = native_measureText(text, start, end, mBidiFlags); float w = native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, start, end, mBidiFlags, null, 0); setTextSize(oldSize); setTextSize(oldSize); return (float) Math.ceil(w * mInvCompatScaling); return (float) Math.ceil(w * mInvCompatScaling); } } private native float native_measureText(String text, int start, int end, int bidiFlags); /** /** * Return the width of the text. * Return the width of the text. * * Loading @@ -1580,23 +1579,9 @@ public class Paint { if (text == null) { if (text == null) { throw new IllegalArgumentException("text cannot be null"); throw new IllegalArgumentException("text cannot be null"); } } return measureText(text, 0, text.length()); if (text.length() == 0) { return 0f; } } if (!mHasCompatScaling) { return (float) Math.ceil(native_measureText(text, mBidiFlags)); } final float oldSize = getTextSize(); setTextSize(oldSize*mCompatScaling); float w = native_measureText(text, mBidiFlags); setTextSize(oldSize); return (float) Math.ceil(w*mInvCompatScaling); } private native float native_measureText(String text, int bidiFlags); /** /** * Return the width of the text. * Return the width of the text. * * Loading Loading @@ -1795,17 +1780,20 @@ public class Paint { return 0; return 0; } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return native_getTextWidths(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags, widths); native_getTextAdvances(mNativePaint, mNativeTypeface, text, index, count, index, count, mBidiFlags, widths, 0); return count; } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); int res = native_getTextWidths(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags, widths); native_getTextAdvances(mNativePaint, mNativeTypeface, text, index, count, index, count, mBidiFlags, widths, 0); setTextSize(oldSize); setTextSize(oldSize); for (int i=0; i<res; i++) { for (int i = 0; i < count; i++) { widths[i] *= mInvCompatScaling; widths[i] *= mInvCompatScaling; } } return res; return count; } } /** /** Loading Loading @@ -1860,7 +1848,7 @@ public class Paint { * @param end The end of the text slice to measure * @param end The end of the text slice to measure * @param widths array to receive the advance widths of the characters. * @param widths array to receive the advance widths of the characters. * Must be at least a large as the text. * Must be at least a large as the text. * @return the number of unichars in the specified text. * @return the number of code units in the specified text. */ */ public int getTextWidths(String text, int start, int end, float[] widths) { public int getTextWidths(String text, int start, int end, float[] widths) { if (text == null) { if (text == null) { Loading @@ -1877,17 +1865,20 @@ public class Paint { return 0; return 0; } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return native_getTextWidths(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, widths); native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, start, end, mBidiFlags, widths, 0); return end - start; } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); int res = native_getTextWidths(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, widths); native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, start, end, mBidiFlags, widths, 0); setTextSize(oldSize); setTextSize(oldSize); for (int i=0; i<res; i++) { for (int i = 0; i < end - start; i++) { widths[i] *= mInvCompatScaling; widths[i] *= mInvCompatScaling; } } return res; return end - start; } } /** /** Loading @@ -1896,7 +1887,7 @@ public class Paint { * @param text The text to measure * @param text The text to measure * @param widths array to receive the advance widths of the characters. * @param widths array to receive the advance widths of the characters. * Must be at least a large as the text. * Must be at least a large as the text. * @return the number of unichars in the specified text. * @return the number of code units in the specified text. */ */ public int getTextWidths(String text, float[] widths) { public int getTextWidths(String text, float[] widths) { return getTextWidths(text, 0, text.length(), widths); return getTextWidths(text, 0, text.length(), widths); Loading Loading @@ -1929,14 +1920,16 @@ public class Paint { return 0f; return 0f; } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return native_getTextRunAdvances(mNativePaint, mNativeTypeface, chars, index, count, return native_getTextAdvances(mNativePaint, mNativeTypeface, chars, index, count, contextIndex, contextCount, isRtl, advances, advancesIndex); contextIndex, contextCount, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances, advancesIndex); } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); float res = native_getTextRunAdvances(mNativePaint, mNativeTypeface, chars, index, count, float res = native_getTextAdvances(mNativePaint, mNativeTypeface, chars, index, count, contextIndex, contextCount, isRtl, advances, advancesIndex); contextIndex, contextCount, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances, advancesIndex); setTextSize(oldSize); setTextSize(oldSize); if (advances != null) { if (advances != null) { Loading Loading @@ -2039,7 +2032,6 @@ public class Paint { */ */ public float getTextRunAdvances(String text, int start, int end, int contextStart, public float getTextRunAdvances(String text, int start, int end, int contextStart, int contextEnd, boolean isRtl, float[] advances, int advancesIndex) { int contextEnd, boolean isRtl, float[] advances, int advancesIndex) { if (text == null) { if (text == null) { throw new IllegalArgumentException("text cannot be null"); throw new IllegalArgumentException("text cannot be null"); } } Loading @@ -2056,14 +2048,16 @@ public class Paint { } } if (!mHasCompatScaling) { if (!mHasCompatScaling) { return native_getTextRunAdvances(mNativePaint, mNativeTypeface, text, start, end, return native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, contextStart, contextEnd, isRtl, advances, advancesIndex); contextStart, contextEnd, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances, advancesIndex); } } final float oldSize = getTextSize(); final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); setTextSize(oldSize * mCompatScaling); float totalAdvance = native_getTextRunAdvances(mNativePaint, mNativeTypeface, text, start, end, float totalAdvance = native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, contextStart, contextEnd, isRtl, advances, advancesIndex); end, contextStart, contextEnd, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances, advancesIndex); setTextSize(oldSize); setTextSize(oldSize); if (advances != null) { if (advances != null) { Loading Loading @@ -2510,21 +2504,16 @@ public class Paint { private static native void native_setTextLocale(long native_object, private static native void native_setTextLocale(long native_object, String locale); String locale); private static native int native_getTextWidths(long native_object, long native_typeface, char[] text, int index, int count, int bidiFlags, float[] widths); private static native int native_getTextWidths(long native_object, long native_typeface, String text, int start, int end, int bidiFlags, float[] widths); private static native int native_getTextGlyphs(long native_object, private static native int native_getTextGlyphs(long native_object, String text, int start, int end, int contextStart, int contextEnd, String text, int start, int end, int contextStart, int contextEnd, int flags, char[] glyphs); int flags, char[] glyphs); private static native float native_getTextRunAdvances(long native_object, long native_typeface, private static native float native_getTextAdvances(long native_object, long native_typeface, char[] text, int index, int count, int contextIndex, int contextCount, char[] text, int index, int count, int contextIndex, int contextCount, boolean isRtl, float[] advances, int advancesIndex); int bidiFlags, float[] advances, int advancesIndex); private static native float native_getTextRunAdvances(long native_object, long native_typeface, private static native float native_getTextAdvances(long native_object, long native_typeface, String text, int start, int end, int contextStart, int contextEnd, String text, int start, int end, int contextStart, int contextEnd, boolean isRtl, float[] advances, int advancesIndex); int bidiFlags, float[] advances, int advancesIndex); private native int native_getTextRunCursor(long native_object, char[] text, private native int native_getTextRunCursor(long native_object, char[] text, int contextStart, int contextLength, int dir, int offset, int cursorOpt); int contextStart, int contextLength, int dir, int offset, int cursorOpt); Loading