summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorGilles Debunne <debunne@google.com>2012-05-04 15:29:09 -0700
committerGilles Debunne <debunne@google.com>2012-05-04 16:24:49 -0700
commite244868053cfe44742b42e75df3a08d0c5914bca (patch)
treefc3d7700f12a1dd0b991c1b291667d8e6cabc5a9 /core
parent4380f9542fcb4a452332ecbea6a2036a2b159ab3 (diff)
downloadframeworks_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.java19
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 {