diff --git a/core/java/android/text/GraphicsOperations.java b/core/java/android/text/GraphicsOperations.java index 6e2168b21aee8..831ccc556bf92 100644 --- a/core/java/android/text/GraphicsOperations.java +++ b/core/java/android/text/GraphicsOperations.java @@ -61,8 +61,8 @@ extends CharSequence * Just like {@link Paint#getTextRunAdvances}. * @hide */ - float getTextRunAdvancesICU(int start, int end, int contextStart, int contextEnd, - int flags, float[] advances, int advancesIndex, Paint paint); + float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, + int flags, float[] advances, int advancesIndex, Paint paint, int reserved); /** * Just like {@link Paint#getTextRunCursor}. diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java index ff6a4cddef157..6b2d8e4e2377e 100644 --- a/core/java/android/text/SpannableStringBuilder.java +++ b/core/java/android/text/SpannableStringBuilder.java @@ -1173,8 +1173,8 @@ implements CharSequence, GetChars, Spannable, Editable, Appendable, * Don't call this yourself -- exists for Paint to use internally. * {@hide} */ - public float getTextRunAdvancesICU(int start, int end, int contextStart, int contextEnd, int flags, - float[] advances, int advancesPos, Paint p) { + public float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, int flags, + float[] advances, int advancesPos, Paint p, int reserved) { float ret; @@ -1182,16 +1182,16 @@ implements CharSequence, GetChars, Spannable, Editable, Appendable, int len = end - start; if (end <= mGapStart) { - ret = p.getTextRunAdvancesICU(mText, start, len, contextStart, contextLen, - flags, advances, advancesPos); + ret = p.getTextRunAdvances(mText, start, len, contextStart, contextLen, + flags, advances, advancesPos, reserved); } else if (start >= mGapStart) { - ret = p.getTextRunAdvancesICU(mText, start + mGapLength, len, - contextStart + mGapLength, contextLen, flags, advances, advancesPos); + ret = p.getTextRunAdvances(mText, start + mGapLength, len, + contextStart + mGapLength, contextLen, flags, advances, advancesPos, reserved); } else { char[] buf = TextUtils.obtain(contextLen); getChars(contextStart, contextEnd, buf, 0); - ret = p.getTextRunAdvancesICU(buf, start - contextStart, len, - 0, contextLen, flags, advances, advancesPos); + ret = p.getTextRunAdvances(buf, start - contextStart, len, + 0, contextLen, flags, advances, advancesPos, reserved); TextUtils.recycle(buf); } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 537709d1324d9..4a99e477ede4c 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -2967,14 +2967,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener advancesIndex); } - public float getTextRunAdvancesICU(int start, int end, int contextStart, + public float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, int flags, float[] advances, int advancesIndex, - Paint p) { + Paint p, int reserved) { int count = end - start; int contextCount = contextEnd - contextStart; - return p.getTextRunAdvancesICU(mChars, start + mStart, count, + return p.getTextRunAdvances(mChars, start + mStart, count, contextStart + mStart, contextCount, flags, advances, - advancesIndex); + advancesIndex, reserved); } public int getTextRunCursor(int contextStart, int contextEnd, int flags, diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 0a54e17de1d74..768b836b24388 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -482,44 +482,28 @@ public: return totalAdvance; } - static float getTextRunAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, SkPaint* paint, + static float getTextRunAdvances___CIIIII_FII(JNIEnv* env, jobject clazz, SkPaint* paint, jcharArray text, jint index, jint count, jint contextIndex, jint contextCount, - jint flags, jfloatArray advances, jint advancesIndex) { + jint flags, jfloatArray advances, jint advancesIndex, jint reserved) { jchar* textArray = env->GetCharArrayElements(text, NULL); - jfloat result = doTextRunAdvances(env, paint, textArray + contextIndex, - index - contextIndex, count, contextCount, flags, advances, advancesIndex); + jfloat result = (reserved == 0) ? + doTextRunAdvances(env, paint, textArray + contextIndex, index - contextIndex, + count, contextCount, flags, advances, advancesIndex) : + doTextRunAdvancesICU(env, paint, textArray + contextIndex, index - contextIndex, + count, contextCount, flags, advances, advancesIndex); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); return result; } - static float getTextRunAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, SkPaint* paint, + static float getTextRunAdvances__StringIIIII_FII(JNIEnv* env, jobject clazz, SkPaint* paint, jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags, - jfloatArray advances, jint advancesIndex) { + jfloatArray advances, jint advancesIndex, jint reserved) { const jchar* textArray = env->GetStringChars(text, NULL); - jfloat result = doTextRunAdvances(env, paint, textArray + contextStart, - start - contextStart, end - start, contextEnd - contextStart, flags, advances, - advancesIndex); - env->ReleaseStringChars(text, textArray); - return result; - } - - static float getTextRunAdvancesICU___CIIIII_FI(JNIEnv* env, jobject clazz, SkPaint* paint, - jcharArray text, jint index, jint count, jint contextIndex, jint contextCount, - jint flags, jfloatArray advances, jint advancesIndex) { - jchar* textArray = env->GetCharArrayElements(text, NULL); - jfloat result = doTextRunAdvancesICU(env, paint, textArray + contextIndex, - index - contextIndex, count, contextCount, flags, advances, advancesIndex); - env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); - return result; - } - - static float getTextRunAdvancesICU__StringIIIII_FI(JNIEnv* env, jobject clazz, SkPaint* paint, - jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags, - jfloatArray advances, jint advancesIndex) { - const jchar* textArray = env->GetStringChars(text, NULL); - jfloat result = doTextRunAdvancesICU(env, paint, textArray + contextStart, - start - contextStart, end - start, contextEnd - contextStart, flags, advances, - advancesIndex); + jfloat result = (reserved == 0) ? + doTextRunAdvances(env, paint, textArray + contextStart, start - contextStart, + end - start, contextEnd - contextStart, flags, advances, advancesIndex) : + doTextRunAdvancesICU(env, paint, textArray + contextStart, start - contextStart, + end - start, contextEnd - contextStart, flags, advances, advancesIndex); env->ReleaseStringChars(text, textArray); return result; } @@ -816,14 +800,12 @@ static JNINativeMethod methods[] = { {"native_breakText","(Ljava/lang/String;ZF[F)I", (void*) SkPaintGlue::breakTextS}, {"native_getTextWidths","(I[CII[F)I", (void*) SkPaintGlue::getTextWidths___CII_F}, {"native_getTextWidths","(ILjava/lang/String;II[F)I", (void*) SkPaintGlue::getTextWidths__StringII_F}, - {"native_getTextRunAdvances","(I[CIIIII[FI)F", - (void*) SkPaintGlue::getTextRunAdvances___CIIIII_FI}, - {"native_getTextRunAdvances","(ILjava/lang/String;IIIII[FI)F", - (void*) SkPaintGlue::getTextRunAdvances__StringIIIII_FI}, - {"native_getTextRunAdvancesICU","(I[CIIIII[FI)F", - (void*) SkPaintGlue::getTextRunAdvancesICU___CIIIII_FI}, - {"native_getTextRunAdvancesICU","(ILjava/lang/String;IIIII[FI)F", - (void*) SkPaintGlue::getTextRunAdvancesICU__StringIIIII_FI}, + {"native_getTextRunAdvances","(I[CIIIII[FII)F", + (void*) SkPaintGlue::getTextRunAdvances___CIIIII_FII}, + {"native_getTextRunAdvances","(ILjava/lang/String;IIIII[FII)F", + (void*) SkPaintGlue::getTextRunAdvances__StringIIIII_FII}, + + {"native_getTextGlyphs","(ILjava/lang/String;IIIII[C)I", (void*) SkPaintGlue::getTextGlyphs__StringIIIII_C}, {"native_getTextRunCursor", "(I[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C}, diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 0949beb812e1b..962f22cde441a 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -1501,6 +1501,20 @@ public class Paint { public float getTextRunAdvances(char[] chars, int index, int count, int contextIndex, int contextCount, int flags, float[] advances, int advancesIndex) { + return getTextRunAdvances(chars, index, count, contextIndex, contextCount, flags, + advances, advancesIndex, 0 /* use Harfbuzz*/); + } + + /** + * Convenience overload that takes a char array instead of a + * String. + * + * @see #getTextRunAdvances(String, int, int, int, int, int, float[], int, int) + * @hide + */ + public float getTextRunAdvances(char[] chars, int index, int count, + int contextIndex, int contextCount, int flags, float[] advances, + int advancesIndex, int reserved) { if ((index | count | contextIndex | contextCount | advancesIndex | (index - contextIndex) @@ -1516,55 +1530,13 @@ public class Paint { if (!mHasCompatScaling) { return native_getTextRunAdvances(mNativePaint, chars, index, count, - contextIndex, contextCount, flags, advances, advancesIndex); + contextIndex, contextCount, flags, advances, advancesIndex, reserved); } final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); float res = native_getTextRunAdvances(mNativePaint, chars, index, count, - contextIndex, contextCount, flags, advances, advancesIndex); - setTextSize(oldSize); - - if (advances != null) { - for (int i = advancesIndex, e = i + count; i < e; i++) { - advances[i] *= mInvCompatScaling; - } - } - return res * mInvCompatScaling; // assume errors are not significant - } - - /** - * Convenience overload that takes a char array instead of a - * String. - * - * @see #getTextRunAdvances(String, int, int, int, int, int, float[], int) - * @hide - */ - public float getTextRunAdvancesICU(char[] chars, int index, int count, - int contextIndex, int contextCount, int flags, float[] advances, - int advancesIndex) { - - if ((index | count | contextIndex | contextCount | advancesIndex - | (index - contextIndex) - | ((contextIndex + contextCount) - (index + count)) - | (chars.length - (contextIndex + contextCount)) - | (advances == null ? 0 : - (advances.length - (advancesIndex + count)))) < 0) { - throw new IndexOutOfBoundsException(); - } - if (flags != DIRECTION_LTR && flags != DIRECTION_RTL) { - throw new IllegalArgumentException("unknown flags value: " + flags); - } - - if (!mHasCompatScaling) { - return native_getTextRunAdvancesICU(mNativePaint, chars, index, count, - contextIndex, contextCount, flags, advances, advancesIndex); - } - - final float oldSize = getTextSize(); - setTextSize(oldSize * mCompatScaling); - float res = native_getTextRunAdvancesICU(mNativePaint, chars, index, count, - contextIndex, contextCount, flags, advances, advancesIndex); + contextIndex, contextCount, flags, advances, advancesIndex, reserved); setTextSize(oldSize); if (advances != null) { @@ -1585,15 +1557,29 @@ public class Paint { public float getTextRunAdvances(CharSequence text, int start, int end, int contextStart, int contextEnd, int flags, float[] advances, int advancesIndex) { + return getTextRunAdvances(text, start, end, contextStart, contextEnd, flags, + advances, advancesIndex, 0 /* use Harfbuzz */); + } + + /** + * Convenience overload that takes a CharSequence instead of a + * String. + * + * @see #getTextRunAdvances(String, int, int, int, int, int, float[], int) + * @hide + */ + public float getTextRunAdvances(CharSequence text, int start, int end, + int contextStart, int contextEnd, int flags, float[] advances, + int advancesIndex, int reserved) { if (text instanceof String) { return getTextRunAdvances((String) text, start, end, - contextStart, contextEnd, flags, advances, advancesIndex); + contextStart, contextEnd, flags, advances, advancesIndex, reserved); } if (text instanceof SpannedString || text instanceof SpannableString) { return getTextRunAdvances(text.toString(), start, end, - contextStart, contextEnd, flags, advances, advancesIndex); + contextStart, contextEnd, flags, advances, advancesIndex, reserved); } if (text instanceof GraphicsOperations) { return ((GraphicsOperations) text).getTextRunAdvances(start, end, @@ -1605,42 +1591,7 @@ public class Paint { char[] buf = TemporaryBuffer.obtain(contextLen); TextUtils.getChars(text, start, end, buf, 0); float result = getTextRunAdvances(buf, start - contextStart, len, - 0, contextLen, flags, advances, advancesIndex); - TemporaryBuffer.recycle(buf); - return result; - } - - /** - * Convenience overload that takes a CharSequence instead of a - * String. - * - * @see #getTextRunAdvances(String, int, int, int, int, int, float[], int) - * @hide - */ - public float getTextRunAdvancesICU(CharSequence text, int start, int end, - int contextStart, int contextEnd, int flags, float[] advances, - int advancesIndex) { - - if (text instanceof String) { - return getTextRunAdvancesICU((String) text, start, end, - contextStart, contextEnd, flags, advances, advancesIndex); - } - if (text instanceof SpannedString || - text instanceof SpannableString) { - return getTextRunAdvancesICU(text.toString(), start, end, - contextStart, contextEnd, flags, advances, advancesIndex); - } - if (text instanceof GraphicsOperations) { - return ((GraphicsOperations) text).getTextRunAdvancesICU(start, end, - contextStart, contextEnd, flags, advances, advancesIndex, this); - } - - int contextLen = contextEnd - contextStart; - int len = end - start; - char[] buf = TemporaryBuffer.obtain(contextLen); - TextUtils.getChars(text, start, end, buf, 0); - float result = getTextRunAdvancesICU(buf, start - contextStart, len, - 0, contextLen, flags, advances, advancesIndex); + 0, contextLen, flags, advances, advancesIndex, reserved); TemporaryBuffer.recycle(buf); return result; } @@ -1689,6 +1640,55 @@ public class Paint { */ public float getTextRunAdvances(String text, int start, int end, int contextStart, int contextEnd, int flags, float[] advances, int advancesIndex) { + return getTextRunAdvances(text, start, end, contextStart, contextEnd, flags, + advances, advancesIndex, 0 /* use Harfbuzz*/); + } + + /** + * Returns the total advance width for the characters in the run + * between start and end, and if advances is not null, the advance + * assigned to each of these characters (java chars). + * + *

The trailing surrogate in a valid surrogate pair is assigned + * an advance of 0. Thus the number of returned advances is + * always equal to count, not to the number of unicode codepoints + * represented by the run. + * + *

In the case of conjuncts or combining marks, the total + * advance is assigned to the first logical character, and the + * following characters are assigned an advance of 0. + * + *

This generates the sum of the advances of glyphs for + * characters in a reordered cluster as the width of the first + * logical character in the cluster, and 0 for the widths of all + * other characters in the cluster. In effect, such clusters are + * treated like conjuncts. + * + *

The shaping bounds limit the amount of context available + * outside start and end that can be used for shaping analysis. + * These bounds typically reflect changes in bidi level or font + * metrics across which shaping does not occur. + * + * @param text the text to measure + * @param start the index of the first character to measure + * @param end the index past the last character to measure + * @param contextStart the index of the first character to use for shaping context, + * must be <= start + * @param contextEnd the index past the last character to use for shaping context, + * must be >= end + * @param flags the flags to control the advances, either {@link #DIRECTION_LTR} + * or {@link #DIRECTION_RTL} + * @param advances array to receive the advances, must have room for all advances, + * can be null if only total advance is needed + * @param advancesIndex the position in advances at which to put the + * advance corresponding to the character at start + * @param reserved int reserved value + * @return the total advance + * + * @hide + */ + public float getTextRunAdvances(String text, int start, int end, int contextStart, + int contextEnd, int flags, float[] advances, int advancesIndex, int reserved) { if ((start | end | contextStart | contextEnd | advancesIndex | (end - start) | (start - contextStart) | (contextEnd - end) @@ -1703,51 +1703,13 @@ public class Paint { if (!mHasCompatScaling) { return native_getTextRunAdvances(mNativePaint, text, start, end, - contextStart, contextEnd, flags, advances, advancesIndex); + contextStart, contextEnd, flags, advances, advancesIndex, reserved); } final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); float totalAdvance = native_getTextRunAdvances(mNativePaint, text, start, end, - contextStart, contextEnd, flags, advances, advancesIndex); - setTextSize(oldSize); - - if (advances != null) { - for (int i = advancesIndex, e = i + (end - start); i < e; i++) { - advances[i] *= mInvCompatScaling; - } - } - return totalAdvance * mInvCompatScaling; // assume errors are insignificant - } - - /** - * Temporary - DO NOT USE - * - * @hide - */ - public float getTextRunAdvancesICU(String text, int start, int end, int contextStart, - int contextEnd, int flags, float[] advances, int advancesIndex) { - - if ((start | end | contextStart | contextEnd | advancesIndex | (end - start) - | (start - contextStart) | (contextEnd - end) - | (text.length() - contextEnd) - | (advances == null ? 0 : - (advances.length - advancesIndex - (end - start)))) < 0) { - throw new IndexOutOfBoundsException(); - } - if (flags != DIRECTION_LTR && flags != DIRECTION_RTL) { - throw new IllegalArgumentException("unknown flags value: " + flags); - } - - if (!mHasCompatScaling) { - return native_getTextRunAdvancesICU(mNativePaint, text, start, end, - contextStart, contextEnd, flags, advances, advancesIndex); - } - - final float oldSize = getTextSize(); - setTextSize(oldSize * mCompatScaling); - float totalAdvance = native_getTextRunAdvances(mNativePaint, text, start, end, - contextStart, contextEnd, flags, advances, advancesIndex); + contextStart, contextEnd, flags, advances, advancesIndex, reserved); setTextSize(oldSize); if (advances != null) { @@ -2017,17 +1979,10 @@ public class Paint { private static native float native_getTextRunAdvances(int native_object, char[] text, int index, int count, int contextIndex, int contextCount, - int flags, float[] advances, int advancesIndex); + int flags, float[] advances, int advancesIndex, int reserved); private static native float native_getTextRunAdvances(int native_object, String text, int start, int end, int contextStart, int contextEnd, - int flags, float[] advances, int advancesIndex); - - private static native float native_getTextRunAdvancesICU(int native_object, - char[] text, int index, int count, int contextIndex, int contextCount, - int flags, float[] advances, int advancesIndex); - private static native float native_getTextRunAdvancesICU(int native_object, - String text, int start, int end, int contextStart, int contextEnd, - int flags, float[] advances, int advancesIndex); + int flags, float[] advances, int advancesIndex, int reserved); private native int native_getTextRunCursor(int native_object, char[] text, int contextStart, int contextLength, int flags, int offset, int cursorOpt); diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java index 2f9b026914bc4..76031a81d1ecc 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java @@ -153,7 +153,8 @@ public class BiDiTestView extends View { float[] advances = new float[length]; float textWidthHB = paint.getTextRunAdvances(text, 0, length, 0, length, dir, advances, 0); setPaintDir(paint, dir); - float textWidthICU = paint.getTextRunAdvancesICU(text, 0, length, 0, length, dir, advances, 0); + float textWidthICU = paint.getTextRunAdvances(text, 0, length, 0, length, dir, advances, 0, + 1 /* use ICU */); logAdvances(text, textWidthHB, textWidthICU, advances); drawMetricsAroundText(canvas, x, y, textWidthHB, textWidthICU, textSize, Color.RED, Color.GREEN);