@@ -1223,8 +1223,6 @@ void onDraw(Canvas canvas, Layout layout, Path highlight, Paint highlightPaint,
12231223
12241224 private void drawHardwareAccelerated (Canvas canvas , Layout layout , Path highlight ,
12251225 Paint highlightPaint , int cursorOffsetVertical ) {
1226- final int width = mTextView .getWidth ();
1227-
12281226 final long lineRange = layout .getLineRangeForDraw (canvas );
12291227 int firstLine = TextUtils .unpackRangeStartFromLong (lineRange );
12301228 int lastLine = TextUtils .unpackRangeEndFromLong (lineRange );
@@ -1243,10 +1241,6 @@ private void drawHardwareAccelerated(Canvas canvas, Layout layout, Path highligh
12431241 int [] blockIndices = dynamicLayout .getBlockIndices ();
12441242 final int numberOfBlocks = dynamicLayout .getNumberOfBlocks ();
12451243
1246- final int scrollX = mTextView .getScrollX ();
1247- final int scrollY = mTextView .getScrollY ();
1248- canvas .translate (scrollX , scrollY );
1249-
12501244 int endOfPreviousBlock = -1 ;
12511245 int searchStartIndex = 0 ;
12521246 for (int i = 0 ; i < numberOfBlocks ; i ++) {
@@ -1274,34 +1268,43 @@ private void drawHardwareAccelerated(Canvas canvas, Layout layout, Path highligh
12741268 final int blockBeginLine = endOfPreviousBlock + 1 ;
12751269 final int top = layout .getLineTop (blockBeginLine );
12761270 final int bottom = layout .getLineBottom (blockEndLine );
1271+ int left = 0 ;
1272+ int right = mTextView .getWidth ();
1273+ if (mTextView .getHorizontallyScrolling ()) {
1274+ float min = Float .MAX_VALUE ;
1275+ float max = Float .MIN_VALUE ;
1276+ for (int line = blockBeginLine ; line <= blockEndLine ; line ++) {
1277+ min = Math .min (min , layout .getLineLeft (line ));
1278+ max = Math .max (max , layout .getLineRight (line ));
1279+ }
1280+ left = (int ) min ;
1281+ right = (int ) (max + 0.5f );
1282+ }
12771283
12781284 final HardwareCanvas hardwareCanvas = blockDisplayList .start ();
12791285 try {
1280- hardwareCanvas .setViewport (width , bottom - top );
1286+ // Tighten the bounds of the viewport to the actual text size
1287+ hardwareCanvas .setViewport (right - left , bottom - top );
12811288 // The dirty rect should always be null for a display list
12821289 hardwareCanvas .onPreDraw (null );
12831290 // drawText is always relative to TextView's origin, this translation brings
1284- // this range of text back to the top of the viewport
1285- hardwareCanvas .translate (-scrollX , -top );
1291+ // this range of text back to the top left corner of the viewport
1292+ hardwareCanvas .translate (-left , -top );
12861293 layout .drawText (hardwareCanvas , blockBeginLine , blockEndLine );
1287- hardwareCanvas . translate ( scrollX , top );
1294+ // No need to untranslate, previous context is popped after drawDisplayList
12881295 } finally {
12891296 hardwareCanvas .onPostDraw ();
12901297 blockDisplayList .end ();
1291- blockDisplayList .setLeftTopRightBottom (0 , top , width , bottom );
1298+ blockDisplayList .setLeftTopRightBottom (left , top , right , bottom );
12921299 // Same as drawDisplayList below, handled by our TextView's parent
12931300 blockDisplayList .setClipChildren (false );
12941301 }
12951302 }
12961303
1297- // TODO When View.USE_DISPLAY_LIST_PROPERTIES is the only code path, the
1298- // width and height parameters should be removed and the bounds set above in
1299- // setLeftTopRightBottom should be used instead for quick rejection.
13001304 ((HardwareCanvas ) canvas ).drawDisplayList (blockDisplayList , null ,
13011305 0 /* no child clipping, our TextView parent enforces it */ );
1306+
13021307 endOfPreviousBlock = blockEndLine ;
1303-
1304- canvas .translate (-scrollX , -scrollY );
13051308 }
13061309 } else {
13071310 // Boring layout is used for empty and hint text
0 commit comments