summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp369
-rw-r--r--src/gui/text/windows/qwindowsdirectwritefontdatabase_p.h6
2 files changed, 164 insertions, 211 deletions
diff --git a/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp b/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp
index 25bb1863298..594fc18f9c6 100644
--- a/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp
+++ b/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp
@@ -357,6 +357,79 @@ QStringList QWindowsDirectWriteFontDatabase::fallbacksForFamily(const QString &f
return result;
}
+template<typename T>
+void QWindowsDirectWriteFontDatabase::collectAdditionalNames(T *font,
+ wchar_t *defaultLocale,
+ wchar_t *englishLocale,
+ std::function<void(const std::pair<QString, QString> &)> registerFamily)
+{
+ BOOL ok;
+ QString defaultLocaleGdiCompatibleFamilyName;
+ QString englishLocaleGdiCompatibleFamilyName;
+
+ const bool hasDefaultLocale = defaultLocale != nullptr;
+ Q_ASSERT(englishLocale != nullptr);
+
+ IDWriteLocalizedStrings *names = nullptr;
+ if (SUCCEEDED(font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &names, &ok)) && ok) {
+ defaultLocaleGdiCompatibleFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
+ englishLocaleGdiCompatibleFamilyName = localeString(names, englishLocale);
+
+ names->Release();
+ }
+
+ QString defaultLocaleGdiCompatibleStyleName;
+ QString englishLocaleGdiCompatibleStyleName;
+ if (SUCCEEDED(font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES, &names, &ok)) && ok) {
+ defaultLocaleGdiCompatibleStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
+ englishLocaleGdiCompatibleStyleName = localeString(names, englishLocale);
+
+ names->Release();
+ }
+
+ QString defaultLocaleTypographicFamilyName;
+ QString englishLocaleTypographicFamilyName;
+ if (SUCCEEDED(font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_TYPOGRAPHIC_FAMILY_NAMES, &names, &ok)) && ok) {
+ defaultLocaleTypographicFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
+ englishLocaleTypographicFamilyName = localeString(names, englishLocale);
+
+ names->Release();
+ }
+
+ QString defaultLocaleTypographicStyleName;
+ QString englishLocaleTypographicStyleName;
+ if (SUCCEEDED(font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_TYPOGRAPHIC_SUBFAMILY_NAMES, &names, &ok)) && ok) {
+ defaultLocaleTypographicStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
+ englishLocaleTypographicStyleName = localeString(names, englishLocale);
+
+ names->Release();
+ }
+
+ {
+ const auto key = std::make_pair(englishLocaleGdiCompatibleFamilyName, englishLocaleGdiCompatibleStyleName);
+ if (!englishLocaleGdiCompatibleFamilyName.isEmpty())
+ registerFamily(key);
+ }
+
+ {
+ const auto key = std::make_pair(defaultLocaleGdiCompatibleFamilyName, defaultLocaleGdiCompatibleStyleName);
+ if (!defaultLocaleGdiCompatibleFamilyName.isEmpty())
+ registerFamily(key);
+ }
+
+ {
+ const auto key = std::make_pair(englishLocaleTypographicFamilyName, englishLocaleTypographicStyleName);
+ if (!englishLocaleTypographicFamilyName.isEmpty())
+ registerFamily(key);
+ }
+
+ {
+ const auto key = std::make_pair(defaultLocaleTypographicFamilyName, defaultLocaleTypographicStyleName);
+ if (!defaultLocaleTypographicFamilyName.isEmpty())
+ registerFamily(key);
+ }
+}
+
QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{
qCDebug(lcQpaFonts) << "Adding application font" << fileName;
@@ -377,6 +450,7 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
return QStringList();
}
+ QSet<std::pair<QString, QString> > registeredFonts;
QSet<QString> ret;
for (int i = 0; i < faces.size(); ++i) {
IDWriteFontFace *face = faces.at(i);
@@ -393,62 +467,6 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
DirectWriteScope<IDWriteFontFace3> face3;
if (SUCCEEDED(face->QueryInterface(__uuidof(IDWriteFontFace3),
reinterpret_cast<void **>(&face3)))) {
- QString defaultLocaleFamilyName;
- QString englishLocaleFamilyName;
-
- IDWriteLocalizedStrings *names = nullptr;
- if (SUCCEEDED(face3->GetFamilyNames(&names))) {
- defaultLocaleFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
- englishLocaleFamilyName = localeString(names, englishLocale);
-
- names->Release();
- }
-
- QString defaultLocaleStyleName;
- QString englishLocaleStyleName;
- if (SUCCEEDED(face3->GetFaceNames(&names))) {
- defaultLocaleStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
- englishLocaleStyleName = localeString(names, englishLocale);
-
- names->Release();
- }
-
- BOOL ok;
- QString defaultLocaleGdiCompatibleFamilyName;
- QString englishLocaleGdiCompatibleFamilyName;
- if (SUCCEEDED(face3->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &names, &ok)) && ok) {
- defaultLocaleGdiCompatibleFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
- englishLocaleGdiCompatibleFamilyName = localeString(names, englishLocale);
-
- names->Release();
- }
-
- QString defaultLocaleGdiCompatibleStyleName;
- QString englishLocaleGdiCompatibleStyleName;
- if (SUCCEEDED(face3->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES, &names, &ok)) && ok) {
- defaultLocaleGdiCompatibleStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
- englishLocaleGdiCompatibleStyleName = localeString(names, englishLocale);
-
- names->Release();
- }
-
- QString defaultLocaleTypographicFamilyName;
- QString englishLocaleTypographicFamilyName;
- if (SUCCEEDED(face3->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_TYPOGRAPHIC_FAMILY_NAMES, &names, &ok)) && ok) {
- defaultLocaleTypographicFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
- englishLocaleTypographicFamilyName = localeString(names, englishLocale);
-
- names->Release();
- }
-
- QString defaultLocaleTypographicStyleName;
- QString englishLocaleTypographicStyleName;
- if (SUCCEEDED(face3->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_TYPOGRAPHIC_SUBFAMILY_NAMES, &names, &ok)) && ok) {
- defaultLocaleTypographicStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
- englishLocaleTypographicStyleName = localeString(names, englishLocale);
-
- names->Release();
- }
QFont::Stretch stretch = fromDirectWriteStretch(face3->GetStretch());
QFont::Style style = fromDirectWriteStyle(face3->GetStyle());
@@ -456,26 +474,26 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
bool fixed = face3->IsMonospacedFont();
bool color = face3->IsColorFont();
- qCDebug(lcQpaFonts) << "\tFont names:" << englishLocaleFamilyName << ", " << defaultLocaleFamilyName
- << ", style names:" << englishLocaleStyleName << ", " << defaultLocaleStyleName
- << ", stretch:" << stretch
- << ", style:" << style
- << ", weight:" << weight
- << ", fixed:" << fixed;
+ auto registerFamilyAndStyle = [&](const std::pair<QString, QString> &familyAndStyle)
+ {
+ if (registeredFonts.contains(familyAndStyle))
+ return;
+ registeredFonts.insert(familyAndStyle);
+ ret.insert(familyAndStyle.first);
- if (!englishLocaleFamilyName.isEmpty()) {
+ qCDebug(lcQpaFonts) << "\tRegistering alternative:" << familyAndStyle.first
+ << ":" << familyAndStyle.second;
if (applicationFont != nullptr) {
QFontDatabasePrivate::ApplicationFont::Properties properties;
properties.style = style;
properties.weight = weight;
- properties.familyName = englishLocaleFamilyName;
- properties.styleName = englishLocaleStyleName;
+ properties.familyName = familyAndStyle.first;
+ properties.styleName = familyAndStyle.second;
applicationFont->properties.append(properties);
}
- ret.insert(englishLocaleFamilyName);
- QPlatformFontDatabase::registerFont(englishLocaleFamilyName,
- englishLocaleStyleName,
+ QPlatformFontDatabase::registerFont(familyAndStyle.first,
+ familyAndStyle.second,
QString(),
weight,
style,
@@ -486,139 +504,53 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
fixed,
color,
writingSystems,
- new FontHandle(face, englishLocaleFamilyName));
- }
+ new FontHandle(face, familyAndStyle.first));
+ };
- if (!defaultLocaleFamilyName.isEmpty() && !ret.contains(defaultLocaleFamilyName)) {
- if (applicationFont != nullptr) {
- QFontDatabasePrivate::ApplicationFont::Properties properties;
- properties.style = style;
- properties.weight = weight;
- properties.familyName = englishLocaleFamilyName;
- properties.styleName = englishLocaleStyleName;
- applicationFont->properties.append(properties);
- }
-
- ret.insert(defaultLocaleFamilyName);
- QPlatformFontDatabase::registerFont(defaultLocaleFamilyName,
- defaultLocaleStyleName,
- QString(),
- weight,
- style,
- stretch,
- antialias,
- scalable,
- size,
- fixed,
- color,
- writingSystems,
- new FontHandle(face, defaultLocaleFamilyName));
- }
+ QString defaultLocaleFamilyName;
+ QString englishLocaleFamilyName;
- if (!englishLocaleGdiCompatibleFamilyName.isEmpty() &&
- !ret.contains(englishLocaleGdiCompatibleFamilyName)) {
- if (applicationFont != nullptr) {
- QFontDatabasePrivate::ApplicationFont::Properties properties;
- properties.style = style;
- properties.weight = weight;
- properties.familyName = englishLocaleGdiCompatibleFamilyName;
- applicationFont->properties.append(properties);
- }
+ IDWriteLocalizedStrings *names = nullptr;
+ if (SUCCEEDED(face3->GetFamilyNames(&names))) {
+ defaultLocaleFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
+ englishLocaleFamilyName = localeString(names, englishLocale);
- ret.insert(englishLocaleGdiCompatibleFamilyName);
- QPlatformFontDatabase::registerFont(englishLocaleGdiCompatibleFamilyName,
- englishLocaleGdiCompatibleStyleName,
- QString(),
- weight,
- style,
- stretch,
- antialias,
- scalable,
- size,
- fixed,
- color,
- writingSystems,
- new FontHandle(face, englishLocaleGdiCompatibleFamilyName));
+ names->Release();
}
- if (!defaultLocaleGdiCompatibleFamilyName.isEmpty()
- && !ret.contains(defaultLocaleGdiCompatibleFamilyName)) {
- if (applicationFont != nullptr) {
- QFontDatabasePrivate::ApplicationFont::Properties properties;
- properties.style = style;
- properties.weight = weight;
- properties.familyName = defaultLocaleGdiCompatibleFamilyName;
- applicationFont->properties.append(properties);
- }
+ QString defaultLocaleStyleName;
+ QString englishLocaleStyleName;
+ if (SUCCEEDED(face3->GetFaceNames(&names))) {
+ defaultLocaleStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
+ englishLocaleStyleName = localeString(names, englishLocale);
- ret.insert(defaultLocaleGdiCompatibleFamilyName);
- QPlatformFontDatabase::registerFont(defaultLocaleGdiCompatibleFamilyName,
- defaultLocaleGdiCompatibleStyleName,
- QString(),
- weight,
- style,
- stretch,
- antialias,
- scalable,
- size,
- fixed,
- color,
- writingSystems,
- new FontHandle(face, defaultLocaleGdiCompatibleFamilyName));
+ names->Release();
}
- if (!englishLocaleTypographicFamilyName.isEmpty()
- && !ret.contains(englishLocaleTypographicFamilyName)) {
- if (applicationFont != nullptr) {
- QFontDatabasePrivate::ApplicationFont::Properties properties;
- properties.style = style;
- properties.weight = weight;
- properties.familyName = englishLocaleTypographicFamilyName;
- applicationFont->properties.append(properties);
- }
+ qCDebug(lcQpaFonts) << "\tFont names:" << englishLocaleFamilyName << ", " << defaultLocaleFamilyName
+ << ", style names:" << englishLocaleStyleName << ", " << defaultLocaleStyleName
+ << ", stretch:" << stretch
+ << ", style:" << style
+ << ", weight:" << weight
+ << ", fixed:" << fixed;
- ret.insert(englishLocaleTypographicFamilyName);
- QPlatformFontDatabase::registerFont(englishLocaleTypographicFamilyName,
- englishLocaleTypographicStyleName,
- QString(),
- weight,
- style,
- stretch,
- antialias,
- scalable,
- size,
- fixed,
- color,
- writingSystems,
- new FontHandle(face, englishLocaleTypographicFamilyName));
+ {
+ const auto key = std::make_pair(englishLocaleFamilyName, englishLocaleStyleName);
+ if (!englishLocaleFamilyName.isEmpty())
+ registerFamilyAndStyle(key);
}
- if (!defaultLocaleTypographicFamilyName.isEmpty()
- && !ret.contains(defaultLocaleTypographicFamilyName)) {
- if (applicationFont != nullptr) {
- QFontDatabasePrivate::ApplicationFont::Properties properties;
- properties.style = style;
- properties.weight = weight;
- properties.familyName = defaultLocaleTypographicFamilyName;
- applicationFont->properties.append(properties);
- }
-
- ret.insert(defaultLocaleTypographicFamilyName);
- QPlatformFontDatabase::registerFont(defaultLocaleTypographicFamilyName,
- defaultLocaleTypographicStyleName,
- QString(),
- weight,
- style,
- stretch,
- antialias,
- scalable,
- size,
- fixed,
- color,
- writingSystems,
- new FontHandle(face, defaultLocaleTypographicFamilyName));
+ {
+ const auto key = std::make_pair(defaultLocaleFamilyName, defaultLocaleStyleName);
+ if (!defaultLocaleFamilyName.isEmpty())
+ registerFamilyAndStyle(key);
}
+ collectAdditionalNames(*face3,
+ hasDefaultLocale ? defaultLocale : nullptr,
+ englishLocale,
+ registerFamilyAndStyle);
+
} else {
qCWarning(lcQpaFonts) << "Unable to query IDWriteFontFace3 interface from font face.";
}
@@ -678,44 +610,59 @@ void QWindowsDirectWriteFontDatabase::populateFontDatabase()
if (SUCCEEDED(factory6->GetSystemFontCollection(false,
DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC,
&fontCollection))) {
+ QSet<QString> registeredFamilies;
for (uint i = 0; i < fontCollection->GetFontFamilyCount(); ++i) {
DirectWriteScope<IDWriteFontFamily2> fontFamily;
if (SUCCEEDED(fontCollection->GetFontFamily(i, &fontFamily))) {
+ auto registerFamily = [&](const std::pair<QString, QString> &familyAndStyle) {
+ const QString registeredFamily = familyAndStyle.first;
+ if (registeredFamilies.contains(registeredFamily))
+ return;
+ registeredFamilies.insert(registeredFamily);
+
+ qCDebug(lcQpaFonts) << "Registering font family" << registeredFamily;
+ registerFontFamily(registeredFamily);
+ m_populatedFonts.insert(registeredFamily, *fontFamily);
+ fontFamily->AddRef();
+
+ if (registeredFamily == defaultFontName
+ && defaultFontName != systemDefaultFontName) {
+ qCDebug(lcQpaFonts) << "Adding default font" << systemDefaultFontName
+ << "as alternative to" << registeredFamily;
+
+ m_populatedFonts.insert(systemDefaultFontName, *fontFamily);
+ fontFamily->AddRef();
+ }
+ };
+
QString defaultLocaleName;
QString englishLocaleName;
-
DirectWriteScope<IDWriteLocalizedStrings> names;
if (SUCCEEDED(fontFamily->GetFamilyNames(&names))) {
if (hasDefaultLocale)
defaultLocaleName = localeString(*names, defaultLocale);
-
englishLocaleName = localeString(*names, englishLocale);
}
- qCDebug(lcQpaFonts) << "Registering font, english name = " << englishLocaleName << ", name in current locale = " << defaultLocaleName;
- if (!defaultLocaleName.isEmpty()) {
- registerFontFamily(defaultLocaleName);
- m_populatedFonts.insert(defaultLocaleName, *fontFamily);
- fontFamily->AddRef();
-
- if (defaultLocaleName == defaultFontName && defaultFontName != systemDefaultFontName) {
- qCDebug(lcQpaFonts) << "Adding default font" << systemDefaultFontName << "as alternative to" << defaultLocaleName;
-
- m_populatedFonts.insert(systemDefaultFontName, *fontFamily);
- fontFamily->AddRef();
- }
+ {
+ const auto key = std::make_pair(defaultLocaleName, QString{});
+ if (!defaultLocaleName.isEmpty())
+ registerFamily(key);
}
- if (!englishLocaleName.isEmpty() && englishLocaleName != defaultLocaleName) {
- registerFontFamily(englishLocaleName);
- m_populatedFonts.insert(englishLocaleName, *fontFamily);
- fontFamily->AddRef();
-
- if (englishLocaleName == defaultFontName && defaultFontName != systemDefaultFontName) {
- qCDebug(lcQpaFonts) << "Adding default font" << systemDefaultFontName << "as alternative to" << englishLocaleName;
+ {
+ const auto key = std::make_pair(englishLocaleName, QString{});
+ if (!englishLocaleName.isEmpty())
+ registerFamily(key);
+ }
- m_populatedFonts.insert(systemDefaultFontName, *fontFamily);
- fontFamily->AddRef();
+ for (uint j = 0; j < fontFamily->GetFontCount(); ++j) {
+ DirectWriteScope<IDWriteFont3> font;
+ if (SUCCEEDED(fontFamily->GetFont(j, &font))) {
+ collectAdditionalNames(*font,
+ hasDefaultLocale ? defaultLocale : nullptr,
+ englishLocale,
+ registerFamily);
}
}
}
diff --git a/src/gui/text/windows/qwindowsdirectwritefontdatabase_p.h b/src/gui/text/windows/qwindowsdirectwritefontdatabase_p.h
index 1ea01cbd88e..c8ebdef3561 100644
--- a/src/gui/text/windows/qwindowsdirectwritefontdatabase_p.h
+++ b/src/gui/text/windows/qwindowsdirectwritefontdatabase_p.h
@@ -69,6 +69,12 @@ private:
friend class QWindowsFontEngineDirectWrite;
static QString localeString(IDWriteLocalizedStrings *names, wchar_t localeName[]);
+ template<typename T>
+ static void collectAdditionalNames(T *fontFace,
+ wchar_t *defaultLocale,
+ wchar_t *englishLocale,
+ std::function<void(const std::pair<QString, QString> &)> registerFamily);
+
QSupportedWritingSystems supportedWritingSystems(IDWriteFontFace *face) const;
QHash<QString, IDWriteFontFamily *> m_populatedFonts;