summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/text/DynamicLayout.java52
-rw-r--r--core/java/android/widget/Editor.java43
-rw-r--r--core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java10
3 files changed, 55 insertions, 50 deletions
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index ff5a467..dc58ef2 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -117,7 +117,7 @@ public class DynamicLayout extends Layout
mObjects = new PackedObjectVector<Directions>(1);
- mBlockEnds = new int[] { 0 };
+ mBlockEndLines = new int[] { 0 };
mBlockIndices = new int[] { INVALID_BLOCK_INDEX };
mNumberOfBlocks = 1;
@@ -391,23 +391,23 @@ public class DynamicLayout extends Layout
int firstBlock = -1;
int lastBlock = -1;
for (int i = 0; i < mNumberOfBlocks; i++) {
- if (mBlockEnds[i] >= startLine) {
+ if (mBlockEndLines[i] >= startLine) {
firstBlock = i;
break;
}
}
for (int i = firstBlock; i < mNumberOfBlocks; i++) {
- if (mBlockEnds[i] >= endLine) {
+ if (mBlockEndLines[i] >= endLine) {
lastBlock = i;
break;
}
}
- final int lastBlockEndLine = mBlockEnds[lastBlock];
+ final int lastBlockEndLine = mBlockEndLines[lastBlock];
boolean createBlockBefore = startLine > (firstBlock == 0 ? 0 :
- mBlockEnds[firstBlock - 1] + 1);
+ mBlockEndLines[firstBlock - 1] + 1);
boolean createBlock = newLineCount > 0;
- boolean createBlockAfter = endLine < mBlockEnds[lastBlock];
+ boolean createBlockAfter = endLine < mBlockEndLines[lastBlock];
int numAddedBlocks = 0;
if (createBlockBefore) numAddedBlocks++;
@@ -419,27 +419,27 @@ public class DynamicLayout extends Layout
if (newNumberOfBlocks == 0) {
// Even when text is empty, there is actually one line and hence one block
- mBlockEnds[0] = 0;
+ mBlockEndLines[0] = 0;
mBlockIndices[0] = INVALID_BLOCK_INDEX;
mNumberOfBlocks = 1;
return;
}
- if (newNumberOfBlocks > mBlockEnds.length) {
+ if (newNumberOfBlocks > mBlockEndLines.length) {
final int newSize = ArrayUtils.idealIntArraySize(newNumberOfBlocks);
- int[] blockEnds = new int[newSize];
+ int[] blockEndLines = new int[newSize];
int[] blockIndices = new int[newSize];
- System.arraycopy(mBlockEnds, 0, blockEnds, 0, firstBlock);
+ System.arraycopy(mBlockEndLines, 0, blockEndLines, 0, firstBlock);
System.arraycopy(mBlockIndices, 0, blockIndices, 0, firstBlock);
- System.arraycopy(mBlockEnds, lastBlock + 1,
- blockEnds, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
+ System.arraycopy(mBlockEndLines, lastBlock + 1,
+ blockEndLines, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
System.arraycopy(mBlockIndices, lastBlock + 1,
blockIndices, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
- mBlockEnds = blockEnds;
+ mBlockEndLines = blockEndLines;
mBlockIndices = blockIndices;
} else {
- System.arraycopy(mBlockEnds, lastBlock + 1,
- mBlockEnds, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
+ System.arraycopy(mBlockEndLines, lastBlock + 1,
+ mBlockEndLines, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
System.arraycopy(mBlockIndices, lastBlock + 1,
mBlockIndices, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
}
@@ -447,24 +447,24 @@ public class DynamicLayout extends Layout
mNumberOfBlocks = newNumberOfBlocks;
final int deltaLines = newLineCount - (endLine - startLine + 1);
for (int i = firstBlock + numAddedBlocks; i < mNumberOfBlocks; i++) {
- mBlockEnds[i] += deltaLines;
+ mBlockEndLines[i] += deltaLines;
}
int blockIndex = firstBlock;
if (createBlockBefore) {
- mBlockEnds[blockIndex] = startLine - 1;
+ mBlockEndLines[blockIndex] = startLine - 1;
mBlockIndices[blockIndex] = INVALID_BLOCK_INDEX;
blockIndex++;
}
if (createBlock) {
- mBlockEnds[blockIndex] = startLine + newLineCount - 1;
+ mBlockEndLines[blockIndex] = startLine + newLineCount - 1;
mBlockIndices[blockIndex] = INVALID_BLOCK_INDEX;
blockIndex++;
}
if (createBlockAfter) {
- mBlockEnds[blockIndex] = lastBlockEndLine + deltaLines;
+ mBlockEndLines[blockIndex] = lastBlockEndLine + deltaLines;
mBlockIndices[blockIndex] = INVALID_BLOCK_INDEX;
}
}
@@ -473,10 +473,10 @@ public class DynamicLayout extends Layout
* This package private method is used for test purposes only
* @hide
*/
- void setBlocksDataForTest(int[] blockEnds, int[] blockIndices, int numberOfBlocks) {
- mBlockEnds = new int[blockEnds.length];
+ void setBlocksDataForTest(int[] blockEndLines, int[] blockIndices, int numberOfBlocks) {
+ mBlockEndLines = new int[blockEndLines.length];
mBlockIndices = new int[blockIndices.length];
- System.arraycopy(blockEnds, 0, mBlockEnds, 0, blockEnds.length);
+ System.arraycopy(blockEndLines, 0, mBlockEndLines, 0, blockEndLines.length);
System.arraycopy(blockIndices, 0, mBlockIndices, 0, blockIndices.length);
mNumberOfBlocks = numberOfBlocks;
}
@@ -484,8 +484,8 @@ public class DynamicLayout extends Layout
/**
* @hide
*/
- public int[] getBlockEnds() {
- return mBlockEnds;
+ public int[] getBlockEndLines() {
+ return mBlockEndLines;
}
/**
@@ -633,8 +633,8 @@ public class DynamicLayout extends Layout
* @hide
*/
public static final int INVALID_BLOCK_INDEX = -1;
- // Stores the line numbers of the last line of each block
- private int[] mBlockEnds;
+ // Stores the line numbers of the last line of each block (inclusive)
+ private int[] mBlockEndLines;
// The indices of this block's display list in TextView's internal display list array or
// INVALID_BLOCK_INDEX if this block has been invalidated during an edition
private int[] mBlockIndices;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 040a385..900f0d3 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1241,24 +1241,21 @@ public class Editor {
}
DynamicLayout dynamicLayout = (DynamicLayout) layout;
- int[] blockEnds = dynamicLayout.getBlockEnds();
+ int[] blockEndLines = dynamicLayout.getBlockEndLines();
int[] blockIndices = dynamicLayout.getBlockIndices();
final int numberOfBlocks = dynamicLayout.getNumberOfBlocks();
- final int mScrollX = mTextView.getScrollX();
- final int mScrollY = mTextView.getScrollY();
- canvas.translate(mScrollX, mScrollY);
int endOfPreviousBlock = -1;
int searchStartIndex = 0;
for (int i = 0; i < numberOfBlocks; i++) {
- int blockEnd = blockEnds[i];
+ int blockEndLine = blockEndLines[i];
int blockIndex = blockIndices[i];
final boolean blockIsInvalid = blockIndex == DynamicLayout.INVALID_BLOCK_INDEX;
if (blockIsInvalid) {
blockIndex = getAvailableDisplayListIndex(blockIndices, numberOfBlocks,
searchStartIndex);
- // Dynamic layout internal block indices structure is updated from Editor
+ // Note how dynamic layout's internal block indices get updated from Editor
blockIndices[i] = blockIndex;
searchStartIndex = blockIndex + 1;
}
@@ -1272,28 +1269,38 @@ public class Editor {
}
if (!blockDisplayList.isValid()) {
+ final int blockBeginLine = endOfPreviousBlock + 1;
+ final int top = layout.getLineTop(blockBeginLine);
+ final int bottom = layout.getLineBottom(blockEndLine);
+
final HardwareCanvas hardwareCanvas = blockDisplayList.start();
try {
- hardwareCanvas.setViewport(width, height);
+ hardwareCanvas.setViewport(width, bottom - top);
// The dirty rect should always be null for a display list
hardwareCanvas.onPreDraw(null);
- hardwareCanvas.translate(-mScrollX, -mScrollY);
- layout.drawText(hardwareCanvas, endOfPreviousBlock + 1, blockEnd);
- hardwareCanvas.translate(mScrollX, mScrollY);
+ // drawText is always relative to TextView's origin, this translation brings
+ // this range of text back to the top of the viewport
+ hardwareCanvas.translate(0, -top);
+ layout.drawText(hardwareCanvas, blockBeginLine, blockEndLine);
+ hardwareCanvas.translate(0, top);
} finally {
hardwareCanvas.onPostDraw();
blockDisplayList.end();
if (View.USE_DISPLAY_LIST_PROPERTIES) {
- blockDisplayList.setLeftTopRightBottom(0, 0, width, height);
+ blockDisplayList.setLeftTopRightBottom(0, top, width, bottom);
+ // Same as drawDisplayList below, handled by our TextView's parent
+ blockDisplayList.setClipChildren(false);
}
}
}
+ // TODO When View.USE_DISPLAY_LIST_PROPERTIES is the only code path, the
+ // width and height parameters should be removed and the bounds set above in
+ // setLeftTopRightBottom should be used instead for quick rejection.
((HardwareCanvas) canvas).drawDisplayList(blockDisplayList, width, height, null,
- DisplayList.FLAG_CLIP_CHILDREN);
- endOfPreviousBlock = blockEnd;
+ 0 /* no child clipping, our TextView parent enforces it */);
+ endOfPreviousBlock = blockEndLine;
}
- canvas.translate(-mScrollX, -mScrollY);
} else {
// Boring layout is used for empty and hint text
layout.drawText(canvas, firstLine, lastLine);
@@ -1572,11 +1579,9 @@ public class Editor {
}
void onScrollChanged() {
- if (mPositionListener != null) {
- mPositionListener.onScrollChanged();
- }
- // Internal scroll affects the clip boundaries
- invalidateTextDisplayList();
+ if (mPositionListener != null) {
+ mPositionListener.onScrollChanged();
+ }
}
/**
diff --git a/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java b/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
index 73da84f..2e42e5a 100644
--- a/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
+++ b/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
@@ -45,18 +45,18 @@ public class DynamicLayoutBlocksTest extends TestCase {
public void printBlocks(String message) {
System.out.print(message);
for (int i = 0; i < dl.getNumberOfBlocks(); i++) {
- System.out.print(" " + Integer.toString(dl.getBlockEnds()[i]));
+ System.out.print(" " + Integer.toString(dl.getBlockEndLines()[i]));
}
System.out.println();
}
public void checkInvariants() {
assertTrue(dl.getNumberOfBlocks() > 0);
- assertTrue(dl.getNumberOfBlocks() <= dl.getBlockEnds().length);
- assertEquals(dl.getBlockEnds().length, dl.getBlockIndices().length);
+ assertTrue(dl.getNumberOfBlocks() <= dl.getBlockEndLines().length);
+ assertEquals(dl.getBlockEndLines().length, dl.getBlockIndices().length);
for (int i = 1; i < dl.getNumberOfBlocks(); i++) {
- assertTrue(dl.getBlockEnds()[i] > dl.getBlockEnds()[i-1]);
+ assertTrue(dl.getBlockEndLines()[i] > dl.getBlockEndLines()[i-1]);
}
}
@@ -78,7 +78,7 @@ public class DynamicLayoutBlocksTest extends TestCase {
}
for (int i = 0; i < dl.getNumberOfBlocks(); i++) {
- assertEquals(ends[i], dl.getBlockEnds()[i]);
+ assertEquals(ends[i], dl.getBlockEndLines()[i]);
assertEquals(indices[i], dl.getBlockIndices()[i]);
}
}