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 <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
parent
844967d297
commit
09ee4282e5
@ -105,13 +105,14 @@ public:
|
|||||||
|
|
||||||
bool sizeDirty;
|
bool sizeDirty;
|
||||||
bool layoutDirty;
|
bool layoutDirty;
|
||||||
|
bool fullLayoutCompleted;
|
||||||
|
|
||||||
QVector<QPointer<QTextFrame> > floats;
|
QVector<QPointer<QTextFrame> > floats;
|
||||||
};
|
};
|
||||||
|
|
||||||
QTextFrameData::QTextFrameData()
|
QTextFrameData::QTextFrameData()
|
||||||
: maximumWidth(QFIXED_MAX),
|
: 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);
|
QTextFrameData *fd = data(f);
|
||||||
QFixed newContentsWidth;
|
QFixed newContentsWidth;
|
||||||
|
|
||||||
bool fullLayout = false;
|
bool fullLayout = (f == document->rootFrame() && !fd->fullLayoutCompleted);
|
||||||
{
|
{
|
||||||
QTextFrameFormat fformat = f->frameFormat();
|
QTextFrameFormat fformat = f->frameFormat();
|
||||||
// set sizes of this frame from the format
|
// set sizes of this frame from the format
|
||||||
@ -3397,6 +3398,7 @@ void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayout
|
|||||||
cp.contentsWidth = layoutStruct->contentsWidth;
|
cp.contentsWidth = layoutStruct->contentsWidth;
|
||||||
checkPoints.append(cp);
|
checkPoints.append(cp);
|
||||||
checkPoints.reserve(checkPoints.size());
|
checkPoints.reserve(checkPoints.size());
|
||||||
|
fd->fullLayoutCompleted = true;
|
||||||
} else {
|
} else {
|
||||||
currentLazyLayoutPosition = checkPoints.constLast().positionInFrame;
|
currentLazyLayoutPosition = checkPoints.constLast().positionInFrame;
|
||||||
// #######
|
// #######
|
||||||
@ -3808,6 +3810,7 @@ void QTextDocumentLayout::documentChanged(int from, int oldLength, int length)
|
|||||||
d->contentHasAlignment = false;
|
d->contentHasAlignment = false;
|
||||||
d->currentLazyLayoutPosition = 0;
|
d->currentLazyLayoutPosition = 0;
|
||||||
d->checkPoints.clear();
|
d->checkPoints.clear();
|
||||||
|
data(d->docPrivate->rootFrame())->fullLayoutCompleted = false;
|
||||||
d->layoutStep();
|
d->layoutStep();
|
||||||
} else {
|
} else {
|
||||||
d->ensureLayoutedByPosition(from);
|
d->ensureLayoutedByPosition(from);
|
||||||
|
Loading…
Reference in New Issue
Block a user