Loading core/java/android/text/DynamicLayout.java +17 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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++; Loading Loading @@ -863,13 +865,19 @@ 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); } } mBlocksAlwaysNeedToBeRedrawn = set; } Loading core/tests/coretests/src/android/text/DynamicLayoutTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading
core/java/android/text/DynamicLayout.java +17 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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++; Loading Loading @@ -863,13 +865,19 @@ 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); } } mBlocksAlwaysNeedToBeRedrawn = set; } Loading
core/tests/coretests/src/android/text/DynamicLayoutTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading