Loading core/java/android/text/GraphicsOperations.java +10 −3 Original line number Original line Diff line number Diff line Loading @@ -38,7 +38,7 @@ extends CharSequence * {@hide} * {@hide} */ */ void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, float x, float y, Paint p); float x, float y, int flags, Paint p); /** /** * Just like {@link Paint#measureText}. * Just like {@link Paint#measureText}. Loading @@ -55,12 +55,19 @@ extends CharSequence * @hide * @hide */ */ float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, float[] advances, int advancesIndex, Paint paint); int flags, float[] advances, int advancesIndex, Paint paint); /** * Just like {@link Paint#getTextRunAdvances}. * @hide */ 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}. * Just like {@link Paint#getTextRunCursor}. * @hide * @hide */ */ int getTextRunCursor(int contextStart, int contextEnd, int offset, int getTextRunCursor(int contextStart, int contextEnd, int flags, int offset, int cursorOpt, Paint p); int cursorOpt, Paint p); } } core/java/android/text/MeasuredText.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -159,15 +159,18 @@ class MeasuredText { mPos = p + len; mPos = p + len; if (mEasy) { if (mEasy) { return paint.getTextRunAdvances(mChars, p, len, p, len, mWidths, p); int flags = mDir == Layout.DIR_LEFT_TO_RIGHT ? Canvas.DIRECTION_LTR : Canvas.DIRECTION_RTL; return paint.getTextRunAdvances(mChars, p, len, p, len, flags, mWidths, p); } } float totalAdvance = 0; float totalAdvance = 0; int level = mLevels[p]; int level = mLevels[p]; for (int q = p, i = p + 1, e = p + len;; ++i) { for (int q = p, i = p + 1, e = p + len;; ++i) { if (i == e || mLevels[i] != level) { if (i == e || mLevels[i] != level) { int flags = (level & 0x1) == 0 ? Canvas.DIRECTION_LTR : Canvas.DIRECTION_RTL; totalAdvance += totalAdvance += paint.getTextRunAdvances(mChars, q, i - q, q, i - q, mWidths, q); paint.getTextRunAdvances(mChars, q, i - q, q, i - q, flags, mWidths, q); if (i == e) { if (i == e) { break; break; } } Loading core/java/android/text/SpannableStringBuilder.java +42 −21 Original line number Original line Diff line number Diff line Loading @@ -1130,20 +1130,20 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * {@hide} * {@hide} */ */ public void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, public void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, float x, float y, Paint p) { float x, float y, int flags, Paint p) { checkRange("drawTextRun", start, end); checkRange("drawTextRun", start, end); int contextLen = contextEnd - contextStart; int contextLen = contextEnd - contextStart; int len = end - start; int len = end - start; if (contextEnd <= mGapStart) { if (contextEnd <= mGapStart) { c.drawTextRun(mText, start, len, contextStart, contextLen, x, y, p); c.drawTextRun(mText, start, len, contextStart, contextLen, x, y, flags, p); } else if (contextStart >= mGapStart) { } else if (contextStart >= mGapStart) { c.drawTextRun(mText, start + mGapLength, len, contextStart + mGapLength, c.drawTextRun(mText, start + mGapLength, len, contextStart + mGapLength, contextLen, x, y, p); contextLen, x, y, flags, p); } else { } else { char[] buf = TextUtils.obtain(contextLen); char[] buf = TextUtils.obtain(contextLen); getChars(contextStart, contextEnd, buf, 0); getChars(contextStart, contextEnd, buf, 0); c.drawTextRun(buf, start - contextStart, len, 0, contextLen, x, y, p); c.drawTextRun(buf, start - contextStart, len, 0, contextLen, x, y, flags, p); TextUtils.recycle(buf); TextUtils.recycle(buf); } } } } Loading Loading @@ -1200,7 +1200,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * Don't call this yourself -- exists for Paint to use internally. * Don't call this yourself -- exists for Paint to use internally. * {@hide} * {@hide} */ */ public float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, public float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, int flags, float[] advances, int advancesPos, Paint p) { float[] advances, int advancesPos, Paint p) { float ret; float ret; Loading @@ -1210,15 +1210,44 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable if (end <= mGapStart) { if (end <= mGapStart) { ret = p.getTextRunAdvances(mText, start, len, contextStart, contextLen, ret = p.getTextRunAdvances(mText, start, len, contextStart, contextLen, advances, advancesPos); flags, advances, advancesPos); } else if (start >= mGapStart) { } else if (start >= mGapStart) { ret = p.getTextRunAdvances(mText, start + mGapLength, len, ret = p.getTextRunAdvances(mText, start + mGapLength, len, contextStart + mGapLength, contextLen, advances, advancesPos); contextStart + mGapLength, contextLen, flags, advances, advancesPos); } else { } else { char[] buf = TextUtils.obtain(contextLen); char[] buf = TextUtils.obtain(contextLen); getChars(contextStart, contextEnd, buf, 0); getChars(contextStart, contextEnd, buf, 0); ret = p.getTextRunAdvances(buf, start - contextStart, len, ret = p.getTextRunAdvances(buf, start - contextStart, len, 0, contextLen, advances, advancesPos); 0, contextLen, flags, advances, advancesPos); TextUtils.recycle(buf); } return ret; } /** * Don't call this yourself -- exists for Paint to use internally. * {@hide} */ public float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, int flags, float[] advances, int advancesPos, Paint p, int reserved) { float ret; int contextLen = contextEnd - contextStart; int len = end - start; if (end <= mGapStart) { ret = p.getTextRunAdvances(mText, start, len, contextStart, contextLen, flags, advances, advancesPos, reserved); } else if (start >= mGapStart) { 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.getTextRunAdvances(buf, start - contextStart, len, 0, contextLen, flags, advances, advancesPos, reserved); TextUtils.recycle(buf); TextUtils.recycle(buf); } } Loading @@ -1241,7 +1270,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * * * @param contextStart the start index of the context * @param contextStart the start index of the context * @param contextEnd the (non-inclusive) end index of the context * @param contextEnd the (non-inclusive) end index of the context * @param flags reserved * @param flags either DIRECTION_RTL or DIRECTION_LTR * @param offset the cursor position to move from * @param offset the cursor position to move from * @param cursorOpt how to move the cursor, one of CURSOR_AFTER, * @param cursorOpt how to move the cursor, one of CURSOR_AFTER, * CURSOR_AT_OR_AFTER, CURSOR_BEFORE, * CURSOR_AT_OR_AFTER, CURSOR_BEFORE, Loading @@ -1253,29 +1282,21 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable @Deprecated @Deprecated public int getTextRunCursor(int contextStart, int contextEnd, int flags, int offset, public int getTextRunCursor(int contextStart, int contextEnd, int flags, int offset, int cursorOpt, Paint p) { int cursorOpt, Paint p) { return getTextRunCursor(contextStart, contextEnd, offset, cursorOpt, p); } /** * @hide */ public int getTextRunCursor(int contextStart, int contextEnd, int offset, int cursorOpt, Paint p) { int ret; int ret; int contextLen = contextEnd - contextStart; int contextLen = contextEnd - contextStart; if (contextEnd <= mGapStart) { if (contextEnd <= mGapStart) { ret = p.getTextRunCursor(mText, contextStart, contextLen, ret = p.getTextRunCursor(mText, contextStart, contextLen, offset, cursorOpt); flags, offset, cursorOpt); } else if (contextStart >= mGapStart) { } else if (contextStart >= mGapStart) { ret = p.getTextRunCursor(mText, contextStart + mGapLength, contextLen, ret = p.getTextRunCursor(mText, contextStart + mGapLength, contextLen, offset + mGapLength, cursorOpt) - mGapLength; flags, offset + mGapLength, cursorOpt) - mGapLength; } else { } else { char[] buf = TextUtils.obtain(contextLen); char[] buf = TextUtils.obtain(contextLen); getChars(contextStart, contextEnd, buf, 0); getChars(contextStart, contextEnd, buf, 0); ret = p.getTextRunCursor(buf, 0, contextLen, ret = p.getTextRunCursor(buf, 0, contextLen, offset - contextStart, cursorOpt) + contextStart; flags, offset - contextStart, cursorOpt) + contextStart; TextUtils.recycle(buf); TextUtils.recycle(buf); } } Loading core/java/android/text/TextLine.java +15 −9 Original line number Original line Diff line number Diff line Loading @@ -664,13 +664,14 @@ class TextLine { } } } } int flags = runIsRtl ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR; int cursorOpt = after ? Paint.CURSOR_AFTER : Paint.CURSOR_BEFORE; int cursorOpt = after ? Paint.CURSOR_AFTER : Paint.CURSOR_BEFORE; if (mCharsValid) { if (mCharsValid) { return wp.getTextRunCursor(mChars, spanStart, spanLimit - spanStart, return wp.getTextRunCursor(mChars, spanStart, spanLimit - spanStart, offset, cursorOpt); flags, offset, cursorOpt); } else { } else { return wp.getTextRunCursor(mText, mStart + spanStart, return wp.getTextRunCursor(mText, mStart + spanStart, mStart + spanLimit, mStart + offset, cursorOpt) - mStart; mStart + spanLimit, flags, mStart + offset, cursorOpt) - mStart; } } } } Loading Loading @@ -737,13 +738,15 @@ class TextLine { int contextLen = contextEnd - contextStart; int contextLen = contextEnd - contextStart; if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) { if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) { int flags = runIsRtl ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR; if (mCharsValid) { if (mCharsValid) { ret = wp.getTextRunAdvances(mChars, start, runLen, ret = wp.getTextRunAdvances(mChars, start, runLen, contextStart, contextLen, null, 0); contextStart, contextLen, flags, null, 0); } else { } else { int delta = mStart; int delta = mStart; ret = wp.getTextRunAdvances(mText, delta + start, delta + end, ret = wp.getTextRunAdvances(mText, delta + start, delta + contextStart, delta + contextEnd, null, 0); delta + end, delta + contextStart, delta + contextEnd, flags, null, 0); } } } } Loading Loading @@ -783,7 +786,8 @@ class TextLine { wp.setAntiAlias(previousAntiAlias); wp.setAntiAlias(previousAntiAlias); } } drawTextRun(c, wp, start, end, contextStart, contextEnd, x, y + wp.baselineShift); drawTextRun(c, wp, start, end, contextStart, contextEnd, runIsRtl, x, y + wp.baselineShift); } } return runIsRtl ? -ret : ret; return runIsRtl ? -ret : ret; Loading Loading @@ -966,21 +970,23 @@ class TextLine { * @param end the end of the run * @param end the end of the run * @param contextStart the start of context for the run * @param contextStart the start of context for the run * @param contextEnd the end of the context for the run * @param contextEnd the end of the context for the run * @param runIsRtl true if the run is right-to-left * @param x the x position of the left edge of the run * @param x the x position of the left edge of the run * @param y the baseline of the run * @param y the baseline of the run */ */ private void drawTextRun(Canvas c, TextPaint wp, int start, int end, private void drawTextRun(Canvas c, TextPaint wp, int start, int end, int contextStart, int contextEnd, float x, int y) { int contextStart, int contextEnd, boolean runIsRtl, float x, int y) { int flags = runIsRtl ? Canvas.DIRECTION_RTL : Canvas.DIRECTION_LTR; if (mCharsValid) { if (mCharsValid) { int count = end - start; int count = end - start; int contextCount = contextEnd - contextStart; int contextCount = contextEnd - contextStart; c.drawTextRun(mChars, start, count, contextStart, contextCount, c.drawTextRun(mChars, start, count, contextStart, contextCount, x, y, wp); x, y, flags, wp); } else { } else { int delta = mStart; int delta = mStart; c.drawTextRun(mText, delta + start, delta + end, c.drawTextRun(mText, delta + start, delta + end, delta + contextStart, delta + contextEnd, x, y, wp); delta + contextStart, delta + contextEnd, x, y, flags, wp); } } } } Loading core/java/android/view/GLES20Canvas.java +26 −19 Original line number Original line Diff line number Diff line Loading @@ -1162,14 +1162,14 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawText(mRenderer, text, index, count, x, y, paint.mNativePaint); nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } } } private static native void nDrawText(int renderer, char[] text, int index, int count, private static native void nDrawText(int renderer, char[] text, int index, int count, float x, float y, int paint); float x, float y, int bidiFlags, int paint); @Override @Override public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { Loading @@ -1177,14 +1177,16 @@ class GLES20Canvas extends HardwareCanvas { try { try { if (text instanceof String || text instanceof SpannedString || if (text instanceof String || text instanceof SpannedString || text instanceof SpannableString) { text instanceof SpannableString) { nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mNativePaint); nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags, paint.mNativePaint); } else if (text instanceof GraphicsOperations) { } else if (text instanceof GraphicsOperations) { ((GraphicsOperations) text).drawText(this, start, end, x, y, ((GraphicsOperations) text).drawText(this, start, end, x, y, paint); paint); } else { } else { char[] buf = TemporaryBuffer.obtain(end - start); char[] buf = TemporaryBuffer.obtain(end - start); TextUtils.getChars(text, start, end, buf, 0); TextUtils.getChars(text, start, end, buf, 0); nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mNativePaint); nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint); TemporaryBuffer.recycle(buf); TemporaryBuffer.recycle(buf); } } } finally { } finally { Loading @@ -1200,20 +1202,21 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawText(mRenderer, text, start, end, x, y, paint.mNativePaint); nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } } } private static native void nDrawText(int renderer, String text, int start, int end, private static native void nDrawText(int renderer, String text, int start, int end, float x, float y, int paint); float x, float y, int bidiFlags, int paint); @Override @Override public void drawText(String text, float x, float y, Paint paint) { public void drawText(String text, float x, float y, Paint paint) { int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mNativePaint); nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags, paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } Loading @@ -1229,14 +1232,14 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset, nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset, paint.mNativePaint); paint.mBidiFlags, paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } } } private static native void nDrawTextOnPath(int renderer, char[] text, int index, int count, private static native void nDrawTextOnPath(int renderer, char[] text, int index, int count, int path, float hOffset, float vOffset, int nativePaint); int path, float hOffset, float vOffset, int bidiFlags, int nativePaint); @Override @Override public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { Loading @@ -1245,25 +1248,28 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset, nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset, paint.mNativePaint); paint.mBidiFlags, paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } } } private static native void nDrawTextOnPath(int renderer, String text, int start, int end, private static native void nDrawTextOnPath(int renderer, String text, int start, int end, int path, float hOffset, float vOffset, int nativePaint); int path, float hOffset, float vOffset, int bidiFlags, int nativePaint); @Override @Override public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, Paint paint) { float x, float y, int dir, Paint paint) { if ((index | count | text.length - index - count) < 0) { if ((index | count | text.length - index - count) < 0) { throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException(); } } if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) { throw new IllegalArgumentException("Unknown direction: " + dir); } int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir, paint.mNativePaint); paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); Loading @@ -1271,31 +1277,32 @@ class GLES20Canvas extends HardwareCanvas { } } private static native void nDrawTextRun(int renderer, char[] text, int index, int count, private static native void nDrawTextRun(int renderer, char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, int nativePaint); int contextIndex, int contextCount, float x, float y, int dir, int nativePaint); @Override @Override public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, Paint paint) { float x, float y, int dir, Paint paint) { if ((start | end | end - start | text.length() - end) < 0) { if ((start | end | end - start | text.length() - end) < 0) { throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException(); } } int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { int flags = dir == 0 ? 0 : 1; if (text instanceof String || text instanceof SpannedString || if (text instanceof String || text instanceof SpannedString || text instanceof SpannableString) { text instanceof SpannableString) { nDrawTextRun(mRenderer, text.toString(), start, end, contextStart, nDrawTextRun(mRenderer, text.toString(), start, end, contextStart, contextEnd, x, y, paint.mNativePaint); contextEnd, x, y, flags, paint.mNativePaint); } else if (text instanceof GraphicsOperations) { } else if (text instanceof GraphicsOperations) { ((GraphicsOperations) text).drawTextRun(this, start, end, ((GraphicsOperations) text).drawTextRun(this, start, end, contextStart, contextEnd, x, y, paint); contextStart, contextEnd, x, y, flags, paint); } else { } else { int contextLen = contextEnd - contextStart; int contextLen = contextEnd - contextStart; int len = end - start; int len = end - start; char[] buf = TemporaryBuffer.obtain(contextLen); char[] buf = TemporaryBuffer.obtain(contextLen); TextUtils.getChars(text, contextStart, contextEnd, buf, 0); TextUtils.getChars(text, contextStart, contextEnd, buf, 0); nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen, nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen, x, y, paint.mNativePaint); x, y, flags, paint.mNativePaint); TemporaryBuffer.recycle(buf); TemporaryBuffer.recycle(buf); } } } finally { } finally { Loading @@ -1304,7 +1311,7 @@ class GLES20Canvas extends HardwareCanvas { } } private static native void nDrawTextRun(int renderer, String text, int start, int end, private static native void nDrawTextRun(int renderer, String text, int start, int end, int contextStart, int contextEnd, float x, float y, int nativePaint); int contextStart, int contextEnd, float x, float y, int flags, int nativePaint); @Override @Override public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, Loading Loading
core/java/android/text/GraphicsOperations.java +10 −3 Original line number Original line Diff line number Diff line Loading @@ -38,7 +38,7 @@ extends CharSequence * {@hide} * {@hide} */ */ void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, float x, float y, Paint p); float x, float y, int flags, Paint p); /** /** * Just like {@link Paint#measureText}. * Just like {@link Paint#measureText}. Loading @@ -55,12 +55,19 @@ extends CharSequence * @hide * @hide */ */ float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, float[] advances, int advancesIndex, Paint paint); int flags, float[] advances, int advancesIndex, Paint paint); /** * Just like {@link Paint#getTextRunAdvances}. * @hide */ 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}. * Just like {@link Paint#getTextRunCursor}. * @hide * @hide */ */ int getTextRunCursor(int contextStart, int contextEnd, int offset, int getTextRunCursor(int contextStart, int contextEnd, int flags, int offset, int cursorOpt, Paint p); int cursorOpt, Paint p); } }
core/java/android/text/MeasuredText.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -159,15 +159,18 @@ class MeasuredText { mPos = p + len; mPos = p + len; if (mEasy) { if (mEasy) { return paint.getTextRunAdvances(mChars, p, len, p, len, mWidths, p); int flags = mDir == Layout.DIR_LEFT_TO_RIGHT ? Canvas.DIRECTION_LTR : Canvas.DIRECTION_RTL; return paint.getTextRunAdvances(mChars, p, len, p, len, flags, mWidths, p); } } float totalAdvance = 0; float totalAdvance = 0; int level = mLevels[p]; int level = mLevels[p]; for (int q = p, i = p + 1, e = p + len;; ++i) { for (int q = p, i = p + 1, e = p + len;; ++i) { if (i == e || mLevels[i] != level) { if (i == e || mLevels[i] != level) { int flags = (level & 0x1) == 0 ? Canvas.DIRECTION_LTR : Canvas.DIRECTION_RTL; totalAdvance += totalAdvance += paint.getTextRunAdvances(mChars, q, i - q, q, i - q, mWidths, q); paint.getTextRunAdvances(mChars, q, i - q, q, i - q, flags, mWidths, q); if (i == e) { if (i == e) { break; break; } } Loading
core/java/android/text/SpannableStringBuilder.java +42 −21 Original line number Original line Diff line number Diff line Loading @@ -1130,20 +1130,20 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * {@hide} * {@hide} */ */ public void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, public void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, float x, float y, Paint p) { float x, float y, int flags, Paint p) { checkRange("drawTextRun", start, end); checkRange("drawTextRun", start, end); int contextLen = contextEnd - contextStart; int contextLen = contextEnd - contextStart; int len = end - start; int len = end - start; if (contextEnd <= mGapStart) { if (contextEnd <= mGapStart) { c.drawTextRun(mText, start, len, contextStart, contextLen, x, y, p); c.drawTextRun(mText, start, len, contextStart, contextLen, x, y, flags, p); } else if (contextStart >= mGapStart) { } else if (contextStart >= mGapStart) { c.drawTextRun(mText, start + mGapLength, len, contextStart + mGapLength, c.drawTextRun(mText, start + mGapLength, len, contextStart + mGapLength, contextLen, x, y, p); contextLen, x, y, flags, p); } else { } else { char[] buf = TextUtils.obtain(contextLen); char[] buf = TextUtils.obtain(contextLen); getChars(contextStart, contextEnd, buf, 0); getChars(contextStart, contextEnd, buf, 0); c.drawTextRun(buf, start - contextStart, len, 0, contextLen, x, y, p); c.drawTextRun(buf, start - contextStart, len, 0, contextLen, x, y, flags, p); TextUtils.recycle(buf); TextUtils.recycle(buf); } } } } Loading Loading @@ -1200,7 +1200,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * Don't call this yourself -- exists for Paint to use internally. * Don't call this yourself -- exists for Paint to use internally. * {@hide} * {@hide} */ */ public float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, public float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, int flags, float[] advances, int advancesPos, Paint p) { float[] advances, int advancesPos, Paint p) { float ret; float ret; Loading @@ -1210,15 +1210,44 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable if (end <= mGapStart) { if (end <= mGapStart) { ret = p.getTextRunAdvances(mText, start, len, contextStart, contextLen, ret = p.getTextRunAdvances(mText, start, len, contextStart, contextLen, advances, advancesPos); flags, advances, advancesPos); } else if (start >= mGapStart) { } else if (start >= mGapStart) { ret = p.getTextRunAdvances(mText, start + mGapLength, len, ret = p.getTextRunAdvances(mText, start + mGapLength, len, contextStart + mGapLength, contextLen, advances, advancesPos); contextStart + mGapLength, contextLen, flags, advances, advancesPos); } else { } else { char[] buf = TextUtils.obtain(contextLen); char[] buf = TextUtils.obtain(contextLen); getChars(contextStart, contextEnd, buf, 0); getChars(contextStart, contextEnd, buf, 0); ret = p.getTextRunAdvances(buf, start - contextStart, len, ret = p.getTextRunAdvances(buf, start - contextStart, len, 0, contextLen, advances, advancesPos); 0, contextLen, flags, advances, advancesPos); TextUtils.recycle(buf); } return ret; } /** * Don't call this yourself -- exists for Paint to use internally. * {@hide} */ public float getTextRunAdvances(int start, int end, int contextStart, int contextEnd, int flags, float[] advances, int advancesPos, Paint p, int reserved) { float ret; int contextLen = contextEnd - contextStart; int len = end - start; if (end <= mGapStart) { ret = p.getTextRunAdvances(mText, start, len, contextStart, contextLen, flags, advances, advancesPos, reserved); } else if (start >= mGapStart) { 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.getTextRunAdvances(buf, start - contextStart, len, 0, contextLen, flags, advances, advancesPos, reserved); TextUtils.recycle(buf); TextUtils.recycle(buf); } } Loading @@ -1241,7 +1270,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * * * @param contextStart the start index of the context * @param contextStart the start index of the context * @param contextEnd the (non-inclusive) end index of the context * @param contextEnd the (non-inclusive) end index of the context * @param flags reserved * @param flags either DIRECTION_RTL or DIRECTION_LTR * @param offset the cursor position to move from * @param offset the cursor position to move from * @param cursorOpt how to move the cursor, one of CURSOR_AFTER, * @param cursorOpt how to move the cursor, one of CURSOR_AFTER, * CURSOR_AT_OR_AFTER, CURSOR_BEFORE, * CURSOR_AT_OR_AFTER, CURSOR_BEFORE, Loading @@ -1253,29 +1282,21 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable @Deprecated @Deprecated public int getTextRunCursor(int contextStart, int contextEnd, int flags, int offset, public int getTextRunCursor(int contextStart, int contextEnd, int flags, int offset, int cursorOpt, Paint p) { int cursorOpt, Paint p) { return getTextRunCursor(contextStart, contextEnd, offset, cursorOpt, p); } /** * @hide */ public int getTextRunCursor(int contextStart, int contextEnd, int offset, int cursorOpt, Paint p) { int ret; int ret; int contextLen = contextEnd - contextStart; int contextLen = contextEnd - contextStart; if (contextEnd <= mGapStart) { if (contextEnd <= mGapStart) { ret = p.getTextRunCursor(mText, contextStart, contextLen, ret = p.getTextRunCursor(mText, contextStart, contextLen, offset, cursorOpt); flags, offset, cursorOpt); } else if (contextStart >= mGapStart) { } else if (contextStart >= mGapStart) { ret = p.getTextRunCursor(mText, contextStart + mGapLength, contextLen, ret = p.getTextRunCursor(mText, contextStart + mGapLength, contextLen, offset + mGapLength, cursorOpt) - mGapLength; flags, offset + mGapLength, cursorOpt) - mGapLength; } else { } else { char[] buf = TextUtils.obtain(contextLen); char[] buf = TextUtils.obtain(contextLen); getChars(contextStart, contextEnd, buf, 0); getChars(contextStart, contextEnd, buf, 0); ret = p.getTextRunCursor(buf, 0, contextLen, ret = p.getTextRunCursor(buf, 0, contextLen, offset - contextStart, cursorOpt) + contextStart; flags, offset - contextStart, cursorOpt) + contextStart; TextUtils.recycle(buf); TextUtils.recycle(buf); } } Loading
core/java/android/text/TextLine.java +15 −9 Original line number Original line Diff line number Diff line Loading @@ -664,13 +664,14 @@ class TextLine { } } } } int flags = runIsRtl ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR; int cursorOpt = after ? Paint.CURSOR_AFTER : Paint.CURSOR_BEFORE; int cursorOpt = after ? Paint.CURSOR_AFTER : Paint.CURSOR_BEFORE; if (mCharsValid) { if (mCharsValid) { return wp.getTextRunCursor(mChars, spanStart, spanLimit - spanStart, return wp.getTextRunCursor(mChars, spanStart, spanLimit - spanStart, offset, cursorOpt); flags, offset, cursorOpt); } else { } else { return wp.getTextRunCursor(mText, mStart + spanStart, return wp.getTextRunCursor(mText, mStart + spanStart, mStart + spanLimit, mStart + offset, cursorOpt) - mStart; mStart + spanLimit, flags, mStart + offset, cursorOpt) - mStart; } } } } Loading Loading @@ -737,13 +738,15 @@ class TextLine { int contextLen = contextEnd - contextStart; int contextLen = contextEnd - contextStart; if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) { if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) { int flags = runIsRtl ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR; if (mCharsValid) { if (mCharsValid) { ret = wp.getTextRunAdvances(mChars, start, runLen, ret = wp.getTextRunAdvances(mChars, start, runLen, contextStart, contextLen, null, 0); contextStart, contextLen, flags, null, 0); } else { } else { int delta = mStart; int delta = mStart; ret = wp.getTextRunAdvances(mText, delta + start, delta + end, ret = wp.getTextRunAdvances(mText, delta + start, delta + contextStart, delta + contextEnd, null, 0); delta + end, delta + contextStart, delta + contextEnd, flags, null, 0); } } } } Loading Loading @@ -783,7 +786,8 @@ class TextLine { wp.setAntiAlias(previousAntiAlias); wp.setAntiAlias(previousAntiAlias); } } drawTextRun(c, wp, start, end, contextStart, contextEnd, x, y + wp.baselineShift); drawTextRun(c, wp, start, end, contextStart, contextEnd, runIsRtl, x, y + wp.baselineShift); } } return runIsRtl ? -ret : ret; return runIsRtl ? -ret : ret; Loading Loading @@ -966,21 +970,23 @@ class TextLine { * @param end the end of the run * @param end the end of the run * @param contextStart the start of context for the run * @param contextStart the start of context for the run * @param contextEnd the end of the context for the run * @param contextEnd the end of the context for the run * @param runIsRtl true if the run is right-to-left * @param x the x position of the left edge of the run * @param x the x position of the left edge of the run * @param y the baseline of the run * @param y the baseline of the run */ */ private void drawTextRun(Canvas c, TextPaint wp, int start, int end, private void drawTextRun(Canvas c, TextPaint wp, int start, int end, int contextStart, int contextEnd, float x, int y) { int contextStart, int contextEnd, boolean runIsRtl, float x, int y) { int flags = runIsRtl ? Canvas.DIRECTION_RTL : Canvas.DIRECTION_LTR; if (mCharsValid) { if (mCharsValid) { int count = end - start; int count = end - start; int contextCount = contextEnd - contextStart; int contextCount = contextEnd - contextStart; c.drawTextRun(mChars, start, count, contextStart, contextCount, c.drawTextRun(mChars, start, count, contextStart, contextCount, x, y, wp); x, y, flags, wp); } else { } else { int delta = mStart; int delta = mStart; c.drawTextRun(mText, delta + start, delta + end, c.drawTextRun(mText, delta + start, delta + end, delta + contextStart, delta + contextEnd, x, y, wp); delta + contextStart, delta + contextEnd, x, y, flags, wp); } } } } Loading
core/java/android/view/GLES20Canvas.java +26 −19 Original line number Original line Diff line number Diff line Loading @@ -1162,14 +1162,14 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawText(mRenderer, text, index, count, x, y, paint.mNativePaint); nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } } } private static native void nDrawText(int renderer, char[] text, int index, int count, private static native void nDrawText(int renderer, char[] text, int index, int count, float x, float y, int paint); float x, float y, int bidiFlags, int paint); @Override @Override public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { Loading @@ -1177,14 +1177,16 @@ class GLES20Canvas extends HardwareCanvas { try { try { if (text instanceof String || text instanceof SpannedString || if (text instanceof String || text instanceof SpannedString || text instanceof SpannableString) { text instanceof SpannableString) { nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mNativePaint); nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags, paint.mNativePaint); } else if (text instanceof GraphicsOperations) { } else if (text instanceof GraphicsOperations) { ((GraphicsOperations) text).drawText(this, start, end, x, y, ((GraphicsOperations) text).drawText(this, start, end, x, y, paint); paint); } else { } else { char[] buf = TemporaryBuffer.obtain(end - start); char[] buf = TemporaryBuffer.obtain(end - start); TextUtils.getChars(text, start, end, buf, 0); TextUtils.getChars(text, start, end, buf, 0); nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mNativePaint); nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint); TemporaryBuffer.recycle(buf); TemporaryBuffer.recycle(buf); } } } finally { } finally { Loading @@ -1200,20 +1202,21 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawText(mRenderer, text, start, end, x, y, paint.mNativePaint); nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } } } private static native void nDrawText(int renderer, String text, int start, int end, private static native void nDrawText(int renderer, String text, int start, int end, float x, float y, int paint); float x, float y, int bidiFlags, int paint); @Override @Override public void drawText(String text, float x, float y, Paint paint) { public void drawText(String text, float x, float y, Paint paint) { int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mNativePaint); nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags, paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } Loading @@ -1229,14 +1232,14 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset, nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset, paint.mNativePaint); paint.mBidiFlags, paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } } } private static native void nDrawTextOnPath(int renderer, char[] text, int index, int count, private static native void nDrawTextOnPath(int renderer, char[] text, int index, int count, int path, float hOffset, float vOffset, int nativePaint); int path, float hOffset, float vOffset, int bidiFlags, int nativePaint); @Override @Override public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { Loading @@ -1245,25 +1248,28 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset, nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset, paint.mNativePaint); paint.mBidiFlags, paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } } } private static native void nDrawTextOnPath(int renderer, String text, int start, int end, private static native void nDrawTextOnPath(int renderer, String text, int start, int end, int path, float hOffset, float vOffset, int nativePaint); int path, float hOffset, float vOffset, int bidiFlags, int nativePaint); @Override @Override public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, Paint paint) { float x, float y, int dir, Paint paint) { if ((index | count | text.length - index - count) < 0) { if ((index | count | text.length - index - count) < 0) { throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException(); } } if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) { throw new IllegalArgumentException("Unknown direction: " + dir); } int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir, paint.mNativePaint); paint.mNativePaint); } finally { } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); Loading @@ -1271,31 +1277,32 @@ class GLES20Canvas extends HardwareCanvas { } } private static native void nDrawTextRun(int renderer, char[] text, int index, int count, private static native void nDrawTextRun(int renderer, char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, int nativePaint); int contextIndex, int contextCount, float x, float y, int dir, int nativePaint); @Override @Override public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, Paint paint) { float x, float y, int dir, Paint paint) { if ((start | end | end - start | text.length() - end) < 0) { if ((start | end | end - start | text.length() - end) < 0) { throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException(); } } int modifiers = setupModifiers(paint); int modifiers = setupModifiers(paint); try { try { int flags = dir == 0 ? 0 : 1; if (text instanceof String || text instanceof SpannedString || if (text instanceof String || text instanceof SpannedString || text instanceof SpannableString) { text instanceof SpannableString) { nDrawTextRun(mRenderer, text.toString(), start, end, contextStart, nDrawTextRun(mRenderer, text.toString(), start, end, contextStart, contextEnd, x, y, paint.mNativePaint); contextEnd, x, y, flags, paint.mNativePaint); } else if (text instanceof GraphicsOperations) { } else if (text instanceof GraphicsOperations) { ((GraphicsOperations) text).drawTextRun(this, start, end, ((GraphicsOperations) text).drawTextRun(this, start, end, contextStart, contextEnd, x, y, paint); contextStart, contextEnd, x, y, flags, paint); } else { } else { int contextLen = contextEnd - contextStart; int contextLen = contextEnd - contextStart; int len = end - start; int len = end - start; char[] buf = TemporaryBuffer.obtain(contextLen); char[] buf = TemporaryBuffer.obtain(contextLen); TextUtils.getChars(text, contextStart, contextEnd, buf, 0); TextUtils.getChars(text, contextStart, contextEnd, buf, 0); nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen, nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen, x, y, paint.mNativePaint); x, y, flags, paint.mNativePaint); TemporaryBuffer.recycle(buf); TemporaryBuffer.recycle(buf); } } } finally { } finally { Loading @@ -1304,7 +1311,7 @@ class GLES20Canvas extends HardwareCanvas { } } private static native void nDrawTextRun(int renderer, String text, int start, int end, private static native void nDrawTextRun(int renderer, String text, int start, int end, int contextStart, int contextEnd, float x, float y, int nativePaint); int contextStart, int contextEnd, float x, float y, int flags, int nativePaint); @Override @Override public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, Loading