summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilles Debunne <debunne@google.com>2012-04-20 15:10:47 -0700
committerGilles Debunne <debunne@google.com>2012-04-20 15:45:39 -0700
commitebc86af1dc186c77f723c8970951e8ff00b4866b (patch)
tree876bcafacd9e951c4b18b1bfcda8ed2374480906
parent70c8723e63e2c58115c356bd4e9525b823b7bf28 (diff)
downloadframeworks_base-ebc86af1dc186c77f723c8970951e8ff00b4866b.zip
frameworks_base-ebc86af1dc186c77f723c8970951e8ff00b4866b.tar.gz
frameworks_base-ebc86af1dc186c77f723c8970951e8ff00b4866b.tar.bz2
Visible spans changes only invalidate the affected text sub display lists
When a span with a visible influence on the text is modified, we only need to invalidate the text sub display lists that overlap this span. This is especially useful when typing and the composing span (an underline span) gets updated after each key stroke. Change-Id: Ib2af3219c41eb79ec5d0a2eee317aca8c4efdef9
-rw-r--r--core/java/android/widget/Editor.java32
-rw-r--r--core/java/android/widget/TextView.java5
2 files changed, 36 insertions, 1 deletions
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 900f0d3..8d199d7 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1339,6 +1339,38 @@ public class Editor {
if (translate) canvas.translate(0, -cursorOffsetVertical);
}
+ /**
+ * Invalidates all the sub-display lists that overlap the specified character range
+ */
+ void invalidateTextDisplayList(Layout layout, int start, int end) {
+ if (mTextDisplayLists != null && layout instanceof DynamicLayout) {
+ final int firstLine = layout.getLineForOffset(start);
+ final int lastLine = layout.getLineForOffset(end);
+
+ DynamicLayout dynamicLayout = (DynamicLayout) layout;
+ int[] blockEndLines = dynamicLayout.getBlockEndLines();
+ int[] blockIndices = dynamicLayout.getBlockIndices();
+ final int numberOfBlocks = dynamicLayout.getNumberOfBlocks();
+
+ int i = 0;
+ // Skip the blocks before firstLine
+ while (i < numberOfBlocks) {
+ if (blockEndLines[i] >= firstLine) break;
+ i++;
+ }
+
+ // Invalidate all subsequent blocks until lastLine is passed
+ while (i < numberOfBlocks) {
+ final int blockIndex = blockIndices[i];
+ if (blockIndex != DynamicLayout.INVALID_BLOCK_INDEX) {
+ mTextDisplayLists[blockIndex].invalidate();
+ }
+ if (blockEndLines[i] >= lastLine) break;
+ i++;
+ }
+ }
+ }
+
void invalidateTextDisplayList() {
if (mTextDisplayLists != null) {
for (int i = 0; i < mTextDisplayLists.length; i++) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 37d9db7..0e7fe7f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6860,7 +6860,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} else {
ims.mContentChanged = true;
}
- if (mEditor != null) getEditor().invalidateTextDisplayList();
+ if (mEditor != null) {
+ if (oldStart >= 0) getEditor().invalidateTextDisplayList(mLayout, oldStart, oldEnd);
+ if (newStart >= 0) getEditor().invalidateTextDisplayList(mLayout, newStart, newEnd);
+ }
}
if (MetaKeyKeyListener.isMetaTracker(buf, what)) {