diff options
| author | Keisuke Kuroyanagi <ksk@google.com> | 2016-01-08 19:55:17 +0900 |
|---|---|---|
| committer | Raph Levien <raph@google.com> | 2016-01-11 14:32:55 -0800 |
| commit | 5bff01d72f2a49add74dd36c8d1ed5038611f20b (patch) | |
| tree | 5ca27537938802692fbe4c65c3a167c35264383d | |
| parent | 720edf95db6c908f87dbbb33c6bde67aedb36899 (diff) | |
| download | frameworks_base-5bff01d72f2a49add74dd36c8d1ed5038611f20b.zip frameworks_base-5bff01d72f2a49add74dd36c8d1ed5038611f20b.tar.gz frameworks_base-5bff01d72f2a49add74dd36c8d1ed5038611f20b.tar.bz2 | |
Respect grapheme clusters in Layout#getOffsetForHorizontal.
TextUtils#getOffsetAfter was used for getting the next
offset in Layout#getOffsetForHorizontal. However, this
method doesn't treat grapheme clusters properly.
Changed to use TextLine#getOffsetToLeftRightOf instead of
TextUtils#getOffsetAfter.
Bug: 25375561
Change-Id: I96c9e6e5da65adfb5266446ecab852c52628dbb5
| -rw-r--r-- | core/java/android/text/Layout.java | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index 706d989..22ad634 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -1131,24 +1131,30 @@ public abstract class Layout { public int getOffsetForHorizontal(int line, float horiz) { // TODO: use Paint.getOffsetForAdvance to avoid binary search final int lineEndOffset = getLineEnd(line); + final int lineStartOffset = getLineStart(line); + + Directions dirs = getLineDirections(line); + + TextLine tl = TextLine.obtain(); + // XXX: we don't care about tabs as we just use TextLine#getOffsetToLeftRightOf here. + tl.set(mPaint, mText, lineStartOffset, lineEndOffset, getParagraphDirection(line), dirs, + false, null); + final int max; if (line == getLineCount() - 1) { max = lineEndOffset; } else { - max = mPaint.getTextRunCursor(mText, 0, mText.length(), - isRtlCharAt(lineEndOffset) ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR, - lineEndOffset, Paint.CURSOR_BEFORE); + max = tl.getOffsetToLeftRightOf(lineEndOffset - lineStartOffset, + !isRtlCharAt(lineEndOffset - 1)) + lineStartOffset; } - final int min = getLineStart(line); - Directions dirs = getLineDirections(line); - - int best = min; + int best = lineStartOffset; float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz); for (int i = 0; i < dirs.mDirections.length; i += 2) { - int here = min + dirs.mDirections[i]; + int here = lineStartOffset + dirs.mDirections[i]; int there = here + (dirs.mDirections[i+1] & RUN_LENGTH_MASK); - int swap = (dirs.mDirections[i+1] & RUN_RTL_FLAG) != 0 ? -1 : 1; + boolean isRtl = (dirs.mDirections[i+1] & RUN_RTL_FLAG) != 0; + int swap = isRtl ? -1 : 1; if (there > max) there = max; @@ -1168,23 +1174,23 @@ public abstract class Layout { low = here + 1; if (low < there) { - low = getOffsetAtStartOf(low); - - float dist = Math.abs(getPrimaryHorizontal(low) - horiz); - - int aft = TextUtils.getOffsetAfter(mText, low); - if (aft < there) { - float other = Math.abs(getPrimaryHorizontal(aft) - horiz); - - if (other < dist) { - dist = other; - low = aft; + int aft = tl.getOffsetToLeftRightOf(low - lineStartOffset, isRtl) + lineStartOffset; + low = tl.getOffsetToLeftRightOf(aft - lineStartOffset, !isRtl) + lineStartOffset; + if (low >= here && low < there) { + float dist = Math.abs(getPrimaryHorizontal(low) - horiz); + if (aft < there) { + float other = Math.abs(getPrimaryHorizontal(aft) - horiz); + + if (other < dist) { + dist = other; + low = aft; + } } - } - if (dist < bestdist) { - bestdist = dist; - best = low; + if (dist < bestdist) { + bestdist = dist; + best = low; + } } } @@ -1203,6 +1209,7 @@ public abstract class Layout { best = max; } + TextLine.recycle(tl); return best; } |
