Search in sources :

Example 1 with DisplayList

use of android.view.DisplayList in project android_frameworks_base by ParanoidAndroid.

the class Editor method drawHardwareAccelerated.

private void drawHardwareAccelerated(Canvas canvas, Layout layout, Path highlight, Paint highlightPaint, int cursorOffsetVertical) {
    final long lineRange = layout.getLineRangeForDraw(canvas);
    int firstLine = TextUtils.unpackRangeStartFromLong(lineRange);
    int lastLine = TextUtils.unpackRangeEndFromLong(lineRange);
    if (lastLine < 0)
        return;
    layout.drawBackground(canvas, highlight, highlightPaint, cursorOffsetVertical, firstLine, lastLine);
    if (layout instanceof DynamicLayout) {
        if (mTextDisplayLists == null) {
            mTextDisplayLists = new DisplayList[ArrayUtils.idealObjectArraySize(0)];
        }
        DynamicLayout dynamicLayout = (DynamicLayout) layout;
        int[] blockEndLines = dynamicLayout.getBlockEndLines();
        int[] blockIndices = dynamicLayout.getBlockIndices();
        final int numberOfBlocks = dynamicLayout.getNumberOfBlocks();
        final int indexFirstChangedBlock = dynamicLayout.getIndexFirstChangedBlock();
        int endOfPreviousBlock = -1;
        int searchStartIndex = 0;
        for (int i = 0; i < numberOfBlocks; i++) {
            int blockEndLine = blockEndLines[i];
            int blockIndex = blockIndices[i];
            final boolean blockIsInvalid = blockIndex == DynamicLayout.INVALID_BLOCK_INDEX;
            if (blockIsInvalid) {
                blockIndex = getAvailableDisplayListIndex(blockIndices, numberOfBlocks, searchStartIndex);
                // Note how dynamic layout's internal block indices get updated from Editor
                blockIndices[i] = blockIndex;
                searchStartIndex = blockIndex + 1;
            }
            DisplayList blockDisplayList = mTextDisplayLists[blockIndex];
            if (blockDisplayList == null) {
                blockDisplayList = mTextDisplayLists[blockIndex] = mTextView.getHardwareRenderer().createDisplayList("Text " + blockIndex);
            } else {
                if (blockIsInvalid)
                    blockDisplayList.clear();
            }
            final boolean blockDisplayListIsInvalid = !blockDisplayList.isValid();
            if (i >= indexFirstChangedBlock || blockDisplayListIsInvalid) {
                final int blockBeginLine = endOfPreviousBlock + 1;
                final int top = layout.getLineTop(blockBeginLine);
                final int bottom = layout.getLineBottom(blockEndLine);
                int left = 0;
                int right = mTextView.getWidth();
                if (mTextView.getHorizontallyScrolling()) {
                    float min = Float.MAX_VALUE;
                    float max = Float.MIN_VALUE;
                    for (int line = blockBeginLine; line <= blockEndLine; line++) {
                        min = Math.min(min, layout.getLineLeft(line));
                        max = Math.max(max, layout.getLineRight(line));
                    }
                    left = (int) min;
                    right = (int) (max + 0.5f);
                }
                // Rebuild display list if it is invalid
                if (blockDisplayListIsInvalid) {
                    final HardwareCanvas hardwareCanvas = blockDisplayList.start(right - left, bottom - top);
                    try {
                        // drawText is always relative to TextView's origin, this translation
                        // brings this range of text back to the top left corner of the viewport
                        hardwareCanvas.translate(-left, -top);
                        layout.drawText(hardwareCanvas, blockBeginLine, blockEndLine);
                    // No need to untranslate, previous context is popped after
                    // drawDisplayList
                    } finally {
                        blockDisplayList.end();
                        // Same as drawDisplayList below, handled by our TextView's parent
                        blockDisplayList.setClipToBounds(false);
                    }
                }
                // Valid disply list whose index is >= indexFirstChangedBlock
                // only needs to update its drawing location.
                blockDisplayList.setLeftTopRightBottom(left, top, right, bottom);
            }
            ((HardwareCanvas) canvas).drawDisplayList(blockDisplayList, null, 0);
            endOfPreviousBlock = blockEndLine;
        }
        dynamicLayout.setIndexFirstChangedBlock(numberOfBlocks);
    } else {
        // Boring layout is used for empty and hint text
        layout.drawText(canvas, firstLine, lastLine);
    }
}
Also used : DisplayList(android.view.DisplayList) HardwareCanvas(android.view.HardwareCanvas) DynamicLayout(android.text.DynamicLayout) Paint(android.graphics.Paint)

Example 2 with DisplayList

use of android.view.DisplayList in project android_frameworks_base by ParanoidAndroid.

the class Editor method getAvailableDisplayListIndex.

private int getAvailableDisplayListIndex(int[] blockIndices, int numberOfBlocks, int searchStartIndex) {
    int length = mTextDisplayLists.length;
    for (int i = searchStartIndex; i < length; i++) {
        boolean blockIndexFound = false;
        for (int j = 0; j < numberOfBlocks; j++) {
            if (blockIndices[j] == i) {
                blockIndexFound = true;
                break;
            }
        }
        if (blockIndexFound)
            continue;
        return i;
    }
    // No available index found, the pool has to grow
    int newSize = ArrayUtils.idealIntArraySize(length + 1);
    DisplayList[] displayLists = new DisplayList[newSize];
    System.arraycopy(mTextDisplayLists, 0, displayLists, 0, length);
    mTextDisplayLists = displayLists;
    return length;
}
Also used : DisplayList(android.view.DisplayList) Paint(android.graphics.Paint)

Aggregations

Paint (android.graphics.Paint)2 DisplayList (android.view.DisplayList)2 DynamicLayout (android.text.DynamicLayout)1 HardwareCanvas (android.view.HardwareCanvas)1