Don't include bearing of mid-string characters in max width
When calculating the maximum width of a text layout, we would add the text width of each substring *after* we had added the negative right bearing of the last character to it. But the bearing of the last character in a wrapped substring does not actually add to the maximum width unless it is the last character of the *whole* string. Prior to 250117086ff15bba79df8f0e15ee66192edc9ea9 this was not noticed, because the last glyph in the substring would typically be a space and the space does not have any bearings (when doing wrapping on individual characters it could still happen). After the change, the previous glyph for which we get the right bearing will be the last non-whitespace glyph. If this happened to have a negative right bearing, we would add this to the max width and end up with a larger max width than we should. This caused a test failure in tst_qquicktext. This test prefers the text width without the bearing (i.e. the *advance* of the substring) unless the line is manually wrapped or it is the last line of the layout. Pick-to: 6.8 Change-Id: Iba1a5ad48d575683672400f0572dfa683a0f2d9c Reviewed-by: Lars Knoll <lars@knoll.priv.no> (cherry picked from commit c08a92307d6d9fa9d9d9a1f301e3f2a65374e99a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
e266949979
commit
610ee0c504
@ -1860,6 +1860,7 @@ void QTextLine::layout_helper(int maxGlyphs)
|
|||||||
|
|
||||||
bool manuallyWrapped = false;
|
bool manuallyWrapped = false;
|
||||||
bool hasInlineObject = false;
|
bool hasInlineObject = false;
|
||||||
|
bool reachedEndOfLine = false;
|
||||||
QFixed maxInlineObjectHeight = 0;
|
QFixed maxInlineObjectHeight = 0;
|
||||||
|
|
||||||
const bool includeTrailingSpaces = eng->option.flags() & QTextOption::IncludeTrailingSpaces;
|
const bool includeTrailingSpaces = eng->option.flags() & QTextOption::IncludeTrailingSpaces;
|
||||||
@ -2087,6 +2088,7 @@ void QTextLine::layout_helper(int maxGlyphs)
|
|||||||
newItem = item + 1;
|
newItem = item + 1;
|
||||||
}
|
}
|
||||||
LB_DEBUG("reached end of line");
|
LB_DEBUG("reached end of line");
|
||||||
|
reachedEndOfLine = true;
|
||||||
lbh.checkFullOtherwiseExtend(line);
|
lbh.checkFullOtherwiseExtend(line);
|
||||||
line.textWidth += lbh.commitedSoftHyphenWidth;
|
line.textWidth += lbh.commitedSoftHyphenWidth;
|
||||||
found:
|
found:
|
||||||
@ -2097,6 +2099,7 @@ found:
|
|||||||
lbh.calculateRightBearing();
|
lbh.calculateRightBearing();
|
||||||
|
|
||||||
// Then apply any negative right bearing
|
// Then apply any negative right bearing
|
||||||
|
const QFixed textWidthWithoutBearing = line.textWidth;
|
||||||
line.textWidth += lbh.negativeRightBearing();
|
line.textWidth += lbh.negativeRightBearing();
|
||||||
|
|
||||||
if (line.length == 0) {
|
if (line.length == 0) {
|
||||||
@ -2168,7 +2171,11 @@ found:
|
|||||||
eng->maxWidth = qMax(eng->maxWidth, line.textWidth);
|
eng->maxWidth = qMax(eng->maxWidth, line.textWidth);
|
||||||
} else {
|
} else {
|
||||||
eng->minWidth = qMax(eng->minWidth, lbh.minw);
|
eng->minWidth = qMax(eng->minWidth, lbh.minw);
|
||||||
if (qAddOverflow(eng->layoutData->currentMaxWidth, line.textWidth, &eng->layoutData->currentMaxWidth))
|
|
||||||
|
const QFixed actualTextWidth = manuallyWrapped || reachedEndOfLine
|
||||||
|
? line.textWidth
|
||||||
|
: textWidthWithoutBearing;
|
||||||
|
if (qAddOverflow(eng->layoutData->currentMaxWidth, actualTextWidth, &eng->layoutData->currentMaxWidth))
|
||||||
eng->layoutData->currentMaxWidth = QFIXED_MAX;
|
eng->layoutData->currentMaxWidth = QFIXED_MAX;
|
||||||
if (!manuallyWrapped) {
|
if (!manuallyWrapped) {
|
||||||
if (qAddOverflow(eng->layoutData->currentMaxWidth, lbh.spaceData.textWidth, &eng->layoutData->currentMaxWidth))
|
if (qAddOverflow(eng->layoutData->currentMaxWidth, lbh.spaceData.textWidth, &eng->layoutData->currentMaxWidth))
|
||||||
|
@ -130,6 +130,7 @@ private slots:
|
|||||||
void negativeLineWidth();
|
void negativeLineWidth();
|
||||||
void embeddedImageLineHeight();
|
void embeddedImageLineHeight();
|
||||||
void unmatchedShapedSubstring();
|
void unmatchedShapedSubstring();
|
||||||
|
void maximumLayoutWidthInWrappedLayout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QFont testFont;
|
QFont testFont;
|
||||||
@ -2836,5 +2837,43 @@ void tst_QTextLayout::unmatchedShapedSubstring()
|
|||||||
QVERIFY(glyphRuns.size() > 0);
|
QVERIFY(glyphRuns.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QTextLayout::maximumLayoutWidthInWrappedLayout()
|
||||||
|
{
|
||||||
|
QString s = QString::fromUtf8("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
|
||||||
|
"Integer at ante dui Curabitur ante est, pulvinar quis adipiscing a, iaculis id ipsum. Nunc blandit\n"
|
||||||
|
"condimentum odio vel egestas. in ipsum lacinia sit amet\n"
|
||||||
|
"mattis orci interdum. Quisque vitae accumsan lectus. Ut nisi turpis,\n"
|
||||||
|
"sollicitudin ut dignissim id, fermentum ac est. Maecenas nec libero leo. Sed ac\n"
|
||||||
|
"mattis orci interdum. Quisque vitae accumsan lectus. Ut nisi turpis,\n"
|
||||||
|
"sollicitudin ut dignissim id, fermentum ac est. Maecenas nec libero leo. Sed ac\n"
|
||||||
|
"leo eget ipsum ultricies viverra sit amet eu orci. Praesent et tortor risus,\n"
|
||||||
|
"viverra accumsan sapien. Sed faucibus eleifend lectus, sed euismod urna porta\n"
|
||||||
|
"eu. Quisque vitae accumsan lectus.");
|
||||||
|
s.replace(QChar::LineFeed, QChar::LineSeparator);
|
||||||
|
|
||||||
|
QTextLayout reference;
|
||||||
|
reference.setText(s);
|
||||||
|
reference.beginLayout();
|
||||||
|
forever {
|
||||||
|
QTextLine line = reference.createLine();
|
||||||
|
if (!line.isValid())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
reference.endLayout();
|
||||||
|
|
||||||
|
QTextLayout breakByWidth;
|
||||||
|
breakByWidth.setText(s);
|
||||||
|
breakByWidth.beginLayout();
|
||||||
|
forever {
|
||||||
|
QTextLine line = breakByWidth.createLine();
|
||||||
|
if (!line.isValid())
|
||||||
|
break;
|
||||||
|
line.setLineWidth(100);
|
||||||
|
}
|
||||||
|
breakByWidth.endLayout();
|
||||||
|
|
||||||
|
QCOMPARE(reference.maximumWidth(), breakByWidth.maximumWidth());
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QTextLayout)
|
QTEST_MAIN(tst_QTextLayout)
|
||||||
#include "tst_qtextlayout.moc"
|
#include "tst_qtextlayout.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user