8#include <QtCore/qendian.h>
9#include <QtCore/qfile.h>
10#include <QtCore/qstringbuilder.h>
11#include <QtCore/qvarlengtharray.h>
23 qCDebug(lcQpaFonts) <<
"Creating DirectWrite database";
28 for (
auto it = m_populatedFonts.
begin();
it != m_populatedFonts.
end(); ++
it)
29 it.value()->Release();
32QString QWindowsDirectWriteFontDatabase::localeString(IDWriteLocalizedStrings *
names,
37 if (SUCCEEDED(
names->FindLocaleName(localeName, &
index, &exists)) && exists) {
82 auto it = m_populatedFonts.
find(familyName);
83 IDWriteFontFamily *fontFamily =
it != m_populatedFonts.
end() ?
it.value() :
nullptr;
84 if (fontFamily ==
nullptr) {
85 qCWarning(lcQpaFonts) <<
"Cannot find" << familyName <<
"in list of fonts";
89 qCDebug(lcQpaFonts) <<
"Populate family:" << familyName;
91 wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
92 bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
93 wchar_t englishLocale[] = L
"en-us";
97 const bool scalable =
true;
98 const bool antialias =
false;
101 IDWriteFontList *matchingFonts;
102 if (SUCCEEDED(fontFamily->GetMatchingFonts(DWRITE_FONT_WEIGHT_REGULAR,
103 DWRITE_FONT_STRETCH_NORMAL,
104 DWRITE_FONT_STYLE_NORMAL,
106 for (
uint j = 0;
j < matchingFonts->GetFontCount(); ++
j) {
108 if (SUCCEEDED(matchingFonts->GetFont(
j, &
font))) {
109 IDWriteFont1 *font1 =
nullptr;
110 if (!SUCCEEDED(
font->QueryInterface(__uuidof(IDWriteFont1),
111 reinterpret_cast<void **
>(&font1)))) {
112 qCWarning(lcQpaFonts) <<
"COM object does not support IDWriteFont1";
116 QString defaultLocaleFamilyName;
117 QString englishLocaleFamilyName;
119 IDWriteFontFamily *fontFamily2;
120 if (SUCCEEDED(font1->GetFontFamily(&fontFamily2))) {
121 IDWriteLocalizedStrings *
names;
122 if (SUCCEEDED(fontFamily2->GetFamilyNames(&
names))) {
123 defaultLocaleFamilyName = hasDefaultLocale ? localeString(
names, defaultLocale) :
QString();
124 englishLocaleFamilyName = localeString(
names, englishLocale);
129 fontFamily2->Release();
132 if (defaultLocaleFamilyName.
isEmpty() && englishLocaleFamilyName.
isEmpty())
133 englishLocaleFamilyName = familyName;
136 IDWriteLocalizedStrings *
names;
137 if (SUCCEEDED(font1->GetFaceNames(&
names))) {
138 QString defaultLocaleStyleName = hasDefaultLocale ? localeString(
names, defaultLocale) :
QString();
139 QString englishLocaleStyleName = localeString(
names, englishLocale);
144 bool fixed = font1->IsMonospacedFont();
146 qCDebug(lcQpaFonts) <<
"Family" << familyName <<
"has english variant" << englishLocaleStyleName <<
", in default locale:" << defaultLocaleStyleName << stretch << style <<
weight << fixed;
148 IDWriteFontFace *
face =
nullptr;
149 if (SUCCEEDED(
font->CreateFontFace(&
face))) {
152 const void *tableData =
nullptr;
154 void *tableContext =
nullptr;
161 if (SUCCEEDED(hr) && exists) {
165 hr = font1->GetUnicodeRanges(0,
nullptr, &rangeCount);
167 if (rangeCount > 0) {
170 hr = font1->GetUnicodeRanges(rangeCount, ranges.
data(), &rangeCount);
172 for (
uint i = 0;
i < rangeCount; ++
i) {
182 qCWarning(lcQpaFonts) <<
"Failed to get unicode ranges for font" << englishLocaleFamilyName << englishLocaleStyleName <<
":" << errorString;
187 if (!englishLocaleStyleName.
isEmpty() || defaultLocaleStyleName.
isEmpty()) {
188 qCDebug(lcQpaFonts) <<
"Font" << englishLocaleFamilyName << englishLocaleStyleName <<
"supports writing systems:" << writingSystems;
190 QPlatformFontDatabase::registerFont(englishLocaleFamilyName, englishLocaleStyleName,
QString(),
weight, style, stretch, antialias, scalable,
size, fixed, writingSystems,
face);
194 if (!defaultLocaleFamilyName.
isEmpty() && defaultLocaleFamilyName != englishLocaleFamilyName) {
195 QPlatformFontDatabase::registerFont(defaultLocaleFamilyName, defaultLocaleStyleName,
QString(),
weight, style, stretch, antialias, scalable,
size, fixed, writingSystems,
face);
211 matchingFonts->Release();
217 IDWriteFontFace *
face =
reinterpret_cast<IDWriteFontFace *
>(
handle);
233 qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
252 IDWriteFontFace *
face = createDirectWriteFace(loadedData);
253 if (
face ==
nullptr) {
254 qCWarning(lcQpaFonts) <<
"Failed to create DirectWrite face from font data. Font may be unsupported.";
258 wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
259 bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
260 wchar_t englishLocale[] = L
"en-us";
264 const bool scalable =
true;
265 const bool antialias =
false;
273 IDWriteFontFace3 *face3 =
nullptr;
274 if (SUCCEEDED(
face->QueryInterface(__uuidof(IDWriteFontFace3),
275 reinterpret_cast<void **
>(&face3)))) {
276 QString defaultLocaleFamilyName;
277 QString englishLocaleFamilyName;
279 IDWriteLocalizedStrings *
names;
280 if (SUCCEEDED(face3->GetFamilyNames(&
names))) {
281 defaultLocaleFamilyName = hasDefaultLocale ? localeString(
names, defaultLocale) :
QString();
282 englishLocaleFamilyName = localeString(
names, englishLocale);
287 QString defaultLocaleStyleName;
288 QString englishLocaleStyleName;
289 if (SUCCEEDED(face3->GetFaceNames(&
names))) {
290 defaultLocaleStyleName = hasDefaultLocale ? localeString(
names, defaultLocale) :
QString();
291 englishLocaleStyleName = localeString(
names, englishLocale);
299 bool fixed = face3->IsMonospacedFont();
301 qCDebug(lcQpaFonts) <<
"\tFont names:" << englishLocaleFamilyName <<
", " << defaultLocaleFamilyName
302 <<
", style names:" << englishLocaleStyleName <<
", " << defaultLocaleStyleName
303 <<
", stretch:" << stretch
304 <<
", style:" << style
306 <<
", fixed:" << fixed;
308 if (!englishLocaleFamilyName.
isEmpty()) {
309 if (applicationFont !=
nullptr) {
313 properties.familyName = englishLocaleFamilyName;
314 properties.styleName = englishLocaleStyleName;
318 ret.append(englishLocaleFamilyName);
319 QPlatformFontDatabase::registerFont(englishLocaleFamilyName, englishLocaleStyleName,
QString(),
weight, style, stretch, antialias, scalable,
size, fixed, writingSystems,
face);
323 if (!defaultLocaleFamilyName.
isEmpty() && defaultLocaleFamilyName != englishLocaleFamilyName) {
324 if (applicationFont !=
nullptr) {
328 properties.familyName = englishLocaleFamilyName;
329 properties.styleName = englishLocaleStyleName;
333 ret.append(defaultLocaleFamilyName);
334 QPlatformFontDatabase::registerFont(defaultLocaleFamilyName, defaultLocaleStyleName,
QString(),
weight, style, stretch, antialias, scalable,
size, fixed, writingSystems,
face);
340 qCWarning(lcQpaFonts) <<
"Unable to query IDWriteFontFace3 interface from font face.";
350 IDWriteFontFace *
face =
reinterpret_cast<IDWriteFontFace *
>(
handle);
367 wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
368 bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
369 wchar_t englishLocale[] = L
"en-us";
374 IDWriteFontCollection *fontCollection;
375 if (SUCCEEDED(
data()->directWriteFactory->GetSystemFontCollection(&fontCollection))) {
376 for (
uint i = 0;
i < fontCollection->GetFontFamilyCount(); ++
i) {
377 IDWriteFontFamily *fontFamily;
378 if (SUCCEEDED(fontCollection->GetFontFamily(
i, &fontFamily))) {
382 IDWriteLocalizedStrings *
names;
383 if (SUCCEEDED(fontFamily->GetFamilyNames(&
names))) {
384 if (hasDefaultLocale)
385 defaultLocaleName = localeString(
names, defaultLocale);
387 englishLocaleName = localeString(
names, englishLocale);
390 qCDebug(lcQpaFonts) <<
"Registering font, english name = " << englishLocaleName <<
", name in current locale = " << defaultLocaleName;
391 if (!defaultLocaleName.
isEmpty()) {
393 m_populatedFonts.
insert(defaultLocaleName, fontFamily);
394 fontFamily->AddRef();
396 if (defaultLocaleName == defaultFontName && defaultFontName != systemDefaultFontName) {
397 qDebug(lcQpaFonts) <<
"Adding default font" << systemDefaultFontName <<
"as alternative to" << defaultLocaleName;
399 m_populatedFonts.
insert(systemDefaultFontName, fontFamily);
400 fontFamily->AddRef();
404 if (!englishLocaleName.
isEmpty() && englishLocaleName != defaultLocaleName) {
406 m_populatedFonts.
insert(englishLocaleName, fontFamily);
407 fontFamily->AddRef();
409 if (englishLocaleName == defaultFontName && defaultFontName != systemDefaultFontName) {
410 qDebug(lcQpaFonts) <<
"Adding default font" << systemDefaultFontName <<
"as alternative to" << englishLocaleName;
412 m_populatedFonts.
insert(systemDefaultFontName, fontFamily);
413 fontFamily->AddRef();
417 fontFamily->Release();
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Script script() const noexcept
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
WritingSystem
\value Any \value Latin \value Greek \value Cyrillic \value Armenian \value Hebrew \value Arabic \val...
StyleHint
Style hints are used by the \l{QFont}{font matching} algorithm to find an appropriate default family ...
QStringList families() const
Stretch
Predefined stretch values that follow the CSS naming convention.
Weight
Qt uses a weighting scale from 1 to 1000 compatible with OpenType.
Style
This enum describes the different styles of glyphs that are used to display text.
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
The QSupportedWritingSystems class is used when registering fonts with the internal Qt fontdatabase.
void setSupported(QFontDatabase::WritingSystem, bool supported=true)
Sets or clears support for the specified writingSystem based on the value given by support.
const T & at(qsizetype idx) const
void populateFontDatabase() override
This function is called once at startup by Qt's internal font database.
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *font=nullptr) override
Adds an application font described by the font contained supplied fontData or using the font containe...
void releaseHandle(void *handle) override
Releases the specified font handle.
QFontEngine * fontEngine(const QFontDef &fontDef, void *handle) override
Returns the font engine that can be used to render the font described by the font definition,...
QWindowsDirectWriteFontDatabase()
~QWindowsDirectWriteFontDatabase() override
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override
Returns a list of alternative fonts for the specified family and style and script using the styleHint...
QFont defaultFont() const override
Returns the default system font.
void populateFamily(const QString &familyName) override
This function is called whenever a lazily populated family, populated through registerFontFamily(),...
bool isPrivateFontFamily(const QString &family) const override
Returns true if the font family is private.
bool fontsAlwaysScalable() const override
Return true if all fonts are considered scalable when using this font database.
static QFont systemDefaultFont()
static QStringList extraTryFontsForFamily(const QString &family)
static int defaultVerticalDPI()
static QSharedPointer< QWindowsFontEngineData > data()
static QString familyForStyleHint(QFont::StyleHint styleHint)
Windows font engine using Direct Write.
QSet< QString >::iterator it
Combined button and popup list for selecting options.
static const QCssKnownValue properties[NumProperties - 1]
Q_GUI_EXPORT QFontDatabase::WritingSystem qt_writing_system_for_script(int script)
#define MAKE_TAG(ch1, ch2, ch3, ch4)
Q_DECL_COLD_FUNCTION Q_CORE_EXPORT QString qt_error_string(int errorCode=-1)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLuint64 GLenum void * handle
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLuint GLuint GLfloat weight
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLsizeiptr const void * fontData
#define QStringLiteral(str)
static QFont::Stretch fromDirectWriteStretch(DWRITE_FONT_STRETCH stretch)
static QFont::Weight fromDirectWriteWeight(DWRITE_FONT_WEIGHT weight)
QT_BEGIN_NAMESPACE Q_GUI_EXPORT QFontDatabase::WritingSystem qt_writing_system_for_script(int script)
static QFont::Style fromDirectWriteStyle(DWRITE_FONT_STYLE style)
QList< Properties > properties