Loading core/java/android/text/Editable.java +7 −3 Original line number Diff line number Diff line Loading @@ -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); Loading core/java/android/text/SpannableStringBuilder.java +37 −16 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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) { Loading Loading @@ -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. */ Loading core/java/android/text/Spanned.java +3 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
core/java/android/text/Editable.java +7 −3 Original line number Diff line number Diff line Loading @@ -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); Loading
core/java/android/text/SpannableStringBuilder.java +37 −16 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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) { Loading Loading @@ -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. */ Loading
core/java/android/text/Spanned.java +3 −1 Original line number Diff line number Diff line Loading @@ -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; Loading