Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2105f9e7 authored by Siyamed Sinir's avatar Siyamed Sinir Committed by Android (Google) Code Review
Browse files

Merge "Fix DynamicLayout block index calculation after edit"

parents d93cecec 50b585e2
Loading
Loading
Loading
Loading
+17 −9
Original line number Diff line number Diff line
@@ -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,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;
        }

+22 −0
Original line number Diff line number Diff line
@@ -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.