summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2018-11-09 17:56:08 +0100
committerMårten Nordheim <marten.nordheim@qt.io>2018-11-30 16:15:03 +0000
commit17ced070fd1e55948659bc37c421f98074910599 (patch)
tree2cc19157f873a7732ad4f470f8d6a872f5c42b5a
parentd23d146175d6fab2ede50818777afe248ca0be23 (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>
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp39
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h8
-rw-r--r--tests/auto/gui/text/qfontdatabase/testdata.qrc1
-rw-r--r--tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp29
-rw-r--r--tests/auto/shared/resources/testfont_italic.ttfbin0 -> 64136 bytes
5 files changed, 71 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);
diff --git a/tests/auto/gui/text/qfontdatabase/testdata.qrc b/tests/auto/gui/text/qfontdatabase/testdata.qrc
index 81a0b5b0bf..224e845601 100644
--- a/tests/auto/gui/text/qfontdatabase/testdata.qrc
+++ b/tests/auto/gui/text/qfontdatabase/testdata.qrc
@@ -3,5 +3,6 @@
<file>LED_REAL.TTF</file>
<file alias="testfont.ttf">../../../shared/resources/testfont.ttf</file>
<file alias="testfont_condensed.ttf">../../../shared/resources/testfont_condensed.ttf</file>
+ <file alias="testfont_italic.ttf">../../../shared/resources/testfont_italic.ttf</file>
</qresource>
</RCC>
diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
index da2f100c0b..68664cdd2f 100644
--- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
@@ -61,6 +61,8 @@ private slots:
void addAppFont_data();
void addAppFont();
+ void addTwoAppFontsFromFamily();
+
void aliases();
void fallbackFonts();
@@ -75,6 +77,7 @@ private:
QString m_ledFont;
QString m_testFont;
QString m_testFontCondensed;
+ QString m_testFontItalic;
};
tst_QFontDatabase::tst_QFontDatabase()
@@ -86,9 +89,11 @@ void tst_QFontDatabase::initTestCase()
m_ledFont = QFINDTESTDATA("LED_REAL.TTF");
m_testFont = QFINDTESTDATA("testfont.ttf");
m_testFontCondensed = QFINDTESTDATA("testfont_condensed.ttf");
+ m_testFontItalic = QFINDTESTDATA("testfont_italic.ttf");
QVERIFY(!m_ledFont.isEmpty());
QVERIFY(!m_testFont.isEmpty());
QVERIFY(!m_testFontCondensed.isEmpty());
+ QVERIFY(!m_testFontItalic.isEmpty());
}
void tst_QFontDatabase::styles_data()
@@ -259,6 +264,30 @@ void tst_QFontDatabase::addAppFont()
QCOMPARE(db.families(), oldFamilies);
}
+void tst_QFontDatabase::addTwoAppFontsFromFamily()
+{
+ int regularId = QFontDatabase::addApplicationFont(m_testFont);
+ if (regularId == -1)
+ QSKIP("Skip the test since app fonts are not supported on this system");
+
+ int italicId = QFontDatabase::addApplicationFont(m_testFontItalic);
+ QVERIFY(italicId != -1);
+
+ QVERIFY(!QFontDatabase::applicationFontFamilies(regularId).isEmpty());
+ QVERIFY(!QFontDatabase::applicationFontFamilies(italicId).isEmpty());
+
+ QString regularFontName = QFontDatabase::applicationFontFamilies(regularId).first();
+ QString italicFontName = QFontDatabase::applicationFontFamilies(italicId).first();
+ QCOMPARE(regularFontName, italicFontName);
+
+ QFont italicFont = QFontDatabase().font(italicFontName,
+ QString::fromLatin1("Italic"), 14);
+ QVERIFY(italicFont.italic());
+
+ QFontDatabase::removeApplicationFont(regularId);
+ QFontDatabase::removeApplicationFont(italicId);
+}
+
void tst_QFontDatabase::aliases()
{
QFontDatabase db;
diff --git a/tests/auto/shared/resources/testfont_italic.ttf b/tests/auto/shared/resources/testfont_italic.ttf
new file mode 100644
index 0000000000..0a01f883f4
--- /dev/null
+++ b/tests/auto/shared/resources/testfont_italic.ttf
Binary files differ