diff options
author | Eskil Abrahamsen Blomfeldt <[email protected]> | 2024-11-18 13:28:28 +0100 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <[email protected]> | 2024-11-18 17:43:50 +0100 |
commit | 7b024cc1749494114fffc3c434b58846707a64af (patch) | |
tree | 0c223558313113693eda8bc35df764ad81a7409b | |
parent | c7a8cbd272b7ffce1d5da604881ed8f66a632444 (diff) |
Don't count overflowing inline image height to previous line
In the line break algorithm, we try filling characters and
objects onto a text line until we see an overflow. We then
keep the state *before* the overflow as the current line and
move to the next.
However, for inline images we would store its height to the
current state before checking if it overflowed. So if the
inline image did cause an overflow it would be counted
towards the height of the preceding line in addition to the
line where it actually ended up.
[ChangeLog][Text] Fixed an issue which could cause the
height of a word-wrapped text line to grow if the immediate
line after it began with an inline image.
Pick-to: 5.15 6.5 6.8
Fixes: QTBUG-130980
Change-Id: I68494b49059e5e35349cbde77aefc64abeb69697
Reviewed-by: Lars Knoll <[email protected]>
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 7 | ||||
-rw-r--r-- | tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 49 |
2 files changed, 53 insertions, 3 deletions
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index f0c7dd24e5b..de56f1040e0 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1951,15 +1951,16 @@ void QTextLine::layout_helper(int maxGlyphs) } } - hasInlineObject = true; - maxInlineObjectHeight = qMax(maxInlineObjectHeight, current.ascent + current.descent); - lbh.tmpData.textWidth += current.width; newItem = item + 1; ++lbh.glyphCount; if (lbh.checkFullOtherwiseExtend(line)) goto found; + + hasInlineObject = true; + maxInlineObjectHeight = qMax(maxInlineObjectHeight, current.ascent + current.descent); + } else if (attributes[lbh.currentPosition].whiteSpace && eng->layoutData->string.at(lbh.currentPosition).decompositionTag() != QChar::NoBreak) { lbh.whiteSpaceOrObject = true; diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index a8c737634a3..a6f4ecaa9af 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -128,6 +128,7 @@ private slots: void min_maximumWidth_data(); void min_maximumWidth(); void negativeLineWidth(); + void embeddedImageLineHeight(); private: QFont testFont; @@ -2761,5 +2762,53 @@ void tst_QTextLayout::negativeLineWidth() } } +void tst_QTextLayout::embeddedImageLineHeight() +{ + QString s1 = QStringLiteral("Foobar Foobar Foobar Foobar"); + QString s2 = QStringLiteral("<img height=\"80\" width=\"80\" />Foobar Foobar Foobar Foobar"); + + qreal s1Width; + qreal s1Height; + { + QTextDocument document; + document.setHtml(s1); + QCOMPARE(document.blockCount(), 1); + + // Trigger layout + { + QImage img(1, 1, QImage::Format_ARGB32_Premultiplied); + QPainter p(&img); + document.drawContents(&p); + } + + QTextLayout *layout = document.firstBlock().layout(); + QVERIFY(layout != nullptr); + QCOMPARE(layout->lineCount(), 1); + QTextLine line = layout->lineAt(0); + s1Width = document.idealWidth(); + s1Height = line.ascent() + line.descent(); + } + + { + QTextDocument document; + document.setHtml(s1 + s2); + document.setTextWidth(std::ceil(s1Width)); + QCOMPARE(document.blockCount(), 1); + + // Trigger layout + { + QImage img(1, 1, QImage::Format_ARGB32_Premultiplied); + QPainter p(&img); + document.drawContents(&p); + } + + QTextLayout *layout = document.firstBlock().layout(); + QVERIFY(layout != nullptr); + QVERIFY(layout->lineCount() > 1); + QTextLine line = layout->lineAt(0); + QCOMPARE(line.ascent() + line.descent(), s1Height); + } +} + QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" |