summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Justin Ghan <justinghan@google.com> 2022-10-04 16:30:58 -0700
committer Justin Ghan <justinghan@google.com> 2022-10-10 00:19:00 -0700
commitb34559a74a4357a0e93ca1f2ce4f0e45be0b5355 (patch)
tree7a4ae3bef492b1da728f76625fca3d7a3a0dabb8
parent91226107447742253e6fc7444ebeb52e4f785f42 (diff)
Remove space gesture: improve range calculation
The initial implementation using Layout#getOffsetForHorizontal could miss whitespace characters at the endpoints. This new implementation using Layout#getRangeForRect ensures all whitespace characters touched are included in the range. Bug: 247557062 Test: atest android.widget.cts.TextViewHandwritingGestureTest Change-Id: I800407a6d89d77cd5e750530d9dae8ccb268869f
-rw-r--r--core/java/android/widget/TextView.java24
1 files changed, 15 insertions, 9 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index aa3aefd5b620..ce5365acf1f4 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9436,17 +9436,23 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
// The operation should be applied to all characters touched by the line joining the points.
- int startOffset = mLayout.getOffsetForHorizontal(line, startPoint.x);
- int endOffset = mLayout.getOffsetForHorizontal(line, endPoint.x);
- if (startOffset == endOffset) {
+ float lineVerticalCenter = (mLayout.getLineTop(line)
+ + mLayout.getLineBottom(line, /* includeLineSpacing= */ false)) / 2f;
+ // Create a rectangle which is +/-0.1f around the line's vertical center, so that the
+ // rectangle doesn't touch the line above or below. (The line height is at least 1f.)
+ RectF area = new RectF(
+ Math.min(startPoint.x, endPoint.x),
+ lineVerticalCenter + 0.1f,
+ Math.max(startPoint.x, endPoint.x),
+ lineVerticalCenter - 0.1f);
+ Range<Integer> range = mLayout.getRangeForRect(
+ area, new GraphemeClusterSegmentFinder(mText, mTextPaint),
+ Layout.INCLUSION_STRATEGY_ANY_OVERLAP);
+ if (range == null) {
return handleGestureFailure(gesture);
- } else if (startOffset > endOffset) {
- int tmp = startOffset;
- startOffset = endOffset;
- endOffset = tmp;
}
- // TODO(b/247557062): The boundary offsets might be off by one. We should check which side
- // of the offset the point is on, and adjust if necessary.
+ int startOffset = range.getLower();
+ int endOffset = range.getUpper();
// TODO(b/247557062): This doesn't handle bidirectional text correctly.
Pattern whitespacePattern = getWhitespacePattern();