96void QFreeTypeFontDatabase::addNamedInstancesForFace(
void *face_,
98 const QString &family,
99 const QString &styleName,
100 QFont::Weight weight,
101 QFont::Stretch stretch,
105 const QSupportedWritingSystems &writingSystems,
106 const QByteArray &fileName,
107 const QByteArray &fontData)
109 FT_Face face =
reinterpret_cast<FT_Face>(face_);
115#if (FREETYPE_MAJOR*10000
+ FREETYPE_MINOR*100
+ FREETYPE_PATCH) >= 20900
116 FT_MM_Var *var =
nullptr;
117 FT_Get_MM_Var(face, &var);
118 if (var !=
nullptr) {
119 std::unique_ptr<FT_MM_Var,
void(*)(FT_MM_Var*)> varGuard(var, [](FT_MM_Var *res) {
120 FT_Done_MM_Var(qt_getFreetype(), res);
123 for (FT_UInt i = 0; i < var->num_namedstyles; ++i) {
124 FT_UInt id = var->namedstyle[i].strid;
126 QFont::Weight instanceWeight = weight;
127 QFont::Stretch instanceStretch = stretch;
128 QFont::Style instanceStyle = style;
129 for (FT_UInt axis = 0; axis < var->num_axis; ++axis) {
130 if (var->axis[axis].tag == QFont::Tag(
"wght").value()) {
131 instanceWeight = QFont::Weight(var->namedstyle[i].coords[axis] >> 16);
132 }
else if (var->axis[axis].tag == QFont::Tag(
"wdth").value()) {
133 instanceStretch = QFont::Stretch(var->namedstyle[i].coords[axis] >> 16);
134 }
else if (var->axis[axis].tag == QFont::Tag(
"ital").value()) {
135 FT_UInt ital = var->namedstyle[i].coords[axis] >> 16;
137 instanceStyle = QFont::StyleItalic;
139 instanceStyle = QFont::StyleNormal;
143 FT_UInt count = FT_Get_Sfnt_Name_Count(face);
144 for (FT_UInt j = 0; j < count; ++j) {
146 if (FT_Get_Sfnt_Name(face, j, &name))
149 if (name.name_id != id)
153 if (name.encoding_id != TT_MS_ID_UNICODE_CS)
157 QString instanceName;
158 for (FT_UInt k = 0; k < name.string_len; k += 2)
159 instanceName += QChar((name.string[k] << 8) + name.string[k + 1]);
160 if (instanceName != styleName) {
161 FontFile *variantFontFile =
new FontFile{
162 QFile::decodeName(fileName),
168 qCDebug(lcFontDb) <<
"Registering named instance" << i
169 <<
":" << instanceName
170 <<
"for font family" << family
171 <<
"with weight" << instanceWeight
172 <<
", style" << instanceStyle
173 <<
", stretch" << instanceStretch;
199 Q_UNUSED(fixedPitch);
200 Q_UNUSED(writingSystems);
206QStringList QFreeTypeFontDatabase::addTTFile(
const QByteArray &fontData,
const QByteArray &file, QFontDatabasePrivate::ApplicationFont *applicationFont)
208 FT_Library library = qt_getFreetype();
212 QStringList families;
216 if (!fontData.isEmpty()) {
217 error = FT_New_Memory_Face(library, (
const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
219 error = FT_New_Face(library, file.constData(), index, &face);
221 if (error != FT_Err_Ok) {
222 qDebug() <<
"FT_New_Face failed with index" << index <<
':' << Qt::hex << error;
225 numFaces = face->num_faces;
227#if (FREETYPE_MAJOR*10000
+ FREETYPE_MINOR*100
+ FREETYPE_PATCH) >= 20501
228 bool isColor = FT_HAS_COLOR(face);
230 bool isColor =
false;
233 QFont::Weight weight = QFont::Normal;
235 QFont::Style style = QFont::StyleNormal;
236 if (face->style_flags & FT_STYLE_FLAG_ITALIC)
237 style = QFont::StyleItalic;
239 if (face->style_flags & FT_STYLE_FLAG_BOLD)
240 weight = QFont::Bold;
242 bool fixedPitch = (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH);
243 QSupportedWritingSystems writingSystems;
245 for (
int i = 0; i < face->num_charmaps; ++i) {
246 FT_CharMap cm = face->charmaps[i];
247 if (cm->encoding == FT_ENCODING_ADOBE_CUSTOM
248 || cm->encoding == FT_ENCODING_MS_SYMBOL) {
249 writingSystems.setSupported(QFontDatabase::Symbol);
254 QFont::Stretch stretch = QFont::Unstretched;
255 TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
257 quint32 unicodeRange[4] = {
258 quint32(os2->ulUnicodeRange1),
259 quint32(os2->ulUnicodeRange2),
260 quint32(os2->ulUnicodeRange3),
261 quint32(os2->ulUnicodeRange4)
263 quint32 codePageRange[2] = {
264 quint32(os2->ulCodePageRange1),
265 quint32(os2->ulCodePageRange2)
268 writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
270 if (os2->usWeightClass) {
271 weight =
static_cast<QFont::Weight>(os2->usWeightClass);
272 }
else if (os2->panose[2]) {
273 int w = os2->panose[2];
275 weight = QFont::Thin;
277 weight = QFont::ExtraLight;
279 weight = QFont::Light;
281 weight = QFont::Normal;
283 weight = QFont::Medium;
285 weight = QFont::DemiBold;
287 weight = QFont::Bold;
289 weight = QFont::ExtraBold;
291 weight = QFont::Black;
294 switch (os2->usWidthClass) {
296 stretch = QFont::UltraCondensed;
299 stretch = QFont::ExtraCondensed;
302 stretch = QFont::Condensed;
305 stretch = QFont::SemiCondensed;
308 stretch = QFont::Unstretched;
311 stretch = QFont::SemiExpanded;
314 stretch = QFont::Expanded;
317 stretch = QFont::ExtraExpanded;
320 stretch = QFont::UltraExpanded;
325 QString family = QString::fromLatin1(face->family_name);
326 FontFile *fontFile =
new FontFile{
327 QFile::decodeName(file),
333 QString styleName = QString::fromLatin1(face->style_name);
335 if (applicationFont !=
nullptr) {
336 QFontDatabasePrivate::ApplicationFont::Properties properties;
337 properties.familyName = family;
338 properties.styleName = styleName;
339 properties.weight = weight;
340 properties.stretch = stretch;
341 properties.style = style;
343 applicationFont->properties.append(properties);
346 registerFont(family, styleName, QString(), weight, style, stretch,
true,
true, 0, fixedPitch, isColor, writingSystems, fontFile);
348 addNamedInstancesForFace(face, index, family, styleName, weight, stretch, style, fixedPitch, isColor, writingSystems, file, fontData);
350 families.append(family);
354 }
while (index < numFaces);