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

Commit 9c95443c authored by Siyamed Sinir's avatar Siyamed Sinir Committed by Android (Google) Code Review
Browse files

Merge "Fix SpannableStringBuilder.replace() exception."

parents 6c333507 3463c04b
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -40,10 +40,14 @@ extends CharSequence, GetChars, Spannable, Appendable
     * is Spanned, the spans from it are preserved into the Editable.
     * Existing spans within the Editable that entirely cover the replaced
     * range are retained, but any that were strictly within the range
     * that was replaced are removed.  As a special case, the cursor
     * position is preserved even when the entire range where it is
     * located is replaced.
     * that was replaced are removed. If the <code>source</code> contains a span
     * with {@link Spanned#SPAN_PARAGRAPH} flag, and it does not satisfy the
     * paragraph boundary constraint, it is not retained. As a special case, the
     * cursor position is preserved even when the entire range where it is located
     * is replaced.
     * @return  a reference to this object.
     *
     * @see Spanned#SPAN_PARAGRAPH
     */
    public Editable replace(int st, int en, CharSequence source, int start, int end);

+37 −16
Original line number Diff line number Diff line
@@ -421,8 +421,17 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable

                // Add span only if this object is not yet used as a span in this string
                if (getSpanStart(spans[i]) < 0) {
                    setSpan(false, spans[i], st - csStart + start, en - csStart + start,
                            sp.getSpanFlags(spans[i]) | SPAN_ADDED);
                    int copySpanStart = st - csStart + start;
                    int copySpanEnd = en - csStart + start;
                    int copySpanFlags = sp.getSpanFlags(spans[i]) | SPAN_ADDED;

                    int flagsStart = (copySpanFlags & START_MASK) >> START_SHIFT;
                    int flagsEnd = copySpanFlags & END_MASK;

                    if(!isInvalidParagraphStart(copySpanStart, flagsStart) &&
                            !isInvalidParagraphEnd(copySpanEnd, flagsEnd)) {
                        setSpan(false, spans[i], copySpanStart, copySpanEnd, copySpanFlags);
                    }
                }
            }
            restoreInvariants();
@@ -666,24 +675,14 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
        checkRange("setSpan", start, end);

        int flagsStart = (flags & START_MASK) >> START_SHIFT;
        if (flagsStart == PARAGRAPH) {
            if (start != 0 && start != length()) {
                char c = charAt(start - 1);

                if (c != '\n')
        if(isInvalidParagraphStart(start, flagsStart)) {
            throw new RuntimeException("PARAGRAPH span must start at paragraph boundary");
        }
        }

        int flagsEnd = flags & END_MASK;
        if (flagsEnd == PARAGRAPH) {
            if (end != 0 && end != length()) {
                char c = charAt(end - 1);

                if (c != '\n')
        if(isInvalidParagraphEnd(end, flagsEnd)) {
            throw new RuntimeException("PARAGRAPH span must end at paragraph boundary");
        }
        }

        // 0-length Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        if (flagsStart == POINT && flagsEnd == MARK && start == end) {
@@ -761,6 +760,28 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
        }
    }

    private final boolean isInvalidParagraphStart(int start, int flagsStart) {
        if (flagsStart == PARAGRAPH) {
            if (start != 0 && start != length()) {
                char c = charAt(start - 1);

                if (c != '\n') return true;
            }
        }
        return false;
    }

    private final boolean isInvalidParagraphEnd(int end, int flagsEnd) {
        if (flagsEnd == PARAGRAPH) {
            if (end != 0 && end != length()) {
                char c = charAt(end - 1);

                if (c != '\n') return true;
            }
        }
        return false;
    }

    /**
     * Remove the specified markup object from the buffer.
     */
+3 −1
Original line number Diff line number Diff line
@@ -81,7 +81,9 @@ extends CharSequence
     * immediately after a \n character, and if the \n
     * that anchors it is deleted, the endpoint is pulled to the
     * next \n that follows in the buffer (or to the end of
     * the buffer).
     * the buffer). If a span with SPAN_PARAGRAPH flag is pasted
     * into another text and the paragraph boundary constraint
     * is not satisfied, the span is discarded.
     */
    public static final int SPAN_PARAGRAPH =   0x33;