diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 10d3b5d2cbe..80c28a376aa 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -436,6 +436,10 @@ bool QFontEngine::processHheaTable() const qint16 descent = qFromBigEndian(hhea.constData() + 6); qint16 leading = qFromBigEndian(hhea.constData() + 8); + // Some fonts may have invalid HHEA data. We detect this and bail out. + if (ascent == 0 && descent == 0) + return false; + QFixed unitsPerEm = emSquareSize(); m_ascent = QFixed::fromReal(ascent * fontDef.pixelSize) / unitsPerEm; m_descent = -QFixed::fromReal(descent * fontDef.pixelSize) / unitsPerEm; @@ -450,7 +454,10 @@ bool QFontEngine::processHheaTable() const void QFontEngine::initializeHeightMetrics() const { - bool hasEmbeddedBitmaps = !getSfntTable(MAKE_TAG('E', 'B', 'L', 'C')).isEmpty() || !getSfntTable(MAKE_TAG('C', 'B', 'L', 'C')).isEmpty(); + bool hasEmbeddedBitmaps = + !getSfntTable(MAKE_TAG('E', 'B', 'L', 'C')).isEmpty() + || !getSfntTable(MAKE_TAG('C', 'B', 'L', 'C')).isEmpty() + || !getSfntTable(MAKE_TAG('b', 'd', 'a', 't')).isEmpty(); if (!hasEmbeddedBitmaps) { // Get HHEA table values if available processHheaTable(); @@ -476,10 +483,16 @@ bool QFontEngine::processOS2Table() const enum { USE_TYPO_METRICS = 0x80 }; QFixed unitsPerEm = emSquareSize(); if (fsSelection & USE_TYPO_METRICS) { + // Some fonts may have invalid OS/2 data. We detect this and bail out. + if (typoAscent == 0 && typoDescent == 0) + return false; m_ascent = QFixed::fromReal(typoAscent * fontDef.pixelSize) / unitsPerEm; m_descent = -QFixed::fromReal(typoDescent * fontDef.pixelSize) / unitsPerEm; m_leading = QFixed::fromReal(typoLineGap * fontDef.pixelSize) / unitsPerEm; } else { + // Some fonts may have invalid OS/2 data. We detect this and bail out. + if (winAscent == 0 && winDescent == 0) + return false; m_ascent = QFixed::fromReal(winAscent * fontDef.pixelSize) / unitsPerEm; m_descent = QFixed::fromReal(winDescent * fontDef.pixelSize) / unitsPerEm; } diff --git a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp index 9ed88fe8ed0..f6700eb43af 100644 --- a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp @@ -57,6 +57,8 @@ private slots: void leadingBelowLine(); void elidedMetrics(); void zeroWidthMetrics(); + void verticalMetrics_data(); + void verticalMetrics(); }; void tst_QFontMetrics::same() @@ -394,5 +396,22 @@ void tst_QFontMetrics::zeroWidthMetrics() QCOMPARE(fm.tightBoundingRect(string3).width(), fm.tightBoundingRect(string4).width()); } +void tst_QFontMetrics::verticalMetrics_data() +{ + QTest::addColumn("font"); + QStringList families = QFontDatabase::families(); + for (const QString &family : families) { + QFont font(family); + QTest::newRow(family.toUtf8()) << font; + } +} + +void tst_QFontMetrics::verticalMetrics() +{ + QFETCH(QFont, font); + QFontMetrics fm(font); + QVERIFY(fm.ascent() != 0 || fm.descent() != 0); +} + QTEST_MAIN(tst_QFontMetrics) #include "tst_qfontmetrics.moc"