Merge changes from topic \'grapheme-dr1.5\' into mnc-dr1.5-dev
am: 9f2c939730
* commit '9f2c939730730e76afc46e891b82499b499503e1':
Respect grapheme clusters in Layout#getOffsetForHorizontal.
Fix: Cursor can be at an invalid offset in EditText.
This commit is contained in:
@@ -1130,20 +1130,31 @@ public abstract class Layout {
|
|||||||
*/
|
*/
|
||||||
public int getOffsetForHorizontal(int line, float horiz) {
|
public int getOffsetForHorizontal(int line, float horiz) {
|
||||||
// TODO: use Paint.getOffsetForAdvance to avoid binary search
|
// TODO: use Paint.getOffsetForAdvance to avoid binary search
|
||||||
int max = getLineEnd(line) - 1;
|
final int lineEndOffset = getLineEnd(line);
|
||||||
int min = getLineStart(line);
|
final int lineStartOffset = getLineStart(line);
|
||||||
|
|
||||||
Directions dirs = getLineDirections(line);
|
Directions dirs = getLineDirections(line);
|
||||||
|
|
||||||
if (line == getLineCount() - 1)
|
TextLine tl = TextLine.obtain();
|
||||||
max++;
|
// 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);
|
||||||
|
|
||||||
int best = min;
|
final int max;
|
||||||
|
if (line == getLineCount() - 1) {
|
||||||
|
max = lineEndOffset;
|
||||||
|
} else {
|
||||||
|
max = tl.getOffsetToLeftRightOf(lineEndOffset - lineStartOffset,
|
||||||
|
!isRtlCharAt(lineEndOffset - 1)) + lineStartOffset;
|
||||||
|
}
|
||||||
|
int best = lineStartOffset;
|
||||||
float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz);
|
float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz);
|
||||||
|
|
||||||
for (int i = 0; i < dirs.mDirections.length; i += 2) {
|
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 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)
|
if (there > max)
|
||||||
there = max;
|
there = max;
|
||||||
@@ -1163,11 +1174,10 @@ public abstract class Layout {
|
|||||||
low = here + 1;
|
low = here + 1;
|
||||||
|
|
||||||
if (low < there) {
|
if (low < there) {
|
||||||
low = getOffsetAtStartOf(low);
|
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);
|
float dist = Math.abs(getPrimaryHorizontal(low) - horiz);
|
||||||
|
|
||||||
int aft = TextUtils.getOffsetAfter(mText, low);
|
|
||||||
if (aft < there) {
|
if (aft < there) {
|
||||||
float other = Math.abs(getPrimaryHorizontal(aft) - horiz);
|
float other = Math.abs(getPrimaryHorizontal(aft) - horiz);
|
||||||
|
|
||||||
@@ -1182,6 +1192,7 @@ public abstract class Layout {
|
|||||||
best = low;
|
best = low;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float dist = Math.abs(getPrimaryHorizontal(here) - horiz);
|
float dist = Math.abs(getPrimaryHorizontal(here) - horiz);
|
||||||
|
|
||||||
@@ -1198,6 +1209,7 @@ public abstract class Layout {
|
|||||||
best = max;
|
best = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextLine.recycle(tl);
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user