diff options
| -rw-r--r-- | core/java/android/text/Editable.java | 10 | ||||
| -rw-r--r-- | core/java/android/text/SpannableStringBuilder.java | 53 | ||||
| -rw-r--r-- | core/java/android/text/Spanned.java | 4 |
3 files changed, 47 insertions, 20 deletions
diff --git a/core/java/android/text/Editable.java b/core/java/android/text/Editable.java index a284a0005918..b3f2c2a5c447 100644 --- a/core/java/android/text/Editable.java +++ b/core/java/android/text/Editable.java @@ -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); diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java index 40315add603d..42672384f316 100644 --- a/core/java/android/text/SpannableStringBuilder.java +++ b/core/java/android/text/SpannableStringBuilder.java @@ -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,23 +675,13 @@ 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') - throw new RuntimeException("PARAGRAPH span must start at paragraph boundary"); - } + 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') - throw new RuntimeException("PARAGRAPH span must end at paragraph boundary"); - } + if(isInvalidParagraphEnd(end, flagsEnd)) { + throw new RuntimeException("PARAGRAPH span must end at paragraph boundary"); } // 0-length Spanned.SPAN_EXCLUSIVE_EXCLUSIVE @@ -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. */ diff --git a/core/java/android/text/Spanned.java b/core/java/android/text/Spanned.java index a785d1b7d2c7..a0d54c26c6d9 100644 --- a/core/java/android/text/Spanned.java +++ b/core/java/android/text/Spanned.java @@ -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; |