diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-12-13 08:14:26 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-01-06 08:43:53 +0000 |
commit | 18ad8a7f17a6f49c0a93c0046c05578820732ccb (patch) | |
tree | c244c721b6a4bb75793f6535392a4b8e046ada3b /src/quick/items/qquicktextedit.cpp | |
parent | cb28c76c40a9492d1a00baf61f71ad52c834ac25 (diff) |
TextEdit: deal with scrolling backwards in rich text
A bug was introduced in 9db23e0e04906cf9ea33e23fa41f34955e5e6fe0 :
when scrolling backwards in some kinds of rich text, updatePaintNode()
failed to re-populate the nodes that had been scrolled out above the
viewport. That was because those nodes had been removed from
textNodeMap, and then firstDirtyPos was set from the first node in
textNodeMap. For some reason this didn't happen with the markdown
document that I was testing (maybe because it had a table and an image
near the beginning), but showed up when viewing an html document similar
to the one we ship with the rich text example. So now we iterate
backwards from textNodeMap.begin() when this happens, to find all nodes
in the current frame that intersect the viewport as rendered.
In the autotest we now use font.pixelSize in an attempt to make
the rendered text ranges more consistent across platforms in CI;
and we need to wait for the rendering to be redone after scrolling.
Change-Id: I70ef54c8d8facc439b9a6f8b5cb8e3a4a1c37e16
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit cd083920b3b4f3a1ed7f2297058cf0d110d7cf10)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/quick/items/qquicktextedit.cpp')
-rw-r--r-- | src/quick/items/qquicktextedit.cpp | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 9ef041bbb1..d0614bbeff 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -2087,7 +2087,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * QQuickTextNodeEngine engine; QQuickTextNodeEngine frameDecorationsEngine; - if (!oldNode || nodeIterator < d->textNodeMap.end()) { + if (!oldNode || nodeIterator < d->textNodeMap.end() || d->textNodeMap.isEmpty()) { if (!oldNode) rootNode = new RootNode; @@ -2184,9 +2184,10 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * QTextFrame::iterator it = textFrame->begin(); while (!it.atEnd()) { QTextBlock block = it.currentBlock(); - ++it; - if (block.position() < firstDirtyPos) + if (block.position() < firstDirtyPos) { + ++it; continue; + } if (!engine.hasContents()) nodeOffset = d->document->documentLayout()->blockBoundingRect(block).topLeft(); @@ -2199,6 +2200,21 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * inView = coveredRegion.bottom() > viewport.top(); } if (d->firstBlockInViewport < 0 && inView) { + // During backward scrolling, we need to iterate backwards from textNodeMap.begin() to fill the top of the viewport. + if (coveredRegion.top() > viewport.top() + 1) { + qCDebug(lcVP) << "checking backwards from block" << block.blockNumber() << "@" << nodeOffset.y() << coveredRegion; + while (it != textFrame->begin() && it.currentBlock().layout() && + it.currentBlock().layout()->boundingRect().top() + nodeOffset.y() > viewport.top()) + --it; + if (!it.currentBlock().layout()) + ++it; + if (Q_LIKELY(it.currentBlock().layout())) { + block = it.currentBlock(); + coveredRegion = block.layout()->boundingRect().adjusted(nodeOffset.x(), nodeOffset.y(), nodeOffset.x(), nodeOffset.y()); + } else { + qCWarning(lcVP) << "failed to find a text block with layout during back-scrolling"; + } + } qCDebug(lcVP) << "first block in viewport" << block.blockNumber() << "@" << nodeOffset.y() << coveredRegion; d->firstBlockInViewport = block.blockNumber(); if (block.layout()) @@ -2240,6 +2256,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * resetEngine(&engine, d->color, d->selectedTextColor, d->selectionColor); nodeStart = block.next().position(); } + ++it; } } if (Q_LIKELY(node && !node->parent())) |