Loading core/java/android/text/SpannableStringBuilder.java +52 −80 Original line number Diff line number Diff line Loading @@ -262,19 +262,8 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable return append(String.valueOf(text)); } private int change(int start, int end, CharSequence tb, int tbstart, int tbend) { return change(true, start, end, tb, tbstart, tbend); } private int change(boolean notify, int start, int end, CharSequence tb, int tbstart, int tbend) { private void change(int start, int end, CharSequence tb, int tbstart, int tbend) { checkRange("replace", start, end); int ret = tbend - tbstart; TextWatcher[] recipients = null; if (notify) { recipients = sendTextWillChange(start, end - start, tbend - tbstart); } for (int i = mSpanCount - 1; i >= 0; i--) { if ((mSpanFlags[i] & SPAN_PARAGRAPH) == SPAN_PARAGRAPH) { Loading Loading @@ -338,7 +327,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable en = tbend; if (getSpanStart(spans[i]) < 0) { setSpan(true, spans[i], setSpan(false, spans[i], st - tbstart + start, en - tbstart + start, sp.getSpanFlags(spans[i])); Loading @@ -346,24 +335,16 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable } } if (end > start) { // no need for span fixup on pure insertion if (tbend > tbstart && end - start == 0) { if (notify) { sendTextChange(recipients, start, end - start, tbend - tbstart); sendTextHasChanged(recipients); } return ret; } boolean atend = (mGapStart + mGapLength == mText.length); boolean atEnd = (mGapStart + mGapLength == mText.length); for (int i = mSpanCount - 1; i >= 0; i--) { if (mSpanStarts[i] >= start && mSpanStarts[i] < mGapStart + mGapLength) { int flag = (mSpanFlags[i] & START_MASK) >> START_SHIFT; if (flag == POINT || (flag == PARAGRAPH && atend)) if (flag == POINT || (flag == PARAGRAPH && atEnd)) mSpanStarts[i] = mGapStart + mGapLength; else mSpanStarts[i] = start; Loading @@ -373,7 +354,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable mSpanEnds[i] < mGapStart + mGapLength) { int flag = (mSpanFlags[i] & END_MASK); if (flag == POINT || (flag == PARAGRAPH && atend)) if (flag == POINT || (flag == PARAGRAPH && atEnd)) mSpanEnds[i] = mGapStart + mGapLength; else mSpanEnds[i] = start; Loading @@ -384,13 +365,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable removeSpan(i); } } if (notify) { sendTextChange(recipients, start, end - start, tbend - tbstart); sendTextHasChanged(recipients); } return ret; } private void removeSpan(int i) { Loading Loading @@ -425,8 +400,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable CharSequence tb, int tbstart, int tbend) { int filtercount = mFilters.length; for (int i = 0; i < filtercount; i++) { CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end); CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end); if (repl != null) { tb = repl; Loading @@ -435,11 +409,17 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable } } if (end == start && tbstart == tbend) { final int origLen = end - start; final int newLen = tbend - tbstart; if (origLen == 0 && newLen == 0) { return this; } if (end == start || tbstart == tbend) { TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class); sendBeforeTextChanged(textWatchers, start, origLen, newLen); if (origLen == 0 || newLen == 0) { change(start, end, tb, tbstart, tbend); } else { int selstart = Selection.getSelectionStart(this); Loading @@ -450,11 +430,6 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable checkRange("replace", start, end); moveGapTo(end); TextWatcher[] recipients; int origlen = end - start; recipients = sendTextWillChange(start, origlen, tbend - tbstart); if (mGapLength < 2) resizeFor(length() + 1); Loading @@ -475,9 +450,9 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable new Exception("mGapLength < 1").printStackTrace(); } int inserted = change(false, start + 1, start + 1, tb, tbstart, tbend); change(false, start, start + 1, "", 0, 0); change(false, start + inserted, start + inserted + origlen, "", 0, 0); change(start + 1, start + 1, tb, tbstart, tbend); change(start, start + 1, "", 0, 0); change(start + newLen, start + newLen + origLen, "", 0, 0); /* * Special case to keep the cursor in the same position Loading @@ -490,7 +465,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable if (selstart > start && selstart < end) { long off = selstart - start; off = off * inserted / (end - start); off = off * newLen / (end - start); selstart = (int) off + start; setSpan(false, Selection.SELECTION_START, selstart, selstart, Loading @@ -499,15 +474,16 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable if (selend > start && selend < end) { long off = selend - start; off = off * inserted / (end - start); off = off * newLen / (end - start); selend = (int) off + start; setSpan(false, Selection.SELECTION_END, selend, selend, Spanned.SPAN_POINT_POINT); } sendTextChange(recipients, start, origlen, inserted); sendTextHasChanged(recipients); } sendTextChanged(textWatchers, start, origLen, newLen); sendAfterTextChanged(textWatchers); return this; } Loading Loading @@ -872,30 +848,27 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable return new String(buf); } private TextWatcher[] sendTextWillChange(int start, int before, int after) { TextWatcher[] recip = getSpans(start, start + before, TextWatcher.class); int n = recip.length; private void sendBeforeTextChanged(TextWatcher[] watchers, int start, int before, int after) { int n = watchers.length; for (int i = 0; i < n; i++) { recip[i].beforeTextChanged(this, start, before, after); watchers[i].beforeTextChanged(this, start, before, after); } return recip; } private void sendTextChange(TextWatcher[] recip, int start, int before, int after) { int n = recip.length; private void sendTextChanged(TextWatcher[] watchers, int start, int before, int after) { int n = watchers.length; for (int i = 0; i < n; i++) { recip[i].onTextChanged(this, start, before, after); watchers[i].onTextChanged(this, start, before, after); } } private void sendTextHasChanged(TextWatcher[] recip) { int n = recip.length; private void sendAfterTextChanged(TextWatcher[] watchers) { int n = watchers.length; for (int i = 0; i < n; i++) { recip[i].afterTextChanged(this); watchers[i].afterTextChanged(this); } } Loading Loading @@ -1037,8 +1010,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * Don't call this yourself -- exists for Canvas to use internally. * {@hide} */ public void drawText(Canvas c, int start, int end, float x, float y, Paint p) { public void drawText(Canvas c, int start, int end, float x, float y, Paint p) { checkRange("drawText", start, end); if (end <= mGapStart) { Loading @@ -1059,8 +1031,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * Don't call this yourself -- exists for Canvas to use internally. * {@hide} */ public void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, public void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, float x, float y, int flags, Paint p) { checkRange("drawTextRun", start, end); Loading Loading @@ -1262,6 +1233,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable private int[] mSpanFlags; private int mSpanCount; // TODO These value are tightly related to the public SPAN_MARK/POINT values in {@link Spanned} private static final int POINT = 2; private static final int PARAGRAPH = 3; Loading Loading
core/java/android/text/SpannableStringBuilder.java +52 −80 Original line number Diff line number Diff line Loading @@ -262,19 +262,8 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable return append(String.valueOf(text)); } private int change(int start, int end, CharSequence tb, int tbstart, int tbend) { return change(true, start, end, tb, tbstart, tbend); } private int change(boolean notify, int start, int end, CharSequence tb, int tbstart, int tbend) { private void change(int start, int end, CharSequence tb, int tbstart, int tbend) { checkRange("replace", start, end); int ret = tbend - tbstart; TextWatcher[] recipients = null; if (notify) { recipients = sendTextWillChange(start, end - start, tbend - tbstart); } for (int i = mSpanCount - 1; i >= 0; i--) { if ((mSpanFlags[i] & SPAN_PARAGRAPH) == SPAN_PARAGRAPH) { Loading Loading @@ -338,7 +327,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable en = tbend; if (getSpanStart(spans[i]) < 0) { setSpan(true, spans[i], setSpan(false, spans[i], st - tbstart + start, en - tbstart + start, sp.getSpanFlags(spans[i])); Loading @@ -346,24 +335,16 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable } } if (end > start) { // no need for span fixup on pure insertion if (tbend > tbstart && end - start == 0) { if (notify) { sendTextChange(recipients, start, end - start, tbend - tbstart); sendTextHasChanged(recipients); } return ret; } boolean atend = (mGapStart + mGapLength == mText.length); boolean atEnd = (mGapStart + mGapLength == mText.length); for (int i = mSpanCount - 1; i >= 0; i--) { if (mSpanStarts[i] >= start && mSpanStarts[i] < mGapStart + mGapLength) { int flag = (mSpanFlags[i] & START_MASK) >> START_SHIFT; if (flag == POINT || (flag == PARAGRAPH && atend)) if (flag == POINT || (flag == PARAGRAPH && atEnd)) mSpanStarts[i] = mGapStart + mGapLength; else mSpanStarts[i] = start; Loading @@ -373,7 +354,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable mSpanEnds[i] < mGapStart + mGapLength) { int flag = (mSpanFlags[i] & END_MASK); if (flag == POINT || (flag == PARAGRAPH && atend)) if (flag == POINT || (flag == PARAGRAPH && atEnd)) mSpanEnds[i] = mGapStart + mGapLength; else mSpanEnds[i] = start; Loading @@ -384,13 +365,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable removeSpan(i); } } if (notify) { sendTextChange(recipients, start, end - start, tbend - tbstart); sendTextHasChanged(recipients); } return ret; } private void removeSpan(int i) { Loading Loading @@ -425,8 +400,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable CharSequence tb, int tbstart, int tbend) { int filtercount = mFilters.length; for (int i = 0; i < filtercount; i++) { CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end); CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end); if (repl != null) { tb = repl; Loading @@ -435,11 +409,17 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable } } if (end == start && tbstart == tbend) { final int origLen = end - start; final int newLen = tbend - tbstart; if (origLen == 0 && newLen == 0) { return this; } if (end == start || tbstart == tbend) { TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class); sendBeforeTextChanged(textWatchers, start, origLen, newLen); if (origLen == 0 || newLen == 0) { change(start, end, tb, tbstart, tbend); } else { int selstart = Selection.getSelectionStart(this); Loading @@ -450,11 +430,6 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable checkRange("replace", start, end); moveGapTo(end); TextWatcher[] recipients; int origlen = end - start; recipients = sendTextWillChange(start, origlen, tbend - tbstart); if (mGapLength < 2) resizeFor(length() + 1); Loading @@ -475,9 +450,9 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable new Exception("mGapLength < 1").printStackTrace(); } int inserted = change(false, start + 1, start + 1, tb, tbstart, tbend); change(false, start, start + 1, "", 0, 0); change(false, start + inserted, start + inserted + origlen, "", 0, 0); change(start + 1, start + 1, tb, tbstart, tbend); change(start, start + 1, "", 0, 0); change(start + newLen, start + newLen + origLen, "", 0, 0); /* * Special case to keep the cursor in the same position Loading @@ -490,7 +465,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable if (selstart > start && selstart < end) { long off = selstart - start; off = off * inserted / (end - start); off = off * newLen / (end - start); selstart = (int) off + start; setSpan(false, Selection.SELECTION_START, selstart, selstart, Loading @@ -499,15 +474,16 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable if (selend > start && selend < end) { long off = selend - start; off = off * inserted / (end - start); off = off * newLen / (end - start); selend = (int) off + start; setSpan(false, Selection.SELECTION_END, selend, selend, Spanned.SPAN_POINT_POINT); } sendTextChange(recipients, start, origlen, inserted); sendTextHasChanged(recipients); } sendTextChanged(textWatchers, start, origLen, newLen); sendAfterTextChanged(textWatchers); return this; } Loading Loading @@ -872,30 +848,27 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable return new String(buf); } private TextWatcher[] sendTextWillChange(int start, int before, int after) { TextWatcher[] recip = getSpans(start, start + before, TextWatcher.class); int n = recip.length; private void sendBeforeTextChanged(TextWatcher[] watchers, int start, int before, int after) { int n = watchers.length; for (int i = 0; i < n; i++) { recip[i].beforeTextChanged(this, start, before, after); watchers[i].beforeTextChanged(this, start, before, after); } return recip; } private void sendTextChange(TextWatcher[] recip, int start, int before, int after) { int n = recip.length; private void sendTextChanged(TextWatcher[] watchers, int start, int before, int after) { int n = watchers.length; for (int i = 0; i < n; i++) { recip[i].onTextChanged(this, start, before, after); watchers[i].onTextChanged(this, start, before, after); } } private void sendTextHasChanged(TextWatcher[] recip) { int n = recip.length; private void sendAfterTextChanged(TextWatcher[] watchers) { int n = watchers.length; for (int i = 0; i < n; i++) { recip[i].afterTextChanged(this); watchers[i].afterTextChanged(this); } } Loading Loading @@ -1037,8 +1010,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * Don't call this yourself -- exists for Canvas to use internally. * {@hide} */ public void drawText(Canvas c, int start, int end, float x, float y, Paint p) { public void drawText(Canvas c, int start, int end, float x, float y, Paint p) { checkRange("drawText", start, end); if (end <= mGapStart) { Loading @@ -1059,8 +1031,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * Don't call this yourself -- exists for Canvas to use internally. * {@hide} */ public void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, public void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd, float x, float y, int flags, Paint p) { checkRange("drawTextRun", start, end); Loading Loading @@ -1262,6 +1233,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable private int[] mSpanFlags; private int mSpanCount; // TODO These value are tightly related to the public SPAN_MARK/POINT values in {@link Spanned} private static final int POINT = 2; private static final int PARAGRAPH = 3; Loading