summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <[email protected]>2024-11-29 15:02:26 +0100
committerEskil Abrahamsen Blomfeldt <[email protected]>2024-12-02 19:09:13 +0100
commit40e364172f001ce7dd6e4e72716e9c17c9d29b9e (patch)
treef72978c857e6d7ba08948e17d7d0ad0c274c119f
parentcbd2f56c14159a1a566f4e423b910256724fdb6a (diff)
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 <[email protected]>
-rw-r--r--src/gui/text/qtextengine.cpp3
-rw-r--r--tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp26
2 files changed, 28 insertions, 1 deletions
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index f8caae50e15..0b7651e65e6 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -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)) {
diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
index a6f4ecaa9af..5ef35c16e09 100644
--- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
+++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
@@ -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"