From 09ee4282e5eedf5b44245e8b28b223339f87ddfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20L=C3=B6ffler?= Date: Sun, 26 Apr 2020 12:03:28 +0200 Subject: Fix invalid text layout data when a full layout run is interrupted When a QTextDocument is laid out, this is done in "chunks" to keep programs responsive. During the layout process, blocks are split into lines. When a full (re)layout is interrupted (e.g. because a QHighlighter changes some formats before the layout for all chunks is completed), later chunks are skipped. This results in invalid data (e.g., blocks not split into lines). This change ensures that full layout runs of the root frame are completed even after interruptions. Fixes: QTBUG-20354 Change-Id: I041c73a532a5abe74d577ca49810191b5594dca2 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextdocumentlayout.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/gui/text/qtextdocumentlayout.cpp') diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index 9d70873590..a2b3c8dc76 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -105,13 +105,14 @@ public: bool sizeDirty; bool layoutDirty; + bool fullLayoutCompleted; QVector > floats; }; QTextFrameData::QTextFrameData() : maximumWidth(QFIXED_MAX), - currentLayoutStruct(nullptr), sizeDirty(true), layoutDirty(true) + currentLayoutStruct(nullptr), sizeDirty(true), layoutDirty(true), fullLayoutCompleted(false) { } @@ -2943,7 +2944,7 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in QTextFrameData *fd = data(f); QFixed newContentsWidth; - bool fullLayout = false; + bool fullLayout = (f == document->rootFrame() && !fd->fullLayoutCompleted); { QTextFrameFormat fformat = f->frameFormat(); // set sizes of this frame from the format @@ -3397,6 +3398,7 @@ void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayout cp.contentsWidth = layoutStruct->contentsWidth; checkPoints.append(cp); checkPoints.reserve(checkPoints.size()); + fd->fullLayoutCompleted = true; } else { currentLazyLayoutPosition = checkPoints.constLast().positionInFrame; // ####### @@ -3808,6 +3810,7 @@ void QTextDocumentLayout::documentChanged(int from, int oldLength, int length) d->contentHasAlignment = false; d->currentLazyLayoutPosition = 0; d->checkPoints.clear(); + data(d->docPrivate->rootFrame())->fullLayoutCompleted = false; d->layoutStep(); } else { d->ensureLayoutedByPosition(from); -- cgit v1.2.3