Consolidate native methods for text measurement.
Bug: 24505153
Change-Id: I6a00b0516442f7d6108ed0598516365310bd85e8
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 988d13a..93c2160 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -44,6 +44,7 @@
#include "TypefaceImpl.h"
#include <vector>
+#include <memory>
// temporary for debugging
#include <Caches.h>
@@ -569,137 +570,9 @@
return descent - ascent + leading;
}
- static jfloat measureText_CIII(JNIEnv* env, jobject jpaint, jcharArray text, jint index, jint count,
- 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) {
+ static jfloat doTextAdvances(JNIEnv *env, Paint *paint, TypefaceImpl* typeface,
+ const jchar *text, jint start, jint count, jint contextCount, jint bidiFlags,
+ jfloatArray advances, jint advancesIndex) {
NPE_CHECK_RETURN_ZERO(env, paint);
NPE_CHECK_RETURN_ZERO(env, text);
@@ -712,50 +585,45 @@
}
if (advances) {
size_t advancesLength = env->GetArrayLength(advances);
- if ((size_t)count > advancesLength) {
+ if ((size_t)(count + advancesIndex) > advancesLength) {
doThrowAIOOBE(env);
return 0;
}
}
- jfloat* advancesArray = new jfloat[count];
- jfloat totalAdvance = 0;
-
- int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
Layout layout;
- MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count, contextCount);
- layout.getAdvances(advancesArray);
- totalAdvance = layout.getAdvance();
-
+ MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count,
+ contextCount);
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 totalAdvance;
+ return layout.getAdvance();
}
- static jfloat getTextRunAdvances___CIIIIZ_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
+ static jfloat getTextAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
jlong typefaceHandle,
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);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
jchar* textArray = env->GetCharArrayElements(text, NULL);
- jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextIndex,
- index - contextIndex, count, contextCount, isRtl, advances, advancesIndex);
+ jfloat result = doTextAdvances(env, paint, typeface, textArray + contextIndex,
+ index - contextIndex, count, contextCount, bidiFlags, advances, advancesIndex);
env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
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,
- 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) {
Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
const jchar* textArray = env->GetStringChars(text, NULL);
- jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextStart,
- start - contextStart, end - start, contextEnd - contextStart, isRtl,
+ jfloat result = doTextAdvances(env, paint, typeface, textArray + contextStart,
+ start - contextStart, end - start, contextEnd - contextStart, bidiFlags,
advances, advancesIndex);
env->ReleaseStringChars(text, textArray);
return result;
@@ -1160,18 +1028,13 @@
(void*)PaintGlue::getFontMetrics},
{"getFontMetricsInt", "!(Landroid/graphics/Paint$FontMetricsInt;)I",
(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","(JJLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS},
- {"native_getTextWidths","(JJ[CIII[F)I", (void*) PaintGlue::getTextWidths___CIII_F},
- {"native_getTextWidths","(JJLjava/lang/String;III[F)I",
- (void*) PaintGlue::getTextWidths__StringIII_F},
- {"native_getTextRunAdvances","(JJ[CIIIIZ[FI)F",
- (void*) PaintGlue::getTextRunAdvances___CIIIIZ_FI},
- {"native_getTextRunAdvances","(JJLjava/lang/String;IIIIZ[FI)F",
- (void*) PaintGlue::getTextRunAdvances__StringIIIIZ_FI},
+ {"native_getTextAdvances","(JJ[CIIIII[FI)F",
+ (void*) PaintGlue::getTextAdvances___CIIIII_FI},
+ {"native_getTextAdvances","(JJLjava/lang/String;IIIII[FI)F",
+ (void*) PaintGlue::getTextAdvances__StringIIIII_FI},
{"native_getTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C},
{"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I",
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index ce35b87..cdbc1b1 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1526,18 +1526,18 @@
return 0f;
}
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();
- setTextSize(oldSize*mCompatScaling);
- float w = native_measureText(text, index, count, mBidiFlags);
+ setTextSize(oldSize * mCompatScaling);
+ float w = native_getTextAdvances(mNativePaint, mNativeTypeface, text, index, count, index,
+ count, mBidiFlags, null, 0);
setTextSize(oldSize);
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.
*
@@ -1558,18 +1558,17 @@
return 0f;
}
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();
- setTextSize(oldSize*mCompatScaling);
- float w = native_measureText(text, start, end, mBidiFlags);
+ setTextSize(oldSize * mCompatScaling);
+ float w = native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, start,
+ end, mBidiFlags, null, 0);
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.
*
@@ -1580,23 +1579,9 @@
if (text == null) {
throw new IllegalArgumentException("text cannot be null");
}
-
- 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);
+ return measureText(text, 0, text.length());
}
- private native float native_measureText(String text, int bidiFlags);
-
/**
* Return the width of the text.
*
@@ -1795,17 +1780,20 @@
return 0;
}
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();
- setTextSize(oldSize*mCompatScaling);
- int res = native_getTextWidths(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags, widths);
+ setTextSize(oldSize * mCompatScaling);
+ native_getTextAdvances(mNativePaint, mNativeTypeface, text, index, count, index, count,
+ mBidiFlags, widths, 0);
setTextSize(oldSize);
- for (int i=0; i<res; i++) {
+ for (int i = 0; i < count; i++) {
widths[i] *= mInvCompatScaling;
}
- return res;
+ return count;
}
/**
@@ -1860,7 +1848,7 @@
* @param end The end of the text slice to measure
* @param widths array to receive the advance widths of the characters.
* 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) {
if (text == null) {
@@ -1877,17 +1865,20 @@
return 0;
}
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();
- setTextSize(oldSize*mCompatScaling);
- int res = native_getTextWidths(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, widths);
+ setTextSize(oldSize * mCompatScaling);
+ native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end, start, end,
+ mBidiFlags, widths, 0);
setTextSize(oldSize);
- for (int i=0; i<res; i++) {
+ for (int i = 0; i < end - start; i++) {
widths[i] *= mInvCompatScaling;
}
- return res;
+ return end - start;
}
/**
@@ -1896,7 +1887,7 @@
* @param text The text to measure
* @param widths array to receive the advance widths of the characters.
* 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) {
return getTextWidths(text, 0, text.length(), widths);
@@ -1929,14 +1920,16 @@
return 0f;
}
if (!mHasCompatScaling) {
- return native_getTextRunAdvances(mNativePaint, mNativeTypeface, chars, index, count,
- contextIndex, contextCount, isRtl, advances, advancesIndex);
+ return native_getTextAdvances(mNativePaint, mNativeTypeface, chars, index, count,
+ contextIndex, contextCount, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances,
+ advancesIndex);
}
final float oldSize = getTextSize();
setTextSize(oldSize * mCompatScaling);
- float res = native_getTextRunAdvances(mNativePaint, mNativeTypeface, chars, index, count,
- contextIndex, contextCount, isRtl, advances, advancesIndex);
+ float res = native_getTextAdvances(mNativePaint, mNativeTypeface, chars, index, count,
+ contextIndex, contextCount, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances,
+ advancesIndex);
setTextSize(oldSize);
if (advances != null) {
@@ -2039,7 +2032,6 @@
*/
public float getTextRunAdvances(String text, int start, int end, int contextStart,
int contextEnd, boolean isRtl, float[] advances, int advancesIndex) {
-
if (text == null) {
throw new IllegalArgumentException("text cannot be null");
}
@@ -2056,14 +2048,16 @@
}
if (!mHasCompatScaling) {
- return native_getTextRunAdvances(mNativePaint, mNativeTypeface, text, start, end,
- contextStart, contextEnd, isRtl, advances, advancesIndex);
+ return native_getTextAdvances(mNativePaint, mNativeTypeface, text, start, end,
+ contextStart, contextEnd, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances,
+ advancesIndex);
}
final float oldSize = getTextSize();
setTextSize(oldSize * mCompatScaling);
- float totalAdvance = native_getTextRunAdvances(mNativePaint, mNativeTypeface, text, start, end,
- contextStart, contextEnd, isRtl, advances, advancesIndex);
+ float totalAdvance = native_getTextAdvances(mNativePaint, mNativeTypeface, text, start,
+ end, contextStart, contextEnd, isRtl ? BIDI_FORCE_RTL : BIDI_FORCE_LTR, advances,
+ advancesIndex);
setTextSize(oldSize);
if (advances != null) {
@@ -2510,21 +2504,16 @@
private static native void native_setTextLocale(long native_object,
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,
String text, int start, int end, int contextStart, int contextEnd,
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,
- boolean isRtl, float[] advances, int advancesIndex);
- private static native float native_getTextRunAdvances(long native_object, long native_typeface,
+ int bidiFlags, float[] advances, int advancesIndex);
+ private static native float native_getTextAdvances(long native_object, long native_typeface,
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,
int contextStart, int contextLength, int dir, int offset, int cursorOpt);