diff options
author | Gilles Debunne <debunne@google.com> | 2012-05-04 15:29:09 -0700 |
---|---|---|
committer | Gilles Debunne <debunne@google.com> | 2012-05-04 16:24:49 -0700 |
commit | e244868053cfe44742b42e75df3a08d0c5914bca (patch) | |
tree | fc3d7700f12a1dd0b991c1b291667d8e6cabc5a9 /core | |
parent | 4380f9542fcb4a452332ecbea6a2036a2b159ab3 (diff) | |
download | frameworks_base-e244868053cfe44742b42e75df3a08d0c5914bca.zip frameworks_base-e244868053cfe44742b42e75df3a08d0c5914bca.tar.gz frameworks_base-e244868053cfe44742b42e75df3a08d0c5914bca.tar.bz2 |
Final fix in SpannableStringBuilder.
Bug 6448052
The empty EXCLUSIVE removal condition was incorrect.
Also changed the unit test the didn't catch this problem.
Change-Id: I5576d830cdfa6cc3716c878fb698695a2978b296
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/text/SpannableStringBuilder.java | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java index 09c9438..0f30d25 100644 --- a/core/java/android/text/SpannableStringBuilder.java +++ b/core/java/android/text/SpannableStringBuilder.java @@ -308,6 +308,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable resizeFor(mText.length + nbNewChars - mGapLength); } + final boolean textIsRemoved = replacementLength == 0; // The removal pass needs to be done before the gap is updated in order to broadcast the // correct previous positions to the correct intersecting SpanWatchers if (replacedLength > 0) { // no need for span fixup on pure insertion @@ -319,12 +320,15 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable while (i < mSpanCount) { if ((mSpanFlags[i] & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) == Spanned.SPAN_EXCLUSIVE_EXCLUSIVE && - mSpanStarts[i] >= start && mSpanStarts[i] < mGapStart + mGapLength && - mSpanEnds[i] >= start && mSpanEnds[i] < mGapStart + mGapLength) { + mSpanStarts[i] >= start && mSpanStarts[i] < mGapStart + mGapLength && + mSpanEnds[i] >= start && mSpanEnds[i] < mGapStart + mGapLength && + // This condition indicates that the span would become empty + (textIsRemoved || mSpanStarts[i] > start || mSpanEnds[i] < mGapStart)) { removeSpan(i); - } else { - i++; + continue; // do not increment i, spans will be shifted left in the array } + + i++; } } @@ -338,7 +342,6 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable if (replacedLength > 0) { // no need for span fixup on pure insertion final boolean atEnd = (mGapStart + mGapLength == mText.length); - final boolean textIsRemoved = replacementLength == 0; for (int i = 0; i < mSpanCount; i++) { final int startFlag = (mSpanFlags[i] & START_MASK) >> START_SHIFT; @@ -390,9 +393,9 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable return mGapStart + mGapLength; } } else { // MARK - // MARKs should be moved to the start, with the exception of a mark located at the - // end of the range (which will be < mGapStart + mGapLength since mGapLength > 0) - // which should stay 'unchanged' at the end of the replaced text. + // MARKs should be moved to the start, with the exception of a mark located at + // the end of the range (which will be < mGapStart + mGapLength since mGapLength + // is > 0, which should stay 'unchanged' at the end of the replaced text. if (textIsRemoved || offset < mGapStart - nbNewChars) { return start; } else { |