diff options
author | Mårten Nordheim <marten.nordheim@qt.io> | 2018-11-09 17:56:08 +0100 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2018-11-30 16:15:03 +0000 |
commit | 17ced070fd1e55948659bc37c421f98074910599 (patch) | |
tree | 2cc19157f873a7732ad4f470f8d6a872f5c42b5a /src | |
parent | d23d146175d6fab2ede50818777afe248ca0be23 (diff) |
Read font selection flags and use them when querying for metrics
Certain fonts with multiple styles have the same family name. When
loading these as application fonts we were not specific enough when
querying for the text metrics. This meant that e.g. the bold version in
a font family would get the metrics of the regular one.
Fixes: QTBUG-67273
Change-Id: Ic988d62cddde0a1f77ddcaf2891cadc21c9b31e6
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp | 39 | ||||
-rw-r--r-- | src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h | 8 |
2 files changed, 41 insertions, 6 deletions
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index c70d507b99..9ff50bdf05 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -1490,7 +1490,8 @@ static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag, static void getFamiliesAndSignatures(const QByteArray &fontData, QList<QFontNames> *families, - QVector<FONTSIGNATURE> *signatures) + QVector<FONTSIGNATURE> *signatures, + QVector<QFontValues> *values) { const uchar *data = reinterpret_cast<const uchar *>(fontData.constData()); @@ -1511,9 +1512,25 @@ static void getFamiliesAndSignatures(const QByteArray &fontData, families->append(qMove(names)); + if (values || signatures) + getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length); + + if (values) { + QFontValues fontValues; + if (table && length >= 64) { + // Read in some details about the font, offset calculated based on the specification + fontValues.weight = qFromBigEndian<quint16>(table + 4); + + quint16 fsSelection = qFromBigEndian<quint16>(table + 62); + fontValues.isItalic = (fsSelection & 1) != 0; + fontValues.isUnderlined = (fsSelection & (1 << 1)) != 0; + fontValues.isOverstruck = (fsSelection & (1 << 4)) != 0; + } + values->append(std::move(fontValues)); + } + if (signatures) { FONTSIGNATURE signature; - getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length); if (table && length >= 86) { // Offsets taken from OS/2 table in the TrueType spec signature.fsUsb[0] = qFromBigEndian<quint32>(table + 42); @@ -1536,11 +1553,12 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, WinApplicationFont font; font.fileName = fileName; QVector<FONTSIGNATURE> signatures; + QVector<QFontValues> fontValues; QList<QFontNames> families; QStringList familyNames; if (!fontData.isEmpty()) { - getFamiliesAndSignatures(fontData, &families, &signatures); + getFamiliesAndSignatures(fontData, &families, &signatures, &fontValues); if (families.isEmpty()) return familyNames; @@ -1553,14 +1571,23 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, // Memory fonts won't show up in enumeration, so do add them the hard way. for (int j = 0; j < families.count(); ++j) { - const QString familyName = families.at(j).name; - const QString styleName = families.at(j).style; + const auto &family = families.at(j); + const QString &familyName = family.name; + const QString &styleName = family.style; familyNames << familyName; HDC hdc = GetDC(0); LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE - 1, familyName.size())); lf.lfCharSet = DEFAULT_CHARSET; + const QFontValues &values = fontValues.at(j); + lf.lfWeight = values.weight; + if (values.isItalic) + lf.lfItalic = TRUE; + if (values.isOverstruck) + lf.lfStrikeOut = TRUE; + if (values.isUnderlined) + lf.lfUnderline = TRUE; HFONT hfont = CreateFontIndirect(&lf); HGDIOBJ oldobj = SelectObject(hdc, hfont); @@ -1581,7 +1608,7 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, QByteArray data = f.readAll(); f.close(); - getFamiliesAndSignatures(data, &families, 0); + getFamiliesAndSignatures(data, &families, nullptr, nullptr); if (families.isEmpty()) return QStringList(); diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h index ab6d6307c7..9d0aa7f723 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h @@ -177,6 +177,14 @@ struct QFontNames QString preferredStyle; // e.g. "Condensed Italic" }; +struct QFontValues +{ + quint16 weight = 0; + bool isItalic = false; + bool isOverstruck = false; + bool isUnderlined = false; +}; + bool qt_localizedName(const QString &name); QString qt_getEnglishName(const QString &familyName, bool includeStyle = false); QFontNames qt_getCanonicalFontNames(const LOGFONT &lf); |