Freetype on Windows: Detect system color fonts

For populating the freetype font database on Windows, we're using
GDI, which does not support color fonts. Therefore we were
registering all system fonts as monochrome, which was okay, because
our Freetype backend did not actually support the color font format
used on Windows.

Since 29a1c57183958b3951db4e7ba9504918a3caa761 we now support COLR
fonts, so they should be added with the correct properties.

Since GDI does not provide this information, we create a temporary
freetype face from the font file when resolving the family during
matching.

Fixes: QTBUG-132255
Change-Id: Ib62632de7fe8d9dc533abe4ae2368090a382cca7
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 81e596c24fc106439ce4135478a2d18d23fdbaac)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2025-01-16 10:34:33 +01:00 committed by Qt Cherry-pick Bot
parent bbcf5a4191
commit 5441057cc1

View File

@ -133,6 +133,23 @@ static const FontKey *findFontKey(const QString &name, int *indexIn = nullptr)
return nullptr;
}
static bool detectColorFont(const QByteArray &filename)
{
#if defined(FT_HAS_COLOR)
FT_Library library = qt_getFreetype();
FT_Face face;
if (FT_New_Face(library, filename.constData(), 0, &face) == FT_Err_Ok) {
bool hasColor = FT_HAS_COLOR(face);
FT_Done_Face(face);
return hasColor;
}
#else
Q_UNUSED(filename);
#endif
return false;
}
static bool addFontToDatabase(QString familyName,
QString styleName,
const QString &fullName,
@ -242,25 +259,27 @@ static bool addFontToDatabase(QString familyName,
if (!QDir::isAbsolutePath(value))
value.prepend(QFile::decodeName(qgetenv("windir") + "\\Fonts\\"));
const bool color = detectColorFont(value.toLocal8Bit());
QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch,
antialias, scalable, size, fixed, false, writingSystems, createFontFile(value, index));
antialias, scalable, size, fixed, color, writingSystems, createFontFile(value, index));
// add fonts windows can generate for us:
if (weight <= QFont::DemiBold && styleName.isEmpty())
QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, style, stretch,
antialias, scalable, size, fixed, false, writingSystems, createFontFile(value, index));
antialias, scalable, size, fixed, color, writingSystems, createFontFile(value, index));
if (style != QFont::StyleItalic && styleName.isEmpty())
QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, weight, QFont::StyleItalic, stretch,
antialias, scalable, size, fixed, false, writingSystems, createFontFile(value, index));
antialias, scalable, size, fixed, color, writingSystems, createFontFile(value, index));
if (weight <= QFont::DemiBold && style != QFont::StyleItalic && styleName.isEmpty())
QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, QFont::StyleItalic, stretch,
antialias, scalable, size, fixed, false, writingSystems, createFontFile(value, index));
antialias, scalable, size, fixed, color, writingSystems, createFontFile(value, index));
if (!subFamilyName.isEmpty() && familyName != subFamilyName) {
QPlatformFontDatabase::registerFont(subFamilyName, subFamilyStyle, foundryName, weight,
style, stretch, antialias, scalable, size, fixed, false, writingSystems, createFontFile(value, index));
style, stretch, antialias, scalable, size, fixed, color, writingSystems, createFontFile(value, index));
}
if (!englishName.isEmpty() && englishName != familyName)