Skip to content

Commit 0caf421

Browse files
Gilles DebunneAndroid (Google) Code Review
authored andcommitted
Merge "Final fix in SpannableStringBuilder." into jb-dev
2 parents fb0caad + e244868 commit 0caf421

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

core/java/android/text/SpannableStringBuilder.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ private void change(int start, int end, CharSequence cs, int csStart, int csEnd)
308308
resizeFor(mText.length + nbNewChars - mGapLength);
309309
}
310310

311+
final boolean textIsRemoved = replacementLength == 0;
311312
// The removal pass needs to be done before the gap is updated in order to broadcast the
312313
// correct previous positions to the correct intersecting SpanWatchers
313314
if (replacedLength > 0) { // no need for span fixup on pure insertion
@@ -319,12 +320,15 @@ private void change(int start, int end, CharSequence cs, int csStart, int csEnd)
319320
while (i < mSpanCount) {
320321
if ((mSpanFlags[i] & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) ==
321322
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE &&
322-
mSpanStarts[i] >= start && mSpanStarts[i] < mGapStart + mGapLength &&
323-
mSpanEnds[i] >= start && mSpanEnds[i] < mGapStart + mGapLength) {
323+
mSpanStarts[i] >= start && mSpanStarts[i] < mGapStart + mGapLength &&
324+
mSpanEnds[i] >= start && mSpanEnds[i] < mGapStart + mGapLength &&
325+
// This condition indicates that the span would become empty
326+
(textIsRemoved || mSpanStarts[i] > start || mSpanEnds[i] < mGapStart)) {
324327
removeSpan(i);
325-
} else {
326-
i++;
328+
continue; // do not increment i, spans will be shifted left in the array
327329
}
330+
331+
i++;
328332
}
329333
}
330334

@@ -338,7 +342,6 @@ private void change(int start, int end, CharSequence cs, int csStart, int csEnd)
338342

339343
if (replacedLength > 0) { // no need for span fixup on pure insertion
340344
final boolean atEnd = (mGapStart + mGapLength == mText.length);
341-
final boolean textIsRemoved = replacementLength == 0;
342345

343346
for (int i = 0; i < mSpanCount; i++) {
344347
final int startFlag = (mSpanFlags[i] & START_MASK) >> START_SHIFT;
@@ -390,9 +393,9 @@ private int updatedIntervalBound(int offset, int start, int nbNewChars, int flag
390393
return mGapStart + mGapLength;
391394
}
392395
} else { // MARK
393-
// MARKs should be moved to the start, with the exception of a mark located at the
394-
// end of the range (which will be < mGapStart + mGapLength since mGapLength > 0)
395-
// which should stay 'unchanged' at the end of the replaced text.
396+
// MARKs should be moved to the start, with the exception of a mark located at
397+
// the end of the range (which will be < mGapStart + mGapLength since mGapLength
398+
// is > 0, which should stay 'unchanged' at the end of the replaced text.
396399
if (textIsRemoved || offset < mGapStart - nbNewChars) {
397400
return start;
398401
} else {

0 commit comments

Comments
 (0)