Skip to content

Commit eb189d3

Browse files
Gilles DebunneAndroid (Google) Code Review
authored andcommitted
Merge "Performance improvement in TextView" into ics-mr1
2 parents 09cbff0 + 8a439ac commit eb189d3

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

core/java/android/text/TextLine.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ static TextLine recycle(TextLine tl) {
119119
* @param hasTabs true if the line might contain tabs or emoji
120120
* @param tabStops the tabStops. Can be null.
121121
*/
122+
@SuppressWarnings("null")
122123
void set(TextPaint paint, CharSequence text, int start, int limit, int dir,
123124
Directions directions, boolean hasTabs, TabStops tabStops) {
124125
mPaint = paint;
@@ -134,11 +135,12 @@ void set(TextPaint paint, CharSequence text, int start, int limit, int dir,
134135
mSpanned = null;
135136

136137
boolean hasReplacement = false;
138+
SpanSet<ReplacementSpan> replacementSpans = null;
137139
if (text instanceof Spanned) {
138140
mSpanned = (Spanned) text;
139-
ReplacementSpan[] spans = mSpanned.getSpans(start, limit, ReplacementSpan.class);
140-
spans = TextUtils.removeEmptySpans(spans, mSpanned, ReplacementSpan.class);
141-
hasReplacement = spans.length > 0;
141+
replacementSpans = new SpanSet<ReplacementSpan>(mSpanned, start, limit,
142+
ReplacementSpan.class);
143+
hasReplacement = replacementSpans.numberOfSpans > 0;
142144
}
143145

144146
mCharsValid = hasReplacement || hasTabs || directions != Layout.DIRS_ALL_LEFT_TO_RIGHT;
@@ -156,10 +158,9 @@ void set(TextPaint paint, CharSequence text, int start, int limit, int dir,
156158
// zero-width characters.
157159
char[] chars = mChars;
158160
for (int i = start, inext; i < limit; i = inext) {
159-
inext = mSpanned.nextSpanTransition(i, limit, ReplacementSpan.class);
160-
ReplacementSpan[] spans = mSpanned.getSpans(i, inext, ReplacementSpan.class);
161-
spans = TextUtils.removeEmptySpans(spans, mSpanned, ReplacementSpan.class);
162-
if (spans.length > 0) {
161+
// replacementSpans cannot be null if hasReplacement is true
162+
inext = replacementSpans.getNextTransition(i, limit);
163+
if (replacementSpans.hasSpansIntersecting(i, inext)) {
163164
// transition into a span
164165
chars[i - start] = '\ufffc';
165166
for (int j = i - start + 1, e = inext - start; j < e; ++j) {
@@ -908,6 +909,15 @@ private static class SpanSet<E> {
908909
numberOfSpans = count;
909910
}
910911

912+
public boolean hasSpansIntersecting(int start, int end) {
913+
for (int i = 0; i < numberOfSpans; i++) {
914+
// equal test is valid since both intervals are not empty by construction
915+
if (spanStarts[i] >= end || spanEnds[i] <= start) continue;
916+
return true;
917+
}
918+
return false;
919+
}
920+
911921
int getNextTransition(int start, int limit) {
912922
for (int i = 0; i < numberOfSpans; i++) {
913923
final int spanStart = spanStarts[i];

0 commit comments

Comments
 (0)