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 <lars@knoll.priv.no>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2024-11-18 13:28:28 +01:00
parent c7a8cbd272
commit 7b024cc174
2 changed files with 53 additions and 3 deletions

View File

@ -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;

View File

@ -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"