97void QFreeTypeFontDatabase::addNamedInstancesForFace(
void *face_,
99 const QString &family,
100 const QString &styleName,
101 QFont::Weight weight,
102 QFont::Stretch stretch,
106 const QSupportedWritingSystems &writingSystems,
107 const QByteArray &fileName,
108 const QByteArray &fontData)
110 FT_Face face =
reinterpret_cast<FT_Face>(face_);
116#if (FREETYPE_MAJOR*10000
+ FREETYPE_MINOR*100
+ FREETYPE_PATCH) >= 20900
117 FT_MM_Var *var =
nullptr;
118 FT_Get_MM_Var(face, &var);
119 if (var !=
nullptr) {
120 std::unique_ptr<FT_MM_Var,
void(*)(FT_MM_Var*)> varGuard(var, [](FT_MM_Var *res) {
121 FT_Done_MM_Var(qt_getFreetype(), res);
124 QMultiHash<FT_UInt, QString> instanceNamesForId;
125 FT_UInt count = FT_Get_Sfnt_Name_Count(face);
126 for (FT_UInt j = 0; j < count; ++j) {
128 if (FT_Get_Sfnt_Name(face, j, &name))
132 const bool isUtf16 = (name.platform_id == TT_PLATFORM_MICROSOFT
133 && (name.encoding_id == TT_MS_ID_UNICODE_CS || name.encoding_id == TT_MS_ID_UCS_4))
134 || name.platform_id == TT_PLATFORM_APPLE_UNICODE;
139 QString instanceName;
140 for (FT_UInt k = 0; k + 1 < name.string_len; k += 2)
141 instanceName += QChar((name.string[k] << 8) + name.string[k + 1]);
143 if (instanceName != styleName)
144 instanceNamesForId.insert(name.name_id, instanceName);
147 for (FT_UInt i = 0; i < var->num_namedstyles; ++i) {
148 const FT_UInt id = var->namedstyle[i].strid;
149 QFont::Weight instanceWeight = weight;
150 QFont::Stretch instanceStretch = stretch;
151 QFont::Style instanceStyle = style;
152 for (FT_UInt axis = 0; axis < var->num_axis; ++axis) {
153 if (var->axis[axis].tag == QFont::Tag(
"wght").value()) {
154 instanceWeight = QFont::Weight(var->namedstyle[i].coords[axis] >> 16);
155 }
else if (var->axis[axis].tag == QFont::Tag(
"wdth").value()) {
156 instanceStretch = QFont::Stretch(var->namedstyle[i].coords[axis] >> 16);
157 }
else if (var->axis[axis].tag == QFont::Tag(
"ital").value()) {
158 FT_UInt ital = var->namedstyle[i].coords[axis] >> 16;
160 instanceStyle = QFont::StyleItalic;
162 instanceStyle = QFont::StyleNormal;
166 const auto [begin, end] = std::as_const(instanceNamesForId).equal_range(id);
167 for (
auto it = begin; it != end; ++it) {
168 const QString &instanceName = it.value();
170 FontFile *variantFontFile =
new FontFile{
171 QFile::decodeName(fileName),
177 qCDebug(lcFontDb) <<
"Registering named instance" << i
178 <<
":" << instanceName
179 <<
"for font family" << family
180 <<
"with weight" << instanceWeight
181 <<
", style" << instanceStyle
182 <<
", stretch" << instanceStretch;
207 Q_UNUSED(fixedPitch);
208 Q_UNUSED(writingSystems);
214QStringList QFreeTypeFontDatabase::addTTFile(
const QByteArray &fontData,
const QByteArray &file, QFontDatabasePrivate::ApplicationFont *applicationFont)
216 FT_Library library = qt_getFreetype();
220 QStringList families;
224 if (!fontData.isEmpty()) {
225 error = FT_New_Memory_Face(library, (
const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
227 error = FT_New_Face(library, file.constData(), index, &face);
229 if (error != FT_Err_Ok) {
230 qDebug() <<
"FT_New_Face failed with index" << index <<
':' << Qt::hex << error;
233 numFaces = face->num_faces;
235#if (FREETYPE_MAJOR*10000
+ FREETYPE_MINOR*100
+ FREETYPE_PATCH) >= 20501
236 bool isColor = FT_HAS_COLOR(face);
238 bool isColor =
false;
241 QFont::Weight weight = QFont::Normal;
243 QFont::Style style = QFont::StyleNormal;
244 if (face->style_flags & FT_STYLE_FLAG_ITALIC)
245 style = QFont::StyleItalic;
247 if (face->style_flags & FT_STYLE_FLAG_BOLD)
248 weight = QFont::Bold;
250 bool fixedPitch = (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH);
251 QSupportedWritingSystems writingSystems;
253 for (
int i = 0; i < face->num_charmaps; ++i) {
254 FT_CharMap cm = face->charmaps[i];
255 if (cm->encoding == FT_ENCODING_ADOBE_CUSTOM
256 || cm->encoding == FT_ENCODING_MS_SYMBOL) {
257 writingSystems.setSupported(QFontDatabase::Symbol);
262 QFont::Stretch stretch = QFont::Unstretched;
263 TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
265 quint32 unicodeRange[4] = {
266 quint32(os2->ulUnicodeRange1),
267 quint32(os2->ulUnicodeRange2),
268 quint32(os2->ulUnicodeRange3),
269 quint32(os2->ulUnicodeRange4)
271 quint32 codePageRange[2] = {
272 quint32(os2->ulCodePageRange1),
273 quint32(os2->ulCodePageRange2)
276 writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
278 if (os2->usWeightClass) {
279 weight =
static_cast<QFont::Weight>(os2->usWeightClass);
280 }
else if (os2->panose[2]) {
281 int w = os2->panose[2];
283 weight = QFont::Thin;
285 weight = QFont::ExtraLight;
287 weight = QFont::Light;
289 weight = QFont::Normal;
291 weight = QFont::Medium;
293 weight = QFont::DemiBold;
295 weight = QFont::Bold;
297 weight = QFont::ExtraBold;
299 weight = QFont::Black;
302 switch (os2->usWidthClass) {
304 stretch = QFont::UltraCondensed;
307 stretch = QFont::ExtraCondensed;
310 stretch = QFont::Condensed;
313 stretch = QFont::SemiCondensed;
316 stretch = QFont::Unstretched;
319 stretch = QFont::SemiExpanded;
322 stretch = QFont::Expanded;
325 stretch = QFont::ExtraExpanded;
328 stretch = QFont::UltraExpanded;
333 QString family = QString::fromLatin1(face->family_name);
334 FontFile *fontFile =
new FontFile{
335 QFile::decodeName(file),
341 QString styleName = QString::fromLatin1(face->style_name);
343 if (applicationFont !=
nullptr) {
344 QFontDatabasePrivate::ApplicationFont::Properties properties;
345 properties.familyName = family;
346 properties.styleName = styleName;
347 properties.weight = weight;
348 properties.stretch = stretch;
349 properties.style = style;
351 applicationFont->properties.append(properties);
354 registerFont(family, styleName, QString(), weight, style, stretch,
true,
true, 0, fixedPitch, isColor, writingSystems, fontFile);
356 addNamedInstancesForFace(face, index, family, styleName, weight, stretch, style, fixedPitch, isColor, writingSystems, file, fontData);
358 families.append(family);
362 }
while (index < numFaces);