Fix: Cursor can be at an invalid offset in EditText.
"getLineEnd(line) - 1" is used as the return value when the
"horiz" is beyond the line end for multiple line text.
In this case, the returned value can point an invalid
offset like the middle point of a surrogate pair.
Bug: 23069901
Change-Id: I1afef7205a15079a42bb0018df73f70fe9ada862
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index cf937e1..f9387b3 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1115,13 +1115,18 @@
*/
public int getOffsetForHorizontal(int line, float horiz) {
// TODO: use Paint.getOffsetForAdvance to avoid binary search
- int max = getLineEnd(line) - 1;
- int min = getLineStart(line);
+ final int lineEndOffset = getLineEnd(line);
+ 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);
+ }
+ final int min = getLineStart(line);
Directions dirs = getLineDirections(line);
- if (line == getLineCount() - 1)
- max++;
-
int best = min;
float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz);