VTextDocumentLayout: bug fix in relayout()

This commit is contained in:
Le Tan 2018-09-26 19:24:18 +08:00
parent 12b819250d
commit bc711e755c

View File

@ -557,7 +557,7 @@ void VTextDocumentLayout::updateOffsetBefore(const QTextBlock &p_block)
blk = blk.next(); blk = blk.next();
while (blk.isValid() && blk.blockNumber() <= blockNum) { while (blk.isValid() && blk.blockNumber() <= blockNum) {
BlockLayoutInfo *ninfo = VTextBlockData::layoutInfo(blk); BlockLayoutInfo *ninfo = VTextBlockData::layoutInfo(blk);
Q_ASSERT(!ninfo->isNull()); V_ASSERT(!ninfo->isNull());
ninfo->m_offset = offset; ninfo->m_offset = offset;
offset = ninfo->bottom(); offset = ninfo->bottom();
blk = blk.next(); blk = blk.next();
@ -570,6 +570,8 @@ void VTextDocumentLayout::updateOffsetBefore(const QTextBlock &p_block)
} }
} }
// NOTICE: It will skip non-layouted or offset-non-changed blocks.
// So if you relayout separated blocks, you need to updateOffsetAfter() for each of them.
void VTextDocumentLayout::updateOffsetAfter(const QTextBlock &p_block) void VTextDocumentLayout::updateOffsetAfter(const QTextBlock &p_block)
{ {
BlockLayoutInfo *info = VTextBlockData::layoutInfo(p_block); BlockLayoutInfo *info = VTextBlockData::layoutInfo(p_block);
@ -975,28 +977,31 @@ void VTextDocumentLayout::relayout(const OrderedIntSet &p_blocks)
QTextDocument *doc = document(); QTextDocument *doc = document();
// Need to relayout and update blocks in ascending order. // Need to relayout and update blocks in ascending order.
QTextBlock startBlock; QVector<QTextBlock> blocks;
blocks.reserve(p_blocks.size());
for (auto bn = p_blocks.keyBegin(); bn != p_blocks.keyEnd(); ++bn) { for (auto bn = p_blocks.keyBegin(); bn != p_blocks.keyEnd(); ++bn) {
QTextBlock block = doc->findBlockByNumber(*bn); QTextBlock block = doc->findBlockByNumber(*bn);
if (block.isValid()) { if (block.isValid()) {
if (!startBlock.isValid()) { blocks.append(block);
startBlock = block;
}
clearBlockLayout(block); clearBlockLayout(block);
layoutBlock(block); layoutBlock(block);
} }
} }
if (!startBlock.isValid()) { if (blocks.isEmpty()) {
return; return;
} }
updateOffset(startBlock); // Need to update offset for each of these discontinuous blocks, because
// the offset of the non-touched blocks may be the same but there are still
// touched blocks after them.
for (auto & blk : blocks) {
updateOffset(blk);
}
updateDocumentSize(); updateDocumentSize();
qreal offset = VTextBlockData::layoutInfo(startBlock)->m_offset; qreal offset = VTextBlockData::layoutInfo(blocks.first())->m_offset;
emit update(QRectF(0., offset, 1000000000., 1000000000.)); emit update(QRectF(0., offset, 1000000000., 1000000000.));
} }