Fix overlapping text for Osaka font on macOS

The Osaka font on macOS has all zeroes in the OS/2 table, probably
because it is not intended to be cross-platform. In Qt 6 (since
f761ad3cd9) we are trying using the
same vertical metrics on all platforms, but this only works if
they are valid.

To work around this issue, we detect the case when ascent/descent
values are both 0, since this is very unlikely to be intentional,
so we fall back to the system-provided ascent and descent in these
cases.

Adding the test also revealed that we had missed the check for
a macOS-specific bitmap font format when skipping the check for
bitmap fonts in 7a18b7e2c2.

[ChangeLog][macOS][Text] Fixed a problem where using the Osaka
font would lead to overlapping text.

Pick-to: 6.2
Fixes: QTBUG-96880
Change-Id: Ifea7918641a68829e8f5ef20a4fb61c0a7e5b757
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2021-12-01 09:14:23 +01:00
parent c6c039167c
commit 6b02473e1e
2 changed files with 33 additions and 1 deletions

View File

@ -436,6 +436,10 @@ bool QFontEngine::processHheaTable() const
qint16 descent = qFromBigEndian<qint16>(hhea.constData() + 6);
qint16 leading = qFromBigEndian<qint16>(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;
}

View File

@ -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<QFont>("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"