Fix assert in certain cases of missing glyph in a string

If a substring for a fallback engine spanned multiple characters,
we would only assign the first of the characters to a glyph in
log clusters. This could cause the log clusters array to become
non-monotonic (you could get an array like [0, 1, 2, 0, 3, 4]).
In turn, this would confuse the text layout algorithm which
depends on the indexes always increasing, and we would sometimes
hit an assert in addNextCluster() if we were unlucky.

To rectify this, make sure all characters in the substring are
mapped to the same cluster.

Fixes: QTBUG-131731
Pick-to: 5.15 6.5 6.8
Change-Id: I93415a58351349ead6eb7a016b32b09f274e6fe4
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2024-11-29 15:02:26 +01:00
parent cbd2f56c14
commit 40e364172f
2 changed files with 28 additions and 1 deletions

View File

@ -1753,7 +1753,8 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si,
g.offsets[0].y = QFixed{};
g.attributes[0].clusterStart = true;
g.attributes[0].dontPrint = true;
log_clusters[0] = glyphs_shaped;
for (uint str_pos = 0; str_pos < item_length; ++str_pos)
log_clusters[str_pos] = glyphs_shaped;
}
if (Q_UNLIKELY(engineIdx != 0)) {

View File

@ -129,6 +129,7 @@ private slots:
void min_maximumWidth();
void negativeLineWidth();
void embeddedImageLineHeight();
void unmatchedShapedSubstring();
private:
QFont testFont;
@ -2810,5 +2811,30 @@ void tst_QTextLayout::embeddedImageLineHeight()
}
}
void tst_QTextLayout::unmatchedShapedSubstring()
{
QString s;
s += QChar(9977);
s += QChar(65039);
s += QChar(8205);
s += QChar(9794);
s += QChar(65039);
QTextLayout lout;
QTextOption opt;
opt.setFlags(QTextOption::DisableEmojiParsing);
lout.setTextOption(opt);
// Note: Shaping of this string would previously assert on some platforms
lout.setText(s);
lout.beginLayout();
lout.createLine();
lout.endLayout();
QList<QGlyphRun> glyphRuns = lout.glyphRuns();
QVERIFY(glyphRuns.size() > 0);
}
QTEST_MAIN(tst_QTextLayout)
#include "tst_qtextlayout.moc"