Remove false Q_UNREACHABLE from shaping code
This was added by 9ff76c27b9 on
the basis that it signifies a shaping error and would later assert
or crash.
But the line is easily reachable by user code. If Harfbuzz returns
0 glyphs, it just means it is unable to shape the string, for instance
if the input string only contains default ignorables (like a ZWJ)
and does not have any appropriate glyph to use for replacement.
Qt expects there to always be at least one glyph in the output
(num_glyphs == 0 is used to indicate shaping is not yet done), so
to avoid asserts later on, we simply populate the output with a
single 0 token, which is a required entry in the font that is
reserved for representing unrepresentable characters.
This also adds a test and therefore a zero-width joiner to the test
font to reproduce the issue.
[ChangeLog][QtGui][Text] Fixed a possible crash with certain fonts
when shaping strings consisting only of control characters.
Fixes: QTBUG-89155
Pick-to: 5.15
Pick-to: 6.0
Change-Id: Ia0dd6a04844c9be90dcab6c464bebe339a3dab11
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
bb10
parent
52fcd0b6d7
commit
fccd419dd6
|
|
@ -1546,12 +1546,21 @@ void QTextEngine::shapeText(int item) const
|
|||
|
||||
si.num_glyphs = glyph_pos;
|
||||
}
|
||||
|
||||
if (Q_UNLIKELY(si.num_glyphs == 0)) {
|
||||
Q_UNREACHABLE(); // ### report shaping errors somehow
|
||||
if (Q_UNLIKELY(!ensureSpace(si.glyph_data_offset + 1))) {
|
||||
qWarning() << "Unable to allocate space for place-holder glyph";
|
||||
return;
|
||||
}
|
||||
|
||||
si.num_glyphs = 1;
|
||||
|
||||
// Overwrite with 0 token to indicate failure
|
||||
QGlyphLayout g = availableGlyphs(&si);
|
||||
g.glyphs[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
layoutData->used += si.num_glyphs;
|
||||
|
||||
QGlyphLayout glyphs = shapedGlyphs(&si);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ private slots:
|
|||
void boundingRect();
|
||||
void mixedScripts();
|
||||
void multiLineBoundingRect();
|
||||
void defaultIgnorables();
|
||||
|
||||
private:
|
||||
int m_testFontId;
|
||||
|
|
@ -631,6 +632,21 @@ void tst_QGlyphRun::multiLineBoundingRect()
|
|||
QVERIFY(firstLineGlyphRun.boundingRect().height() < allGlyphRun.boundingRect().height());
|
||||
}
|
||||
|
||||
void tst_QGlyphRun::defaultIgnorables()
|
||||
{
|
||||
QTextLayout layout;
|
||||
layout.setFont(QFont("QtsSpecialTestFont"));
|
||||
layout.setText(QChar(0x200D));
|
||||
layout.beginLayout();
|
||||
layout.createLine();
|
||||
layout.endLayout();
|
||||
|
||||
QList<QGlyphRun> runs = layout.glyphRuns();
|
||||
QCOMPARE(runs.size(), 1);
|
||||
QCOMPARE(runs.at(0).glyphIndexes().size(), 1);
|
||||
QCOMPARE(runs.at(0).glyphIndexes()[0], 0);
|
||||
}
|
||||
|
||||
#endif // QT_NO_RAWFONT
|
||||
|
||||
QTEST_MAIN(tst_QGlyphRun)
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue