Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP6
qt6-base.33152
0002-QTextLayout-fix-maximumWidth-for-a-text-co...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0002-QTextLayout-fix-maximumWidth-for-a-text-containing-line.patch of Package qt6-base.33152
From 991c056438b311566bc4ea543af0f33dfd5dffbb Mon Sep 17 00:00:00 2001 From: Vladimir Belyavsky <belyavskyv@gmail.com> Date: Tue, 27 Sep 2022 16:57:08 +0300 Subject: [PATCH] QTextLayout: fix maximumWidth() for a text containing line separator This is improved version of previous fix 013c346a8dcbd618febb07884c64c740daf9754d that was reverted because it broke some tests for Quick Text. The problem was that it did not work correctly in the case the text was wrapped to a fixed width. To deal with this we'll accumulate current line full width (as if it hadn't been wrapped) in layout data (layoutData->currentMaxWidth). Then when the next line is explicitly wrapped by line or paragraph separator, this accumulated width will be used to adjust layout's maximum width. Change-Id: Iad7119d9808e1db15fe1fbc5db049c3db928529f Fixes: QTBUG-89557 Fixes: QTBUG-104986 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> --- src/gui/text/qtextengine.cpp | 3 +++ src/gui/text/qtextengine_p.h | 1 + src/gui/text/qtextlayout.cpp | 16 +++++++++++----- tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 16 +++++++++++++++- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 35d604859409..af974753159c 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 925dafe04e2f..59e332c64aeb 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 e4281b78e601..d168a77d57f5 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 67d4b9884bb7..3958e2a01c98 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 -- 2.16.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor