Layout#getRangeForRect API changes

- Layout#getRangeForRect returns Range<Integer> instead of int[].
- WordSegmentFinder takes ULocale instead of Locale
- Additional Javadoc

Bug: 251085162
Test: atest android.text.cts.LayoutGetRangeForRectTest
Change-Id: Id51f5b23885dc93addc44b81d641c963c58505c8
This commit is contained in:
Justin Ghan
2022-10-06 15:18:01 -07:00
parent 8f7607087f
commit 4212ebb0e9
7 changed files with 53 additions and 17 deletions

View File

@@ -45331,7 +45331,7 @@ package android.text {
method public final int getParagraphLeft(int);
method public final int getParagraphRight(int);
method public float getPrimaryHorizontal(int);
method @Nullable public int[] getRangeForRect(@NonNull android.graphics.RectF, @NonNull android.text.SegmentFinder, @NonNull android.text.Layout.TextInclusionStrategy);
method @Nullable public android.util.Range<java.lang.Integer> getRangeForRect(@NonNull android.graphics.RectF, @NonNull android.text.SegmentFinder, @NonNull android.text.Layout.TextInclusionStrategy);
method public float getSecondaryHorizontal(int);
method public void getSelectionPath(int, int, android.graphics.Path);
method public final float getSpacingAdd();
@@ -45746,7 +45746,7 @@ package android.text {
}
public class WordSegmentFinder extends android.text.SegmentFinder {
ctor public WordSegmentFinder(@NonNull CharSequence, @NonNull java.util.Locale);
ctor public WordSegmentFinder(@NonNull CharSequence, @NonNull android.icu.util.ULocale);
method public int nextEndBoundary(@IntRange(from=0) int);
method public int nextStartBoundary(@IntRange(from=0) int);
method public int previousEndBoundary(@IntRange(from=0) int);

View File

@@ -34,6 +34,13 @@ public class GraphemeClusterSegmentFinder extends SegmentFinder {
private final CharSequence mText;
private final TextPaint mTextPaint;
/**
* Constructs a GraphemeClusterSegmentFinder instance for the specified text which uses the
* provided TextPaint to determine grapheme cluster boundaries.
*
* @param text text to be segmented
* @param textPaint TextPaint used to draw the text
*/
public GraphemeClusterSegmentFinder(
@NonNull CharSequence text, @NonNull TextPaint textPaint) {
mText = text;

View File

@@ -36,6 +36,7 @@ import android.text.style.LineBackgroundSpan;
import android.text.style.ParagraphStyle;
import android.text.style.ReplacementSpan;
import android.text.style.TabStopSpan;
import android.util.Range;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -1859,11 +1860,12 @@ public abstract class Layout {
* text segment
* @param inclusionStrategy strategy for determining whether a text segment is inside the
* specified area
* @return int array of size 2 containing the start (inclusive) and end (exclusive) character
* offsets of the range, or null if there are no text segments inside the area
* @return an integer range where the endpoints are the start (inclusive) and end (exclusive)
* character offsets of the text range, or null if there are no text segments inside the
* area
*/
@Nullable
public int[] getRangeForRect(@NonNull RectF area, @NonNull SegmentFinder segmentFinder,
public Range<Integer> getRangeForRect(@NonNull RectF area, @NonNull SegmentFinder segmentFinder,
@NonNull TextInclusionStrategy inclusionStrategy) {
// Find the first line whose bottom (without line spacing) is below the top of the area.
int startLine = getLineForVertical((int) area.top);
@@ -1921,7 +1923,7 @@ public abstract class Layout {
start = segmentFinder.previousStartBoundary(start + 1);
end = segmentFinder.nextEndBoundary(end - 1);
return new int[] {start, end};
return new Range(start, end);
}
/**

View File

@@ -33,6 +33,11 @@ import android.graphics.RectF;
* @see Layout#getRangeForRect(RectF, SegmentFinder, Layout.TextInclusionStrategy)
*/
public abstract class SegmentFinder {
/**
* Return value of previousStartBoundary(int), previousEndBoundary(int), nextStartBoundary(int),
* and nextEndBoundary(int) when there are no boundaries of the specified type in the specified
* direction.
*/
public static final int DONE = -1;
/**

View File

@@ -18,12 +18,10 @@ package android.text;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.icu.text.BreakIterator;
import android.icu.util.ULocale;
import android.text.method.WordIterator;
import java.util.Locale;
/**
* Implementation of {@link SegmentFinder} using words as the text segment. Word boundaries are
* found using {@link WordIterator}. Whitespace characters are excluded, so they are not included in
@@ -39,14 +37,28 @@ public class WordSegmentFinder extends SegmentFinder {
private final CharSequence mText;
private final WordIterator mWordIterator;
/**
* Constructs a WordSegmentFinder instance for the specified text which uses the provided locale
* to determine word boundaries.
*
* @param text text to be segmented
* @param locale locale used for analyzing the text
*/
public WordSegmentFinder(
@NonNull CharSequence text, @SuppressLint("UseIcu") @NonNull Locale locale) {
@NonNull CharSequence text, @NonNull ULocale locale) {
mText = text;
mWordIterator = new WordIterator(locale);
mWordIterator.setCharSequence(text, 0, text.length());
}
/** @hide */
/**
* Constructs a WordSegmentFinder instance for the specified text which uses the provided
* WordIterator to determine word boundaries.
*
* @param text text to be segmented
* @param wordIterator word iterator used to find word boundaries in the text
* @hide
*/
public WordSegmentFinder(@NonNull CharSequence text, @NonNull WordIterator wordIterator) {
mText = text;
mWordIterator = wordIterator;

View File

@@ -21,6 +21,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.icu.lang.UCharacter;
import android.icu.lang.UProperty;
import android.icu.text.BreakIterator;
import android.icu.util.ULocale;
import android.os.Build;
import android.text.CharSequenceCharacterIterator;
import android.text.Selection;
@@ -60,6 +61,14 @@ public class WordIterator implements Selection.PositionIterator {
mIterator = BreakIterator.getWordInstance(locale);
}
/**
* Constructs a new WordIterator for the specified locale.
* @param locale The locale to be used for analyzing the text.
*/
public WordIterator(ULocale locale) {
mIterator = BreakIterator.getWordInstance(locale);
}
@UnsupportedAppUsage
public void setCharSequence(@NonNull CharSequence charSequence, int start, int end) {
if (0 <= start && end <= charSequence.length()) {

View File

@@ -151,6 +151,7 @@ import android.util.DisplayMetrics;
import android.util.FeatureFlagUtils;
import android.util.IntArray;
import android.util.Log;
import android.util.Range;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.AccessibilityIterators.TextSegmentIterator;
@@ -9312,27 +9313,27 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
/** @hide */
public int performHandwritingSelectGesture(@NonNull SelectGesture gesture) {
int[] range = getRangeForRect(
Range<Integer> range = getRangeForRect(
convertFromScreenToContentCoordinates(gesture.getSelectionArea()),
gesture.getGranularity());
if (range == null) {
return handleGestureFailure(gesture);
}
Selection.setSelection(getEditableText(), range[0], range[1]);
Selection.setSelection(getEditableText(), range.getLower(), range.getUpper());
mEditor.startSelectionActionModeAsync(/* adjustSelection= */ false);
return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS;
}
/** @hide */
public int performHandwritingDeleteGesture(@NonNull DeleteGesture gesture) {
int[] range = getRangeForRect(
Range<Integer> range = getRangeForRect(
convertFromScreenToContentCoordinates(gesture.getDeletionArea()),
gesture.getGranularity());
if (range == null) {
return handleGestureFailure(gesture);
}
int start = range[0];
int end = range[1];
int start = range.getLower();
int end = range.getUpper();
// For word granularity, adjust the start and end offsets to remove extra whitespace around
// the deleted text.
@@ -9523,7 +9524,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
@Nullable
private int[] getRangeForRect(@NonNull RectF area, int granularity) {
private Range<Integer> getRangeForRect(@NonNull RectF area, int granularity) {
SegmentFinder segmentFinder;
if (granularity == HandwritingGesture.GRANULARITY_WORD) {
WordIterator wordIterator = getWordIterator();