diff options
| author | 2022-10-04 16:30:58 -0700 | |
|---|---|---|
| committer | 2022-10-10 00:19:00 -0700 | |
| commit | b34559a74a4357a0e93ca1f2ce4f0e45be0b5355 (patch) | |
| tree | 7a4ae3bef492b1da728f76625fca3d7a3a0dabb8 | |
| parent | 91226107447742253e6fc7444ebeb52e4f785f42 (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.java | 24 |
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(); |