@@ -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