diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 35d60485940..af974753159 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2604,6 +2604,7 @@ QTextEngine::LayoutData::LayoutData() haveCharAttributes = false; logClustersPtr = nullptr; available_glyphs = 0; + currentMaxWidth = 0; } QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int _allocated) @@ -2636,6 +2637,7 @@ QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int hasBidi = false; layoutState = LayoutEmpty; haveCharAttributes = false; + currentMaxWidth = 0; } QTextEngine::LayoutData::~LayoutData() @@ -2721,6 +2723,7 @@ void QTextEngine::freeMemory() layoutData->hasBidi = false; layoutData->layoutState = LayoutEmpty; layoutData->haveCharAttributes = false; + layoutData->currentMaxWidth = 0; layoutData->items.clear(); } if (specialData) diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 925dafe04e2..59e332c64ae 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -385,6 +385,7 @@ public: uint layoutState : 2; uint memory_on_stack : 1; uint haveCharAttributes : 1; + QFixed currentMaxWidth; QString string; bool reallocate(int totalGlyphs); }; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index e4281b78e60..d168a77d57f 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1865,6 +1865,7 @@ void QTextLine::layout_helper(int maxGlyphs) lbh.logClusters = eng->layoutData->logClustersPtr; lbh.previousGlyph = 0; + bool manuallyWrapped = false; bool hasInlineObject = false; QFixed maxInlineObjectHeight = 0; @@ -1940,6 +1941,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; @@ -1974,11 +1976,10 @@ void QTextLine::layout_helper(int maxGlyphs) addNextCluster(lbh.currentPosition, end, lbh.spaceData, lbh.glyphCount, current, lbh.logClusters, lbh.glyphs); } - - if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) { - goto found; - } } else { + if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) + goto found; + lbh.whiteSpaceOrObject = false; bool sb_or_ws = false; lbh.saveCurrentGlyph(); @@ -2161,7 +2162,12 @@ found: eng->maxWidth = qMax(eng->maxWidth, line.textWidth); } else { eng->minWidth = qMax(eng->minWidth, lbh.minw); - eng->maxWidth += line.textWidth + lbh.spaceData.textWidth; + eng->layoutData->currentMaxWidth += line.textWidth; + if (!manuallyWrapped) + eng->layoutData->currentMaxWidth += lbh.spaceData.textWidth; + eng->maxWidth = qMax(eng->maxWidth, eng->layoutData->currentMaxWidth); + if (manuallyWrapped) + eng->layoutData->currentMaxWidth = 0; } line.textWidth += trailingSpace; diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index 67d4b9884bb..3958e2a01c9 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -2655,17 +2655,28 @@ void tst_QTextLayout::min_maximumWidth_data() QTest::newRow("long string") << QStringLiteral("lmong_long_crazy_87235982735_23857239682376923876923876-fuwhfhfw-names-AAAA-deeaois2019-03-03.and.more"); QTest::newRow("QTBUG-106947") << QStringLiteral("text text"); QTest::newRow("spaces") << QStringLiteral(" text text "); + QTest::newRow("QTBUG-104986") << QStringLiteral("text\ntext\ntext"); + QTest::newRow("spaces + line breaks") << QStringLiteral(" \n text\n \ntext \n "); } void tst_QTextLayout::min_maximumWidth() { QFETCH(QString, text); + text.replace('\n', QChar::LineSeparator); QTextLayout layout(text, testFont); layout.setCacheEnabled(true); + QTextOption opt; + opt.setWrapMode(QTextOption::NoWrap); + layout.setTextOption(opt); + layout.beginLayout(); + while (layout.createLine().isValid()) { } + layout.endLayout(); + + const qreal nonWrappedMaxWidth = layout.maximumWidth(); + for (int wrapMode = QTextOption::NoWrap; wrapMode <= QTextOption::WrapAtWordBoundaryOrAnywhere; ++wrapMode) { - QTextOption opt; opt.setWrapMode((QTextOption::WrapMode)wrapMode); layout.setTextOption(opt); layout.beginLayout(); @@ -2674,6 +2685,9 @@ void tst_QTextLayout::min_maximumWidth() const qreal minWidth = layout.minimumWidth(); const qreal maxWidth = layout.maximumWidth(); + QCOMPARE_LE(minWidth, maxWidth); + QCOMPARE_LE(maxWidth, nonWrappedMaxWidth); // maxWidth for wrapped text shouldn't exceed maxWidth for the text without wrapping. + // Try the layout from slightly wider than the widest (maxWidth) // and narrow it down to slighly narrower than minWidth // layout.maximumWidth() should return the same regardless