Merge "Make PrecomputedText Spannable for supporting selection" into pi-dev
am: 71ed54f377
Change-Id: I9f755b9ba3b5b4b909f57708bb7bdcec349e0724
This commit is contained in:
@@ -704,7 +704,12 @@ public class DynamicLayout extends Layout {
|
||||
// Spans other than ReplacementSpan can be ignored because line top and bottom are
|
||||
// disjunction of all tops and bottoms, although it's not optimal.
|
||||
final Paint paint = getPaint();
|
||||
paint.getTextBounds(text, start, end, mTempRect);
|
||||
if (text instanceof PrecomputedText) {
|
||||
PrecomputedText precomputed = (PrecomputedText) text;
|
||||
precomputed.getBounds(start, end, mTempRect);
|
||||
} else {
|
||||
paint.getTextBounds(text, start, end, mTempRect);
|
||||
}
|
||||
final Paint.FontMetricsInt fm = paint.getFontMetricsInt();
|
||||
return mTempRect.top < fm.top || mTempRect.bottom > fm.bottom;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.text.AutoGrowArray.ByteArray;
|
||||
import android.text.AutoGrowArray.FloatArray;
|
||||
import android.text.AutoGrowArray.IntArray;
|
||||
@@ -296,6 +297,18 @@ public class MeasuredParagraph {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the bounding rectangle that encloses all of the characters, with an implied origin
|
||||
* at (0, 0).
|
||||
*
|
||||
* This is available only if the MeasuredParagraph is computed with buildForStaticLayout.
|
||||
*/
|
||||
public void getBounds(@NonNull Paint paint, @IntRange(from = 0) int start,
|
||||
@IntRange(from = 0) int end, @NonNull Rect bounds) {
|
||||
nGetBounds(mNativePtr, mCopiedBuffer, paint.getNativeInstance(), start, end,
|
||||
paint.getBidiFlags(), bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates new MeasuredParagraph for Bidi computation.
|
||||
*
|
||||
@@ -728,4 +741,7 @@ public class MeasuredParagraph {
|
||||
|
||||
@CriticalNative
|
||||
private static native int nGetMemoryUsage(/* Non Zero */ long nativePtr);
|
||||
|
||||
private static native void nGetBounds(long nativePtr, char[] buf, long paintPtr, int start,
|
||||
int end, int bidiFlag, Rect rect);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package android.text;
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.graphics.Rect;
|
||||
import android.text.style.MetricAffectingSpan;
|
||||
import android.util.IntArray;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
@@ -61,7 +63,7 @@ import java.util.Objects;
|
||||
* {@link android.widget.TextView} will be rejected internally and compute the text layout again
|
||||
* with the current {@link android.widget.TextView} parameters.
|
||||
*/
|
||||
public class PrecomputedText implements Spanned {
|
||||
public class PrecomputedText implements Spannable {
|
||||
private static final char LINE_FEED = '\n';
|
||||
|
||||
/**
|
||||
@@ -268,7 +270,7 @@ public class PrecomputedText implements Spanned {
|
||||
};
|
||||
|
||||
// The original text.
|
||||
private final @NonNull SpannedString mText;
|
||||
private final @NonNull SpannableString mText;
|
||||
|
||||
// The inclusive start offset of the measuring target.
|
||||
private final @IntRange(from = 0) int mStart;
|
||||
@@ -342,7 +344,7 @@ public class PrecomputedText implements Spanned {
|
||||
private PrecomputedText(@NonNull CharSequence text, @IntRange(from = 0) int start,
|
||||
@IntRange(from = 0) int end, @NonNull Params param,
|
||||
@NonNull MeasuredParagraph[] measuredTexts, @NonNull int[] paragraphBreakPoints) {
|
||||
mText = new SpannedString(text);
|
||||
mText = new SpannableString(text);
|
||||
mStart = start;
|
||||
mEnd = end;
|
||||
mParams = param;
|
||||
@@ -448,6 +450,21 @@ public class PrecomputedText implements Spanned {
|
||||
return getMeasuredParagraph(paraIndex).getWidth(start - paraStart, end - paraStart);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void getBounds(@IntRange(from = 0) int start, @IntRange(from = 0) int end,
|
||||
@NonNull Rect bounds) {
|
||||
final int paraIndex = findParaIndex(start);
|
||||
final int paraStart = getParagraphStart(paraIndex);
|
||||
final int paraEnd = getParagraphEnd(paraIndex);
|
||||
if (start < paraStart || paraEnd < end) {
|
||||
throw new RuntimeException("Cannot measured across the paragraph:"
|
||||
+ "para: (" + paraStart + ", " + paraEnd + "), "
|
||||
+ "request: (" + start + ", " + end + ")");
|
||||
}
|
||||
getMeasuredParagraph(paraIndex).getBounds(mParams.mPaint,
|
||||
start - paraStart, end - paraStart, bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of native PrecomputedText memory usage.
|
||||
*
|
||||
@@ -462,6 +479,35 @@ public class PrecomputedText implements Spanned {
|
||||
return r;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Spannable overrides
|
||||
//
|
||||
// Do not allow to modify MetricAffectingSpan
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if {@link MetricAffectingSpan} is specified.
|
||||
*/
|
||||
@Override
|
||||
public void setSpan(Object what, int start, int end, int flags) {
|
||||
if (what instanceof MetricAffectingSpan) {
|
||||
throw new IllegalArgumentException(
|
||||
"MetricAffectingSpan can not be set to PrecomputedText.");
|
||||
}
|
||||
mText.setSpan(what, start, end, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if {@link MetricAffectingSpan} is specified.
|
||||
*/
|
||||
@Override
|
||||
public void removeSpan(Object what) {
|
||||
if (what instanceof MetricAffectingSpan) {
|
||||
throw new IllegalArgumentException(
|
||||
"MetricAffectingSpan can not be removed from PrecomputedText.");
|
||||
}
|
||||
mText.removeSpan(what);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Spanned overrides
|
||||
//
|
||||
|
||||
@@ -5642,6 +5642,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
needEditableForNotification = true;
|
||||
}
|
||||
|
||||
PrecomputedText precomputed =
|
||||
(text instanceof PrecomputedText) ? (PrecomputedText) text : null;
|
||||
if (type == BufferType.EDITABLE || getKeyListener() != null
|
||||
|| needEditableForNotification) {
|
||||
createEditorIfNeeded();
|
||||
@@ -5651,10 +5653,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
setFilters(t, mFilters);
|
||||
InputMethodManager imm = InputMethodManager.peekInstance();
|
||||
if (imm != null) imm.restartInput(this);
|
||||
} else if (type == BufferType.SPANNABLE || mMovement != null) {
|
||||
text = mSpannableFactory.newSpannable(text);
|
||||
} else if (text instanceof PrecomputedText) {
|
||||
PrecomputedText precomputed = (PrecomputedText) text;
|
||||
} else if (precomputed != null) {
|
||||
if (mTextDir == null) {
|
||||
mTextDir = getTextDirectionHeuristic();
|
||||
}
|
||||
@@ -5667,6 +5666,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
+ "PrecomputedText: " + precomputed.getParams()
|
||||
+ "TextView: " + getTextMetricsParams());
|
||||
}
|
||||
} else if (type == BufferType.SPANNABLE || mMovement != null) {
|
||||
text = mSpannableFactory.newSpannable(text);
|
||||
} else if (!(text instanceof CharWrapper)) {
|
||||
text = TextUtils.stringOrSpannedString(text);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user