Merge "Fix DynamicLayout block index calculation after edit"
This commit is contained in:
committed by
Android (Google) Code Review
commit
2105f9e774
@@ -492,7 +492,9 @@ public class DynamicLayout extends Layout
|
||||
}
|
||||
}
|
||||
|
||||
private void reflow(CharSequence s, int where, int before, int after) {
|
||||
/** @hide */
|
||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
||||
public void reflow(CharSequence s, int where, int before, int after) {
|
||||
if (s != mBase)
|
||||
return;
|
||||
|
||||
@@ -805,8 +807,8 @@ public class DynamicLayout extends Layout
|
||||
return;
|
||||
}
|
||||
|
||||
int firstBlock = -1;
|
||||
int lastBlock = -1;
|
||||
/*final*/ int firstBlock = -1;
|
||||
/*final*/ int lastBlock = -1;
|
||||
for (int i = 0; i < mNumberOfBlocks; i++) {
|
||||
if (mBlockEndLines[i] >= startLine) {
|
||||
firstBlock = i;
|
||||
@@ -821,10 +823,10 @@ public class DynamicLayout extends Layout
|
||||
}
|
||||
final int lastBlockEndLine = mBlockEndLines[lastBlock];
|
||||
|
||||
boolean createBlockBefore = startLine > (firstBlock == 0 ? 0 :
|
||||
final boolean createBlockBefore = startLine > (firstBlock == 0 ? 0 :
|
||||
mBlockEndLines[firstBlock - 1] + 1);
|
||||
boolean createBlock = newLineCount > 0;
|
||||
boolean createBlockAfter = endLine < mBlockEndLines[lastBlock];
|
||||
final boolean createBlock = newLineCount > 0;
|
||||
final boolean createBlockAfter = endLine < mBlockEndLines[lastBlock];
|
||||
|
||||
int numAddedBlocks = 0;
|
||||
if (createBlockBefore) numAddedBlocks++;
|
||||
@@ -863,12 +865,18 @@ public class DynamicLayout extends Layout
|
||||
|
||||
if (numAddedBlocks + numRemovedBlocks != 0 && mBlocksAlwaysNeedToBeRedrawn != null) {
|
||||
final ArraySet<Integer> set = new ArraySet<>();
|
||||
final int changedBlockCount = numAddedBlocks - numRemovedBlocks;
|
||||
for (int i = 0; i < mBlocksAlwaysNeedToBeRedrawn.size(); i++) {
|
||||
Integer block = mBlocksAlwaysNeedToBeRedrawn.valueAt(i);
|
||||
if (block > firstBlock) {
|
||||
block += numAddedBlocks - numRemovedBlocks;
|
||||
if (block < firstBlock) {
|
||||
// block index is before firstBlock add it since it did not change
|
||||
set.add(block);
|
||||
}
|
||||
if (block > lastBlock) {
|
||||
// block index is after lastBlock, the index reduced to += changedBlockCount
|
||||
block += changedBlockCount;
|
||||
set.add(block);
|
||||
}
|
||||
set.add(block);
|
||||
}
|
||||
mBlocksAlwaysNeedToBeRedrawn = set;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.platform.test.annotations.Presubmit;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.text.style.ReplacementSpan;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -189,6 +190,27 @@ public class DynamicLayoutTest {
|
||||
layout.getLineExtra(100);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReflow_afterSpannableEdit() {
|
||||
final String text = "a\nb:\uD83C\uDF1A c \n\uD83C\uDF1A";
|
||||
final int length = text.length();
|
||||
final SpannableStringBuilder spannable = new SpannableStringBuilder(text);
|
||||
spannable.setSpan(new MockReplacementSpan(), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
spannable.setSpan(new MockReplacementSpan(), 10, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
final DynamicLayout layout = new DynamicLayout(spannable, new TextPaint(), WIDTH,
|
||||
ALIGN_NORMAL, 1.0f /*spacingMultiplier*/, 0f /*spacingAdd*/, false /*includepad*/);
|
||||
|
||||
spannable.delete(8, 9);
|
||||
spannable.replace(7, 8, "ch");
|
||||
|
||||
layout.reflow(spannable, 0, length, length);
|
||||
final ArraySet<Integer> blocks = layout.getBlocksAlwaysNeedToBeRedrawn();
|
||||
for (Integer value : blocks) {
|
||||
assertTrue("Block index should not be negative", value >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFallbackLineSpacing() {
|
||||
// All glyphs in the fonts are 1em wide.
|
||||
|
||||
Reference in New Issue
Block a user