QTextLayout: fix maximumWidth() for a text containing line separator
When laying out, we need to increase layout's maximum width _only_ if the previous line was not explicitly wrapped by a line or paragraph separator, or if the current line's width is greater than the previously accumulated layout's maximum width. Fixes: QTBUG-89557 Fixes: QTBUG-104986 Pick-to: 6.2 6.4 Change-Id: Ib7cc4b9dda8f20166dcbd5cfd3b56424bb33d14a Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
parent
53086094d8
commit
013c346a8d
@ -2603,6 +2603,7 @@ QTextEngine::LayoutData::LayoutData()
|
||||
hasBidi = false;
|
||||
layoutState = LayoutEmpty;
|
||||
haveCharAttributes = false;
|
||||
previousLineManuallyWrapped = false;
|
||||
logClustersPtr = nullptr;
|
||||
available_glyphs = 0;
|
||||
}
|
||||
@ -2637,6 +2638,7 @@ QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int
|
||||
hasBidi = false;
|
||||
layoutState = LayoutEmpty;
|
||||
haveCharAttributes = false;
|
||||
previousLineManuallyWrapped = false;
|
||||
}
|
||||
|
||||
QTextEngine::LayoutData::~LayoutData()
|
||||
@ -2722,6 +2724,7 @@ void QTextEngine::freeMemory()
|
||||
layoutData->hasBidi = false;
|
||||
layoutData->layoutState = LayoutEmpty;
|
||||
layoutData->haveCharAttributes = false;
|
||||
layoutData->previousLineManuallyWrapped = false;
|
||||
layoutData->items.clear();
|
||||
}
|
||||
if (specialData)
|
||||
|
@ -385,6 +385,7 @@ public:
|
||||
uint layoutState : 2;
|
||||
uint memory_on_stack : 1;
|
||||
uint haveCharAttributes : 1;
|
||||
uint previousLineManuallyWrapped : 1;
|
||||
QString string;
|
||||
bool reallocate(int totalGlyphs);
|
||||
};
|
||||
|
@ -1808,6 +1808,7 @@ void QTextLine::layout_helper(int maxGlyphs)
|
||||
lbh.logClusters = eng->layoutData->logClustersPtr;
|
||||
lbh.previousGlyph = 0;
|
||||
|
||||
bool manuallyWrapped = false;
|
||||
bool hasInlineObject = false;
|
||||
QFixed maxInlineObjectHeight = 0;
|
||||
|
||||
@ -1883,6 +1884,7 @@ void QTextLine::layout_helper(int maxGlyphs)
|
||||
lbh.calculateRightBearingForPreviousGlyph();
|
||||
}
|
||||
line += lbh.tmpData;
|
||||
manuallyWrapped = true;
|
||||
goto found;
|
||||
} else if (current.analysis.flags == QScriptAnalysis::Object) {
|
||||
lbh.whiteSpaceOrObject = true;
|
||||
@ -2105,7 +2107,10 @@ found:
|
||||
eng->maxWidth = qMax(eng->maxWidth, line.textWidth);
|
||||
} else {
|
||||
eng->minWidth = qMax(eng->minWidth, lbh.minw);
|
||||
eng->maxWidth += line.textWidth;
|
||||
if (eng->layoutData->previousLineManuallyWrapped)
|
||||
eng->maxWidth = qMax(eng->maxWidth, line.textWidth);
|
||||
else
|
||||
eng->maxWidth += line.textWidth;
|
||||
}
|
||||
|
||||
if (line.textWidth > 0 && item < eng->layoutData->items.size())
|
||||
@ -2119,6 +2124,8 @@ found:
|
||||
|
||||
line.justified = false;
|
||||
line.gridfitted = false;
|
||||
|
||||
eng->layoutData->previousLineManuallyWrapped = manuallyWrapped;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -125,6 +125,7 @@ private slots:
|
||||
void softHyphens_data();
|
||||
void softHyphens();
|
||||
void min_maximumWidth();
|
||||
void min_maximumWidthWithLineSeparator();
|
||||
|
||||
private:
|
||||
QFont testFont;
|
||||
@ -2683,5 +2684,32 @@ void tst_QTextLayout::min_maximumWidth()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QTextLayout::min_maximumWidthWithLineSeparator()
|
||||
{
|
||||
QTextLayout referenceLayout("text", testFont);
|
||||
|
||||
QString multilineText("text\ntext\ntext");
|
||||
multilineText.replace('\n', QChar::LineSeparator);
|
||||
QTextLayout layout(multilineText, testFont);
|
||||
|
||||
for (int wrapMode = QTextOption::NoWrap; wrapMode <= QTextOption::WrapAtWordBoundaryOrAnywhere; ++wrapMode) {
|
||||
QTextOption opt;
|
||||
opt.setWrapMode((QTextOption::WrapMode)wrapMode);
|
||||
|
||||
referenceLayout.setTextOption(opt);
|
||||
referenceLayout.beginLayout();
|
||||
while (referenceLayout.createLine().isValid()) { }
|
||||
referenceLayout.endLayout();
|
||||
|
||||
layout.setTextOption(opt);
|
||||
layout.beginLayout();
|
||||
while (layout.createLine().isValid()) { }
|
||||
layout.endLayout();
|
||||
|
||||
QCOMPARE(layout.minimumWidth(), referenceLayout.minimumWidth());
|
||||
QCOMPARE(layout.maximumWidth(), referenceLayout.maximumWidth());
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QTextLayout)
|
||||
#include "tst_qtextlayout.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user