Skip to content

Commit 0711047

Browse files
author
Gilles Debunne
committed
Handle non DynamicLayout in Editable draw method.
An Editable text will use a BoringLayout when the text is empty. Fallback on the regular layout draw text method when the layout does not support the block optimisation. Change-Id: Ie4bdb4381f2f58b71d7c35b2f5734e544e3115ea
1 parent 3df92c5 commit 0711047

File tree

1 file changed

+55
-54
lines changed

1 file changed

+55
-54
lines changed

core/java/android/widget/TextView.java

Lines changed: 55 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -11708,66 +11708,67 @@ private void drawHardwareAccelerated(Canvas canvas, Layout layout, Path highligh
1170811708
layout.drawBackground(canvas, highlight, mHighlightPaint, cursorOffsetVertical,
1170911709
firstLine, lastLine);
1171011710

11711-
if (mTextDisplayLists == null) {
11712-
mTextDisplayLists = new DisplayList[ArrayUtils.idealObjectArraySize(0)];
11713-
}
11714-
if (! (layout instanceof DynamicLayout)) {
11715-
Log.e(LOG_TAG, "Editable TextView is not using a DynamicLayout");
11716-
return;
11717-
}
11718-
11719-
DynamicLayout dynamicLayout = (DynamicLayout) layout;
11720-
int[] blockEnds = dynamicLayout.getBlockEnds();
11721-
int[] blockIndices = dynamicLayout.getBlockIndices();
11722-
final int numberOfBlocks = dynamicLayout.getNumberOfBlocks();
11723-
11724-
canvas.translate(mScrollX, mScrollY);
11725-
int endOfPreviousBlock = -1;
11726-
int searchStartIndex = 0;
11727-
for (int i = 0; i < numberOfBlocks; i++) {
11728-
int blockEnd = blockEnds[i];
11729-
int blockIndex = blockIndices[i];
11711+
if (layout instanceof DynamicLayout) {
11712+
if (mTextDisplayLists == null) {
11713+
mTextDisplayLists = new DisplayList[ArrayUtils.idealObjectArraySize(0)];
11714+
}
11715+
11716+
DynamicLayout dynamicLayout = (DynamicLayout) layout;
11717+
int[] blockEnds = dynamicLayout.getBlockEnds();
11718+
int[] blockIndices = dynamicLayout.getBlockIndices();
11719+
final int numberOfBlocks = dynamicLayout.getNumberOfBlocks();
11720+
11721+
canvas.translate(mScrollX, mScrollY);
11722+
int endOfPreviousBlock = -1;
11723+
int searchStartIndex = 0;
11724+
for (int i = 0; i < numberOfBlocks; i++) {
11725+
int blockEnd = blockEnds[i];
11726+
int blockIndex = blockIndices[i];
11727+
11728+
final boolean blockIsInvalid = blockIndex == DynamicLayout.INVALID_BLOCK_INDEX;
11729+
if (blockIsInvalid) {
11730+
blockIndex = getAvailableDisplayListIndex(blockIndices, numberOfBlocks,
11731+
searchStartIndex);
11732+
// Dynamic layout internal block indices structure is updated from Editor
11733+
blockIndices[i] = blockIndex;
11734+
searchStartIndex = blockIndex + 1;
11735+
}
1173011736

11731-
final boolean blockIsInvalid = blockIndex == DynamicLayout.INVALID_BLOCK_INDEX;
11732-
if (blockIsInvalid) {
11733-
blockIndex = getAvailableDisplayListIndex(blockIndices, numberOfBlocks,
11734-
searchStartIndex);
11735-
// Dynamic layout internal block indices structure is updated from Editor
11736-
blockIndices[i] = blockIndex;
11737-
searchStartIndex = blockIndex + 1;
11738-
}
11737+
DisplayList blockDisplayList = mTextDisplayLists[blockIndex];
11738+
if (blockDisplayList == null) {
11739+
blockDisplayList = mTextDisplayLists[blockIndex] =
11740+
getHardwareRenderer().createDisplayList("Text " + blockIndex);
11741+
} else {
11742+
if (blockIsInvalid) blockDisplayList.invalidate();
11743+
}
1173911744

11740-
DisplayList blockDisplayList = mTextDisplayLists[blockIndex];
11741-
if (blockDisplayList == null) {
11742-
blockDisplayList = mTextDisplayLists[blockIndex] =
11743-
getHardwareRenderer().createDisplayList("Text " + blockIndex);
11744-
} else {
11745-
if (blockIsInvalid) blockDisplayList.invalidate();
11746-
}
11747-
11748-
if (!blockDisplayList.isValid()) {
11749-
final HardwareCanvas hardwareCanvas = blockDisplayList.start();
11750-
try {
11751-
hardwareCanvas.setViewport(width, height);
11752-
// The dirty rect should always be null for a display list
11753-
hardwareCanvas.onPreDraw(null);
11754-
hardwareCanvas.translate(-mScrollX, -mScrollY);
11755-
layout.drawText(hardwareCanvas, endOfPreviousBlock + 1, blockEnd);
11756-
hardwareCanvas.translate(mScrollX, mScrollY);
11757-
} finally {
11758-
hardwareCanvas.onPostDraw();
11759-
blockDisplayList.end();
11760-
if (USE_DISPLAY_LIST_PROPERTIES) {
11761-
blockDisplayList.setLeftTopRightBottom(0, 0, width, height);
11745+
if (!blockDisplayList.isValid()) {
11746+
final HardwareCanvas hardwareCanvas = blockDisplayList.start();
11747+
try {
11748+
hardwareCanvas.setViewport(width, height);
11749+
// The dirty rect should always be null for a display list
11750+
hardwareCanvas.onPreDraw(null);
11751+
hardwareCanvas.translate(-mScrollX, -mScrollY);
11752+
layout.drawText(hardwareCanvas, endOfPreviousBlock + 1, blockEnd);
11753+
hardwareCanvas.translate(mScrollX, mScrollY);
11754+
} finally {
11755+
hardwareCanvas.onPostDraw();
11756+
blockDisplayList.end();
11757+
if (USE_DISPLAY_LIST_PROPERTIES) {
11758+
blockDisplayList.setLeftTopRightBottom(0, 0, width, height);
11759+
}
1176211760
}
1176311761
}
11764-
}
1176511762

11766-
((HardwareCanvas) canvas).drawDisplayList(blockDisplayList, width, height, null,
11767-
DisplayList.FLAG_CLIP_CHILDREN);
11768-
endOfPreviousBlock = blockEnd;
11763+
((HardwareCanvas) canvas).drawDisplayList(blockDisplayList, width, height, null,
11764+
DisplayList.FLAG_CLIP_CHILDREN);
11765+
endOfPreviousBlock = blockEnd;
11766+
}
11767+
canvas.translate(-mScrollX, -mScrollY);
11768+
} else {
11769+
// Fallback on the layout method (a BoringLayout is used when the text is empty)
11770+
layout.drawText(canvas, firstLine, lastLine);
1176911771
}
11770-
canvas.translate(-mScrollX, -mScrollY);
1177111772
}
1177211773

1177311774
private int getAvailableDisplayListIndex(int[] blockIndices, int numberOfBlocks,

0 commit comments

Comments
 (0)