use of android.text.DynamicLayout in project UltimateAndroid by cymcsg.
the class TextDrawer method draw.
public void draw(Canvas canvas) {
if (shouldDrawText()) {
float[] textPosition = getBestTextPosition();
if (!TextUtils.isEmpty(mTitle)) {
canvas.save();
if (hasRecalculated) {
mDynamicTitleLayout = new DynamicLayout(mTitle, titlePaint, (int) textPosition[2], Layout.Alignment.ALIGN_NORMAL, 1.0f, 1.0f, true);
}
if (mDynamicTitleLayout != null) {
canvas.translate(textPosition[0], textPosition[1]);
mDynamicTitleLayout.draw(canvas);
canvas.restore();
}
}
if (!TextUtils.isEmpty(mDetails)) {
canvas.save();
if (hasRecalculated) {
mDynamicDetailLayout = new DynamicLayout(mDetails, textPaint, (int) textPosition[2], Layout.Alignment.ALIGN_NORMAL, 1.2f, 1.0f, true);
}
float offsetForTitle = mDynamicTitleLayout != null ? mDynamicTitleLayout.getHeight() : 0;
if (mDynamicDetailLayout != null) {
canvas.translate(textPosition[0], textPosition[1] + offsetForTitle);
mDynamicDetailLayout.draw(canvas);
canvas.restore();
}
}
}
hasRecalculated = false;
}
use of android.text.DynamicLayout in project android_frameworks_base by ParanoidAndroid.
the class Editor method invalidateTextDisplayList.
/**
* 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].clear();
}
if (blockEndLines[i] >= lastLine)
break;
i++;
}
}
}
use of android.text.DynamicLayout 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);
}
}
use of android.text.DynamicLayout in project platform_frameworks_base by android.
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 (mTextRenderNodes == null) {
mTextRenderNodes = ArrayUtils.emptyArray(TextRenderNode.class);
}
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;
if (mTextRenderNodes[blockIndex] != null) {
mTextRenderNodes[blockIndex].isDirty = true;
}
searchStartIndex = blockIndex + 1;
}
if (mTextRenderNodes[blockIndex] == null) {
mTextRenderNodes[blockIndex] = new TextRenderNode("Text " + blockIndex);
}
final boolean blockDisplayListIsInvalid = mTextRenderNodes[blockIndex].needsRecord();
RenderNode blockDisplayList = mTextRenderNodes[blockIndex].renderNode;
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 DisplayListCanvas displayListCanvas = 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
displayListCanvas.translate(-left, -top);
layout.drawText(displayListCanvas, blockBeginLine, blockEndLine);
mTextRenderNodes[blockIndex].isDirty = false;
// No need to untranslate, previous context is popped after
// drawDisplayList
} finally {
blockDisplayList.end(displayListCanvas);
// 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);
}
((DisplayListCanvas) canvas).drawRenderNode(blockDisplayList);
endOfPreviousBlock = blockEndLine;
}
dynamicLayout.setIndexFirstChangedBlock(numberOfBlocks);
} else {
// Boring layout is used for empty and hint text
layout.drawText(canvas, firstLine, lastLine);
}
}
use of android.text.DynamicLayout in project ShowcaseView by amlcurran.
the class TextDrawer method draw.
public void draw(Canvas canvas) {
if (shouldDrawText()) {
float[] textPosition = getBestTextPosition();
int width = Math.max(0, (int) mBestTextPosition[INDEX_TEXT_WIDTH]);
if (!TextUtils.isEmpty(titleString)) {
canvas.save();
if (hasRecalculated) {
titleLayout = new DynamicLayout(titleString, titlePaint, width, titleAlignment, 1.0f, 1.0f, true);
}
if (titleLayout != null) {
canvas.translate(textPosition[INDEX_TEXT_START_X], textPosition[INDEX_TEXT_START_Y]);
titleLayout.draw(canvas);
canvas.restore();
}
}
if (!TextUtils.isEmpty(textString)) {
canvas.save();
if (hasRecalculated) {
textLayout = new DynamicLayout(textString, textPaint, width, textAlignment, 1.2f, 1.0f, true);
}
float offsetForTitle = titleLayout != null ? titleLayout.getHeight() : 0;
if (textLayout != null) {
canvas.translate(textPosition[INDEX_TEXT_START_X], textPosition[INDEX_TEXT_START_Y] + offsetForTitle);
textLayout.draw(canvas);
canvas.restore();
}
}
}
hasRecalculated = false;
}
Aggregations