diff options
| author | Gilles Debunne <debunne@google.com> | 2011-10-26 16:41:28 -0700 |
|---|---|---|
| committer | Gilles Debunne <debunne@google.com> | 2011-11-29 17:53:40 -0800 |
| commit | 8a439ac7a34d6b83782a672f3d6aa90fa262409c (patch) | |
| tree | 34a9393cc85c6d5e1cc62e12d42e39e0a041c9b3 /core/java/android/text/TextLine.java | |
| parent | 9b518d9304eb4ad17591944926231b661a3dfce0 (diff) | |
Performance improvement in TextView
Using a SpanSet to minimize the number the calls to getSpans.
This is a cherry pick of 145653 in ICS-MR1
Change-Id: I0a6e1fc7bd7a89325c2925bf98d59626d5e12995
Diffstat (limited to 'core/java/android/text/TextLine.java')
| -rw-r--r-- | core/java/android/text/TextLine.java | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 68fea1907b87..b73d90046303 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -119,6 +119,7 @@ class TextLine { * @param hasTabs true if the line might contain tabs or emoji * @param tabStops the tabStops. Can be null. */ + @SuppressWarnings("null") void set(TextPaint paint, CharSequence text, int start, int limit, int dir, Directions directions, boolean hasTabs, TabStops tabStops) { mPaint = paint; @@ -134,11 +135,12 @@ class TextLine { mSpanned = null; boolean hasReplacement = false; + SpanSet<ReplacementSpan> replacementSpans = null; if (text instanceof Spanned) { mSpanned = (Spanned) text; - ReplacementSpan[] spans = mSpanned.getSpans(start, limit, ReplacementSpan.class); - spans = TextUtils.removeEmptySpans(spans, mSpanned, ReplacementSpan.class); - hasReplacement = spans.length > 0; + replacementSpans = new SpanSet<ReplacementSpan>(mSpanned, start, limit, + ReplacementSpan.class); + hasReplacement = replacementSpans.numberOfSpans > 0; } mCharsValid = hasReplacement || hasTabs || directions != Layout.DIRS_ALL_LEFT_TO_RIGHT; @@ -156,10 +158,9 @@ class TextLine { // zero-width characters. char[] chars = mChars; for (int i = start, inext; i < limit; i = inext) { - inext = mSpanned.nextSpanTransition(i, limit, ReplacementSpan.class); - ReplacementSpan[] spans = mSpanned.getSpans(i, inext, ReplacementSpan.class); - spans = TextUtils.removeEmptySpans(spans, mSpanned, ReplacementSpan.class); - if (spans.length > 0) { + // replacementSpans cannot be null if hasReplacement is true + inext = replacementSpans.getNextTransition(i, limit); + if (replacementSpans.hasSpansIntersecting(i, inext)) { // transition into a span chars[i - start] = '\ufffc'; for (int j = i - start + 1, e = inext - start; j < e; ++j) { @@ -908,6 +909,15 @@ class TextLine { numberOfSpans = count; } + public boolean hasSpansIntersecting(int start, int end) { + for (int i = 0; i < numberOfSpans; i++) { + // equal test is valid since both intervals are not empty by construction + if (spanStarts[i] >= end || spanEnds[i] <= start) continue; + return true; + } + return false; + } + int getNextTransition(int start, int limit) { for (int i = 0; i < numberOfSpans; i++) { final int spanStart = spanStarts[i]; |
