Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 284a0ae7 authored by Seigo Nonaka's avatar Seigo Nonaka Committed by android-build-merger
Browse files

Merge "Make PrecomputedText Spannable for supporting selection" into pi-dev am: 02c8d1b0

am: 42033475

Change-Id: Ibac099cd1256e4a87299196dcfeda8d50c900197
parents 71a66ec7 42033475
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -44044,7 +44044,7 @@ package android.text {
    method public abstract int getSpanTypeId();
  }
  public class PrecomputedText implements android.text.Spanned {
  public class PrecomputedText implements android.text.Spannable {
    method public char charAt(int);
    method public static android.text.PrecomputedText create(java.lang.CharSequence, android.text.PrecomputedText.Params);
    method public int getParagraphCount();
@@ -44058,6 +44058,8 @@ package android.text {
    method public java.lang.CharSequence getText();
    method public int length();
    method public int nextSpanTransition(int, int, java.lang.Class);
    method public void removeSpan(java.lang.Object);
    method public void setSpan(java.lang.Object, int, int, int);
    method public java.lang.CharSequence subSequence(int, int);
  }
+6 −1
Original line number Diff line number Diff line
@@ -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();
        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;
    }
+16 −0
Original line number Diff line number Diff line
@@ -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);
}
+56 −5
Original line number Diff line number Diff line
@@ -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 com.android.internal.util.Preconditions;

@@ -57,10 +59,12 @@ import java.util.Objects;
 * </pre>
 *
 * Note that the {@link PrecomputedText} created from different parameters of the target
 * {@link android.widget.TextView} will be rejected internally and compute the text layout again
 * with the current {@link android.widget.TextView} parameters.
 * {@link android.widget.TextView} will be rejected.
 *
 * Note that any {@link android.text.NoCopySpan} attached to the original text won't be passed to
 * PrecomputedText.
 */
public class PrecomputedText implements Spanned {
public class PrecomputedText implements Spannable {
    private static final char LINE_FEED = '\n';

    /**
@@ -283,7 +287,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;
@@ -304,6 +308,9 @@ public class PrecomputedText implements Spanned {
     * presented can save work on the UI thread.
     * </p>
     *
     * Note that any {@link android.text.NoCopySpan} attached to the text won't be passed to the
     * created PrecomputedText.
     *
     * @param text the text to be measured
     * @param params parameters that define how text will be precomputed
     * @return A {@link PrecomputedText}
@@ -347,7 +354,7 @@ public class PrecomputedText implements Spanned {
    private PrecomputedText(@NonNull CharSequence text, @IntRange(from = 0) int start,
            @IntRange(from = 0) int end, @NonNull Params params,
            @NonNull ParagraphInfo[] paraInfo) {
        mText = new SpannedString(text);
        mText = new SpannableString(text, true /* ignoreNoCopySpan */);
        mStart = start;
        mEnd = end;
        mParams = params;
@@ -457,6 +464,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.
     *
@@ -471,6 +493,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
    //
+5 −4
Original line number Diff line number Diff line
@@ -5640,6 +5640,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();
@@ -5649,10 +5651,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();
            }
@@ -5665,6 +5664,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);
        }
Loading