Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qfontconfigdatabase.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
7#include <QtGui/private/qfontengine_ft_p.h>
8
9#include <QtCore/QList>
10#include <QtCore/QElapsedTimer>
11#include <QtCore/QFile>
12
13#include <qpa/qplatformnativeinterface.h>
14#include <qpa/qplatformscreen.h>
15#include <qpa/qplatformintegration.h>
16#include <qpa/qplatformservices.h>
17
18#include <QtGui/private/qguiapplication_p.h>
19
20#include <QtGui/qguiapplication.h>
21
22#include <QtCore/private/qduplicatetracker_p.h>
23
24#include <fontconfig/fontconfig.h>
25#if FC_VERSION >= 20402
26#include <fontconfig/fcfreetype.h>
27#endif
28
30
32
33static inline int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper, int qtLower, int qtUpper)
34{
35 return qtLower + ((fcweight - fcLower) * (qtUpper - qtLower)) / (fcUpper - fcLower);
36}
37
38static inline int weightFromFcWeight(int fcweight)
39{
40 // Font Config uses weights from 0 to 215 (the highest enum value) while QFont ranges from
41 // 1 to 1000. The spacing between the values for the enums are uneven so a linear mapping from
42 // Font Config values to Qt would give surprising results. So, we do a piecewise linear
43 // mapping. This ensures that where there is a corresponding enum on both sides (for example
44 // FC_WEIGHT_DEMIBOLD and QFont::DemiBold) we map one to the other but other values map
45 // to intermediate Qt weights.
46
47 if (fcweight <= FC_WEIGHT_THIN)
48 return QFont::Thin;
49 if (fcweight <= FC_WEIGHT_ULTRALIGHT)
50 return mapToQtWeightForRange(fcweight, FC_WEIGHT_THIN, FC_WEIGHT_ULTRALIGHT, QFont::Thin, QFont::ExtraLight);
51 if (fcweight <= FC_WEIGHT_LIGHT)
52 return mapToQtWeightForRange(fcweight, FC_WEIGHT_ULTRALIGHT, FC_WEIGHT_LIGHT, QFont::ExtraLight, QFont::Light);
53 if (fcweight <= FC_WEIGHT_NORMAL)
54 return mapToQtWeightForRange(fcweight, FC_WEIGHT_LIGHT, FC_WEIGHT_NORMAL, QFont::Light, QFont::Normal);
55 if (fcweight <= FC_WEIGHT_MEDIUM)
56 return mapToQtWeightForRange(fcweight, FC_WEIGHT_NORMAL, FC_WEIGHT_MEDIUM, QFont::Normal, QFont::Medium);
57 if (fcweight <= FC_WEIGHT_DEMIBOLD)
58 return mapToQtWeightForRange(fcweight, FC_WEIGHT_MEDIUM, FC_WEIGHT_DEMIBOLD, QFont::Medium, QFont::DemiBold);
59 if (fcweight <= FC_WEIGHT_BOLD)
60 return mapToQtWeightForRange(fcweight, FC_WEIGHT_DEMIBOLD, FC_WEIGHT_BOLD, QFont::DemiBold, QFont::Bold);
61 if (fcweight <= FC_WEIGHT_ULTRABOLD)
62 return mapToQtWeightForRange(fcweight, FC_WEIGHT_BOLD, FC_WEIGHT_ULTRABOLD, QFont::Bold, QFont::ExtraBold);
63 if (fcweight <= FC_WEIGHT_BLACK)
64 return mapToQtWeightForRange(fcweight, FC_WEIGHT_ULTRABOLD, FC_WEIGHT_BLACK, QFont::ExtraBold, QFont::Black);
65 if (fcweight <= FC_WEIGHT_ULTRABLACK)
66 return mapToQtWeightForRange(fcweight, FC_WEIGHT_BLACK, FC_WEIGHT_ULTRABLACK, QFont::Black,
68 return QFONT_WEIGHT_MAX;
69}
70
71static inline int stretchFromFcWidth(int fcwidth)
72{
73 // Font Config enums for width match pretty closely with those used by Qt so just use
74 // Font Config values directly while enforcing the same limits imposed by QFont.
75 const int maxStretch = 4000;
76 int qtstretch;
77 if (fcwidth < 1)
78 qtstretch = 1;
79 else if (fcwidth > maxStretch)
80 qtstretch = maxStretch;
81 else
82 qtstretch = fcwidth;
83
84 return qtstretch;
85}
86
87static const char specialLanguages[][6] = {
88 "", // Unknown
89 "", // Inherited
90 "", // Common
91 "en", // Latin
92 "el", // Greek
93 "ru", // Cyrillic
94 "hy", // Armenian
95 "he", // Hebrew
96 "ar", // Arabic
97 "syr", // Syriac
98 "dv", // Thaana
99 "hi", // Devanagari
100 "bn", // Bengali
101 "pa", // Gurmukhi
102 "gu", // Gujarati
103 "or", // Oriya
104 "ta", // Tamil
105 "te", // Telugu
106 "kn", // Kannada
107 "ml", // Malayalam
108 "si", // Sinhala
109 "th", // Thai
110 "lo", // Lao
111 "bo", // Tibetan
112 "my", // Myanmar
113 "ka", // Georgian
114 "ko", // Hangul
115 "am", // Ethiopic
116 "chr", // Cherokee
117 "cr", // CanadianAboriginal
118 "sga", // Ogham
119 "non", // Runic
120 "km", // Khmer
121 "mn", // Mongolian
122 "ja", // Hiragana
123 "ja", // Katakana
124 "zh-TW", // Bopomofo
125 "", // Han
126 "ii", // Yi
127 "ett", // OldItalic
128 "got", // Gothic
129 "en", // Deseret
130 "fil", // Tagalog
131 "hnn", // Hanunoo
132 "bku", // Buhid
133 "tbw", // Tagbanwa
134 "cop", // Coptic
135 "lif", // Limbu
136 "tdd", // TaiLe
137 "grc", // LinearB
138 "uga", // Ugaritic
139 "en", // Shavian
140 "so", // Osmanya
141 "grc", // Cypriot
142 "", // Braille
143 "bug", // Buginese
144 "khb", // NewTaiLue
145 "cu", // Glagolitic
146 "shi", // Tifinagh
147 "syl", // SylotiNagri
148 "peo", // OldPersian
149 "pra", // Kharoshthi
150 "ban", // Balinese
151 "akk", // Cuneiform
152 "phn", // Phoenician
153 "lzh", // PhagsPa
154 "man", // Nko
155 "su", // Sundanese
156 "lep", // Lepcha
157 "sat", // OlChiki
158 "vai", // Vai
159 "saz", // Saurashtra
160 "eky", // KayahLi
161 "rej", // Rejang
162 "xlc", // Lycian
163 "xcr", // Carian
164 "xld", // Lydian
165 "cjm", // Cham
166 "nod", // TaiTham
167 "blt", // TaiViet
168 "ae", // Avestan
169 "egy", // EgyptianHieroglyphs
170 "smp", // Samaritan
171 "lis", // Lisu
172 "bax", // Bamum
173 "jv", // Javanese
174 "mni", // MeeteiMayek
175 "arc", // ImperialAramaic
176 "xsa", // OldSouthArabian
177 "xpr", // InscriptionalParthian
178 "pal", // InscriptionalPahlavi
179 "otk", // OldTurkic
180 "bh", // Kaithi
181 "bbc", // Batak
182 "pra", // Brahmi
183 "myz", // Mandaic
184 "ccp", // Chakma
185 "xmr", // MeroiticCursive
186 "xmr", // MeroiticHieroglyphs
187 "hmd", // Miao
188 "sa", // Sharada
189 "srb", // SoraSompeng
190 "doi", // Takri
191 "lez", // CaucasianAlbanian
192 "bsq", // BassaVah
193 "fr", // Duployan
194 "sq", // Elbasan
195 "sa", // Grantha
196 "hnj", // PahawhHmong
197 "sd", // Khojki
198 "lab", // LinearA
199 "hi", // Mahajani
200 "xmn", // Manichaean
201 "men", // MendeKikakui
202 "mr", // Modi
203 "mru", // Mro
204 "xna", // OldNorthArabian
205 "arc", // Nabataean
206 "arc", // Palmyrene
207 "ctd", // PauCinHau
208 "kv", // OldPermic
209 "pal", // PsalterPahlavi
210 "sa", // Siddham
211 "sd", // Khudawadi
212 "mai", // Tirhuta
213 "hoc", // WarangCiti
214 "", // Ahom
215 "", // AnatolianHieroglyphs
216 "", // Hatran
217 "", // Multani
218 "", // OldHungarian
219 "", // SignWriting
220 "", // Adlam
221 "", // Bhaiksuki
222 "", // Marchen
223 "", // Newa
224 "", // Osage
225 "", // Tangut
226 "", // MasaramGondi
227 "", // Nushu
228 "", // Soyombo
229 "", // ZanabazarSquare
230 "", // Dogra
231 "", // GunjalaGondi
232 "", // HanifiRohingya
233 "", // Makasar
234 "", // Medefaidrin
235 "", // OldSogdian
236 "", // Sogdian
237 "", // Elymaic
238 "", // Nandinagari
239 "", // NyiakengPuachueHmong
240 "", // Wancho
241 "", // Chorasmian
242 "", // DivesAkuru
243 "", // KhitanSmallScript
244 "", // Yezidi
245 "", // CyproMinoan
246 "", // OldUyghur
247 "", // Tangsa
248 "", // Toto
249 "", // Vithkuqi
250 "", // Kawi
251 "", // NagMundari
252};
253static_assert(sizeof specialLanguages / sizeof *specialLanguages == QChar::ScriptCount);
254
255// this could become a list of all languages used for each writing
256// system, instead of using the single most common language.
257static const char languageForWritingSystem[][6] = {
258 "", // Any
259 "en", // Latin
260 "el", // Greek
261 "ru", // Cyrillic
262 "hy", // Armenian
263 "he", // Hebrew
264 "ar", // Arabic
265 "syr", // Syriac
266 "div", // Thaana
267 "hi", // Devanagari
268 "bn", // Bengali
269 "pa", // Gurmukhi
270 "gu", // Gujarati
271 "or", // Oriya
272 "ta", // Tamil
273 "te", // Telugu
274 "kn", // Kannada
275 "ml", // Malayalam
276 "si", // Sinhala
277 "th", // Thai
278 "lo", // Lao
279 "bo", // Tibetan
280 "my", // Myanmar
281 "ka", // Georgian
282 "km", // Khmer
283 "zh-cn", // SimplifiedChinese
284 "zh-tw", // TraditionalChinese
285 "ja", // Japanese
286 "ko", // Korean
287 "vi", // Vietnamese
288 "", // Symbol
289 "sga", // Ogham
290 "non", // Runic
291 "man" // N'Ko
292};
294
295#if FC_VERSION >= 20297
296// Newer FontConfig let's us sort out fonts that report certain scripts support,
297// but no open type tables for handling them correctly.
298// Check the reported script presence in the FC_CAPABILITY's "otlayout:" section.
299static const char capabilityForWritingSystem[][5] = {
300 "", // Any
301 "", // Latin
302 "", // Greek
303 "", // Cyrillic
304 "", // Armenian
305 "", // Hebrew
306 "", // Arabic
307 "syrc", // Syriac
308 "thaa", // Thaana
309 "deva", // Devanagari
310 "beng", // Bengali
311 "guru", // Gurmukhi
312 "gujr", // Gujarati
313 "orya", // Oriya
314 "taml", // Tamil
315 "telu", // Telugu
316 "knda", // Kannada
317 "mlym", // Malayalam
318 "sinh", // Sinhala
319 "", // Thai
320 "", // Lao
321 "tibt", // Tibetan
322 "mymr", // Myanmar
323 "", // Georgian
324 "khmr", // Khmer
325 "", // SimplifiedChinese
326 "", // TraditionalChinese
327 "", // Japanese
328 "", // Korean
329 "", // Vietnamese
330 "", // Symbol
331 "", // Ogham
332 "", // Runic
333 "nko " // N'Ko
334};
335static_assert(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount);
336#endif
337
338static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
339{
340 const char *stylehint = nullptr;
341 switch (style) {
342 case QFont::SansSerif:
343 stylehint = "sans-serif";
344 break;
345 case QFont::Serif:
346 stylehint = "serif";
347 break;
349 case QFont::Monospace:
350 stylehint = "monospace";
351 break;
352 case QFont::Cursive:
353 stylehint = "cursive";
354 break;
355 case QFont::Fantasy:
356 stylehint = "fantasy";
357 break;
358 default:
359 break;
360 }
361 return stylehint;
362}
363
364static inline bool requiresOpenType(int writingSystem)
365{
366 return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
367 || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
368}
369
371 QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr,
372 FT_Face face = nullptr,
373 QFontconfigDatabase *db = nullptr)
374{
375 QString familyName;
376 QString familyNameLang;
377 FcChar8 *value = nullptr;
378 int weight_value;
379 int slant_value;
380 int spacing_value;
381 int width_value;
382 FcChar8 *file_value;
383 int indexValue;
384 FcChar8 *foundry_value;
385 FcChar8 *style_value;
386 FcBool scalable;
387 FcBool antialias;
388
389 if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) != FcResultMatch)
390 return;
391
392 familyName = QString::fromUtf8((const char *)value);
393
394 if (FcPatternGetString(pattern, FC_FAMILYLANG, 0, &value) == FcResultMatch)
395 familyNameLang = QString::fromUtf8((const char *)value);
396
397 slant_value = FC_SLANT_ROMAN;
398 weight_value = FC_WEIGHT_REGULAR;
399 spacing_value = FC_PROPORTIONAL;
400 file_value = nullptr;
401 indexValue = 0;
402 scalable = FcTrue;
403
404
405 if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant_value) != FcResultMatch)
406 slant_value = FC_SLANT_ROMAN;
407 if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight_value) != FcResultMatch)
408 weight_value = FC_WEIGHT_REGULAR;
409 if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &width_value) != FcResultMatch)
410 width_value = FC_WIDTH_NORMAL;
411 if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing_value) != FcResultMatch)
412 spacing_value = FC_PROPORTIONAL;
413 if (FcPatternGetString(pattern, FC_FILE, 0, &file_value) != FcResultMatch)
414 file_value = nullptr;
415 if (FcPatternGetInteger(pattern, FC_INDEX, 0, &indexValue) != FcResultMatch)
416 indexValue = 0;
417 if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
418 scalable = FcTrue;
419 if (FcPatternGetString(pattern, FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
420 foundry_value = nullptr;
421 if (FcPatternGetString(pattern, FC_STYLE, 0, &style_value) != FcResultMatch)
422 style_value = nullptr;
423 if (FcPatternGetBool(pattern,FC_ANTIALIAS,0,&antialias) != FcResultMatch)
424 antialias = true;
425
426 QSupportedWritingSystems writingSystems;
427 FcLangSet *langset = nullptr;
428 FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
429 if (res == FcResultMatch) {
430 bool hasLang = false;
431#if FC_VERSION >= 20297
432 FcChar8 *cap = nullptr;
433 FcResult capRes = FcResultNoMatch;
434#endif
435 for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
436 const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
437 if (lang) {
438 FcLangResult langRes = FcLangSetHasLang(langset, lang);
439 if (langRes != FcLangDifferentLang) {
440#if FC_VERSION >= 20297
441 if (*capabilityForWritingSystem[j] && requiresOpenType(j)) {
442 if (cap == nullptr)
443 capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap);
444 if (capRes == FcResultMatch && strstr(reinterpret_cast<const char *>(cap), capabilityForWritingSystem[j]) == nullptr)
445 continue;
446 }
447#endif
449 hasLang = true;
450 }
451 }
452 }
453 if (!hasLang)
454 // none of our known languages, add it to the other set
455 writingSystems.setSupported(QFontDatabase::Other);
456 } else {
457 // we set Other to supported for symbol fonts. It makes no
458 // sense to merge these with other ones, as they are
459 // special in a way.
460 writingSystems.setSupported(QFontDatabase::Other);
461 }
462
463 FontFile *fontFile = new FontFile;
464 fontFile->fileName = QString::fromLocal8Bit((const char *)file_value);
465 fontFile->indexValue = indexValue;
466
467 QFont::Style style = (slant_value == FC_SLANT_ITALIC)
469 : ((slant_value == FC_SLANT_OBLIQUE)
472 // Note: weight should really be an int but registerFont incorrectly uses an enum
474
475 double pixel_size = 0;
476 if (!scalable)
477 FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &pixel_size);
478
479 bool fixedPitch = spacing_value >= FC_MONO;
480 // Note: stretch should really be an int but registerFont incorrectly uses an enum
481 QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
482 QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
483
484 if (applicationFont != nullptr) {
486 properties.familyName = familyName;
487 properties.styleName = styleName;
488 properties.weight = weight;
489 properties.style = style;
490 properties.stretch = stretch;
491
492 applicationFont->properties.append(properties);
493 }
494
495 QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1StringView((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
496 if (applicationFont != nullptr && face != nullptr && db != nullptr) {
497 db->addNamedInstancesForFace(face,
498 indexValue,
499 familyName,
500 styleName,
501 weight,
502 stretch,
503 style,
504 fixedPitch,
505 writingSystems,
506 QByteArray((const char*)file_value),
507 applicationFont->data);
508 }
509
510// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
511
512 for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k) {
513 const QString altFamilyName = QString::fromUtf8((const char *)value);
514 // Extra family names can be aliases or subfamilies.
515 // If it is a subfamily, register it as a separate font, so only members of the subfamily are
516 // matched when the subfamily is requested.
517 QString altStyleName;
518 if (FcPatternGetString(pattern, FC_STYLE, k, &value) == FcResultMatch)
519 altStyleName = QString::fromUtf8((const char *)value);
520 else
521 altStyleName = styleName;
522
523 QString altFamilyNameLang;
524 if (FcPatternGetString(pattern, FC_FAMILYLANG, k, &value) == FcResultMatch)
525 altFamilyNameLang = QString::fromUtf8((const char *)value);
526 else
527 altFamilyNameLang = familyNameLang;
528
529 if (familyNameLang == altFamilyNameLang && altStyleName != styleName) {
530 if (applicationFont != nullptr) {
532 properties.familyName = altFamilyName;
533 properties.styleName = altStyleName;
534 properties.weight = weight;
535 properties.style = style;
536 properties.stretch = stretch;
537
538 applicationFont->properties.append(properties);
539 }
540 FontFile *altFontFile = new FontFile(*fontFile);
541 QPlatformFontDatabase::registerFont(altFamilyName, altStyleName, QLatin1StringView((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,altFontFile);
542 } else {
543 QPlatformFontDatabase::registerAliasToFontFamily(familyName, altFamilyName);
544 }
545 }
546
547}
548
549static bool isDprScaling()
550{
551 return !qFuzzyCompare(qApp->devicePixelRatio(), 1.0);
552}
553
555{
556 FcConfigDestroy(FcConfigGetCurrent());
557}
558
560{
561 FcInit();
562 FcFontSet *fonts;
563
564 {
565 FcObjectSet *os = FcObjectSetCreate();
566 FcPattern *pattern = FcPatternCreate();
567 const char *properties [] = {
568 FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
569 FC_SPACING, FC_FILE, FC_INDEX,
570 FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
571 FC_WIDTH, FC_FAMILYLANG,
572#if FC_VERSION >= 20297
573 FC_CAPABILITY,
574#endif
575 (const char *)nullptr
576 };
577 const char **p = properties;
578 while (*p) {
579 FcObjectSetAdd(os, *p);
580 ++p;
581 }
582
583#ifdef FC_VARIABLE
584 /* Support the named instance of Variable Fonts. */
585 FcPatternAddBool(pattern, FC_VARIABLE, FcFalse);
586#endif
587
588 fonts = FcFontList(nullptr, pattern, os);
589 FcObjectSetDestroy(os);
590 FcPatternDestroy(pattern);
591 if (!fonts)
592 return;
593 }
594
595 for (int i = 0; i < fonts->nfont; i++)
596 populateFromPattern(fonts->fonts[i]);
597
598 FcFontSetDestroy (fonts);
599
600 struct FcDefaultFont {
601 const char *qtname;
602 const char *rawname;
603 bool fixed;
604 };
605 const FcDefaultFont defaults[] = {
606 { "Serif", "serif", false },
607 { "Sans Serif", "sans-serif", false },
608 { "Monospace", "monospace", true },
609 { nullptr, nullptr, false }
610 };
611 const FcDefaultFont *f = defaults;
612 // aliases only make sense for 'common', not for any of the specials
614 ws.setSupported(QFontDatabase::Latin);
615
616 while (f->qtname) {
617 QString familyQtName = QString::fromLatin1(f->qtname);
618 registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
619 registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
620 registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
621 ++f;
622 }
623
624 //QPA has very lazy population of the font db. We want it to be initialized when
625 //QApplication is constructed, so that the population procedure can do something like this to
626 //set the default font
627// const FcDefaultFont *s = defaults;
628// QFont font("Sans Serif");
629// font.setPointSize(9);
630// QApplication::setFont(font);
631}
632
634{
635 // Clear app fonts.
636 FcConfigAppFontClear(nullptr);
637}
638
640{
641 return new QFontEngineMultiFontConfig(fontEngine, script);
642}
643
644namespace {
645QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintingPreference, FcPattern *match, bool preferXftConf)
646{
647 switch (hintingPreference) {
655 break;
656 }
657
658 if (isDprScaling())
660
661 void *hintStyleResource =
662 QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
664 int xftHintStyle = int(reinterpret_cast<qintptr>(hintStyleResource));
665 if (preferXftConf && xftHintStyle > 0)
666 return QFontEngine::HintStyle(xftHintStyle - 1);
667
668 int hint_style = 0;
669 if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultMatch) {
670 switch (hint_style) {
671 case FC_HINT_NONE:
673 case FC_HINT_SLIGHT:
675 case FC_HINT_MEDIUM:
677 case FC_HINT_FULL:
679 default:
680 Q_UNREACHABLE();
681 break;
682 }
683 }
684 if (xftHintStyle > 0)
685 return QFontEngine::HintStyle(xftHintStyle - 1);
686
688}
689
690QFontEngine::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match, bool preferXftConf)
691{
692 void *subpixelTypeResource =
693 QGuiApplication::platformNativeInterface()->nativeResourceForScreen("subpixeltype",
695 int xftSubpixelType = int(reinterpret_cast<qintptr>(subpixelTypeResource));
696 if (preferXftConf && xftSubpixelType > 0)
697 return QFontEngine::SubpixelAntialiasingType(xftSubpixelType - 1);
698
699 int subpixel = FC_RGBA_UNKNOWN;
700 if (FcPatternGetInteger(match, FC_RGBA, 0, &subpixel) == FcResultMatch) {
701 switch (subpixel) {
702 case FC_RGBA_UNKNOWN:
703 case FC_RGBA_NONE:
705 case FC_RGBA_RGB:
707 case FC_RGBA_BGR:
709 case FC_RGBA_VRGB:
711 case FC_RGBA_VBGR:
713 default:
714 Q_UNREACHABLE();
715 break;
716 }
717 }
718
719 if (xftSubpixelType > 0)
720 return QFontEngine::SubpixelAntialiasingType(xftSubpixelType - 1);
721
723}
724} // namespace
725
727{
728 if (!usrPtr)
729 return nullptr;
730
731 FontFile *fontfile = static_cast<FontFile *> (usrPtr);
733 fid.filename = QFile::encodeName(fontfile->fileName);
734 fid.index = fontfile->indexValue;
735 fid.instanceIndex = fontfile->instanceIndex;
736 fid.variableAxes = f.variableAxisValues;
737
738 // FIXME: Unify with logic in QFontEngineFT::create()
740 engine->face_id = fid;
741
742 setupFontEngine(engine, f);
743
744 if (!engine->init(fid, engine->antialias, engine->defaultFormat) || engine->invalid()) {
745 delete engine;
746 engine = nullptr;
747 }
748
749 return engine;
750}
751
753{
754 QFontEngineFT *engine = static_cast<QFontEngineFT*>(QFreeTypeFontDatabase::fontEngine(fontData, pixelSize, hintingPreference));
755 if (engine == nullptr)
756 return nullptr;
757
758 setupFontEngine(engine, engine->fontDef);
759
760 return engine;
761}
762
763QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
764{
765 QStringList fallbackFamilies;
766 FcPattern *pattern = FcPatternCreate();
767 if (!pattern)
768 return fallbackFamilies;
769
770 FcValue value;
771 value.type = FcTypeString;
772 const QByteArray cs = family.toUtf8();
773 value.u.s = (const FcChar8 *)cs.data();
774 FcPatternAdd(pattern,FC_FAMILY,value,true);
775
776 int slant_value = FC_SLANT_ROMAN;
777 if (style == QFont::StyleItalic)
778 slant_value = FC_SLANT_ITALIC;
779 else if (style == QFont::StyleOblique)
780 slant_value = FC_SLANT_OBLIQUE;
781 FcPatternAddInteger(pattern, FC_SLANT, slant_value);
782
783 Q_ASSERT(uint(script) < QChar::ScriptCount);
784 if (*specialLanguages[script] != '\0') {
785 FcLangSet *ls = FcLangSetCreate();
786 FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
787 FcPatternAddLangSet(pattern, FC_LANG, ls);
788 FcLangSetDestroy(ls);
789 } else if (!family.isEmpty()) {
790 // If script is Common or Han, then it may include languages like CJK,
791 // we should attach system default language set to the pattern
792 // to obtain correct font fallback list (i.e. if LANG=zh_CN
793 // then we normally want to use a Chinese font for CJK text;
794 // while a Japanese font should be used for that if LANG=ja)
795 FcPattern *dummy = FcPatternCreate();
796 FcDefaultSubstitute(dummy);
797 FcChar8 *lang = nullptr;
798 FcResult res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
799 if (res == FcResultMatch)
800 FcPatternAddString(pattern, FC_LANG, lang);
801 FcPatternDestroy(dummy);
802 }
803
804 const char *stylehint = getFcFamilyForStyleHint(styleHint);
805 if (stylehint) {
806 value.u.s = (const FcChar8 *)stylehint;
807 FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
808 }
809
810 FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
811 FcDefaultSubstitute(pattern);
812
813 FcResult result = FcResultMatch;
814 FcFontSet *fontSet = FcFontSort(nullptr,pattern,FcFalse,nullptr,&result);
815 FcPatternDestroy(pattern);
816
817 if (fontSet) {
818 QDuplicateTracker<QString> duplicates(fontSet->nfont + 1);
819 (void)duplicates.hasSeen(family.toCaseFolded());
820 for (int i = 0; i < fontSet->nfont; i++) {
821 FcChar8 *value = nullptr;
822 if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
823 continue;
824 // capitalize(value);
825 const QString familyName = QString::fromUtf8((const char *)value);
826 const QString familyNameCF = familyName.toCaseFolded();
827 if (!duplicates.hasSeen(familyNameCF)) {
828 fallbackFamilies << familyName;
829 }
830 }
831 FcFontSetDestroy(fontSet);
832 }
833// qDebug() << "fallbackFamilies for:" << family << style << styleHint << script << fallbackFamilies;
834
835 return fallbackFamilies;
836}
837
838static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id, FcBlanks *blanks, int *count, FT_Face *face)
839{
840#if FC_VERSION < 20402
841 Q_UNUSED(data);
842 *face = nullptr;
843 return FcFreeTypeQuery(file, id, blanks, count);
844#else
845 if (data.isEmpty()) {
846 *face = nullptr;
847 return FcFreeTypeQuery(file, id, blanks, count);
848 }
849
850 FT_Library lib = qt_getFreetype();
851
852 FcPattern *pattern = nullptr;
853
854 if (!FT_New_Memory_Face(lib, (const FT_Byte *)data.constData(), data.size(), id, face)) {
855 *count = (*face)->num_faces;
856
857 pattern = FcFreeTypeQueryFace(*face, file, id, blanks);
858 } else {
859 *face = nullptr;
860 }
861
862 return pattern;
863#endif
864}
865
867{
868 QStringList families;
869
870 if (applicationFont != nullptr)
871 applicationFont->properties.clear();
872
873 FcFontSet *set = FcConfigGetFonts(nullptr, FcSetApplication);
874 if (!set) {
875 FcConfigAppFontAddFile(nullptr, (const FcChar8 *)":/non-existent");
876 set = FcConfigGetFonts(nullptr, FcSetApplication); // try again
877 if (!set)
878 return families;
879 }
880
881 int id = 0;
882 FcBlanks *blanks = FcConfigGetBlanks(nullptr);
883 int count = 0;
884
886 do {
887 FT_Face face;
888 pattern = queryFont((const FcChar8 *)QFile::encodeName(fileName).constData(),
889 fontData, id, blanks, &count, &face);
890 if (!pattern)
891 return families;
892
893 FcChar8 *fam = nullptr;
894 if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
895 QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
896 families << family;
897 }
898 populateFromPattern(pattern, applicationFont, face, this);
899
900 if (face)
901 FT_Done_Face(face);
902
903 FcFontSetAdd(set, pattern);
904
905 ++id;
906 } while (id < count);
907
908 return families;
909}
910
912{
914 if (!resolved.isEmpty() && resolved != family)
915 return resolved;
916 FcPattern *pattern = FcPatternCreate();
917 if (!pattern)
918 return family;
919
920 if (!family.isEmpty()) {
921 const QByteArray cs = family.toUtf8();
922 FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) cs.constData());
923 }
924 FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
925 FcDefaultSubstitute(pattern);
926
927 FcChar8 *familyAfterSubstitution = nullptr;
928 FcPatternGetString(pattern, FC_FAMILY, 0, &familyAfterSubstitution);
929 resolved = QString::fromUtf8((const char *) familyAfterSubstitution);
930 FcPatternDestroy(pattern);
931
932 return resolved;
933}
934
936{
937 // Hack to get system default language until FcGetDefaultLangs()
938 // is exported (https://bugs.freedesktop.org/show_bug.cgi?id=32853)
939 // or https://bugs.freedesktop.org/show_bug.cgi?id=35482 is fixed
940 FcPattern *dummy = FcPatternCreate();
941 FcDefaultSubstitute(dummy);
942 FcChar8 *lang = nullptr;
943 FcResult res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
944
945 FcPattern *pattern = FcPatternCreate();
946 if (res == FcResultMatch) {
947 // Make defaultFont pattern matching locale language aware, because
948 // certain FC_LANG based custom rules may happen in FcConfigSubstitute()
949 FcPatternAddString(pattern, FC_LANG, lang);
950 }
951 FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
952 FcDefaultSubstitute(pattern);
953
954 FcChar8 *familyAfterSubstitution = nullptr;
955 FcPatternGetString(pattern, FC_FAMILY, 0, &familyAfterSubstitution);
956 QString resolved = QString::fromUtf8((const char *) familyAfterSubstitution);
957 FcPatternDestroy(pattern);
958 FcPatternDestroy(dummy);
959
960 return QFont(resolved);
961}
962
963void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef &fontDef) const
964{
965 bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
966 bool forcedAntialiasSetting = !antialias || isDprScaling();
967
969 bool preferXftConf = false;
970
971 if (services) {
972 const QList<QByteArray> desktopEnv = services->desktopEnvironment().split(':');
973 preferXftConf = !(desktopEnv.contains("KDE") || desktopEnv.contains("LXQT") || desktopEnv.contains("UKUI"));
974 }
975
977 // try and get the pattern
978 FcPattern *pattern = FcPatternCreate();
979 FcPattern *match = nullptr;
980
981 FcValue value;
982 value.type = FcTypeString;
983 QByteArray cs = fontDef.families.first().toUtf8();
984 value.u.s = (const FcChar8 *)cs.data();
985 FcPatternAdd(pattern,FC_FAMILY,value,true);
986
987 QFontEngine::FaceId fid = engine->faceId();
988
989 if (!fid.filename.isEmpty()) {
990 value.u.s = (const FcChar8 *)fid.filename.data();
991 FcPatternAdd(pattern,FC_FILE,value,true);
992
993 value.type = FcTypeInteger;
994 value.u.i = fid.index;
995 FcPatternAdd(pattern,FC_INDEX,value,true);
996 }
997
998 if (!qFuzzyIsNull(fontDef.pixelSize))
999 FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontDef.pixelSize);
1000
1001 FcResult result;
1002
1003 FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
1004 FcDefaultSubstitute(pattern);
1005
1006#ifdef FC_VARIABLE
1007 if (!fid.filename.isEmpty()) {
1008 // FC_INDEX is ignored during processing in FcFontMatch.
1009 // So iterate FcPatterns directly and find it out.
1010 FcFontSet *fcsets[2], *fcfs;
1011
1012 fcsets[0] = FcConfigGetFonts(nullptr, FcSetSystem);
1013 fcsets[1] = FcConfigGetFonts(nullptr, FcSetApplication);
1014 for (int nset = 0; nset < 2; nset++) {
1015 fcfs = fcsets[nset];
1016 if (fcfs == nullptr)
1017 continue;
1018 for (int fnum = 0; fnum < fcfs->nfont; fnum++) {
1019 FcPattern *fcpat = fcfs->fonts[fnum];
1020 FcChar8 *fcfile;
1021 FcBool variable;
1022 double fcpixelsize;
1023 int fcindex;
1024
1025 // Skip the variable font itself, only to use the named instances and normal fonts here
1026 if (FcPatternGetBool(fcpat, FC_VARIABLE, 0, &variable) == FcResultMatch &&
1027 variable == FcTrue)
1028 continue;
1029
1030 if (!qFuzzyIsNull(fontDef.pixelSize)) {
1031 if (FcPatternGetDouble(fcpat, FC_PIXEL_SIZE, 0, &fcpixelsize) == FcResultMatch &&
1032 fontDef.pixelSize != fcpixelsize)
1033 continue;
1034 }
1035
1036 if (FcPatternGetString(fcpat, FC_FILE, 0, &fcfile) == FcResultMatch &&
1037 FcPatternGetInteger(fcpat, FC_INDEX, 0, &fcindex) == FcResultMatch) {
1038 QByteArray f = QByteArray::fromRawData((const char *)fcfile,
1039 qstrlen((const char *)fcfile));
1040 if (f == fid.filename && fcindex == fid.index) {
1041 // We found it.
1042 match = FcFontRenderPrepare(nullptr, pattern, fcpat);
1043 goto bail;
1044 }
1045 }
1046 }
1047 }
1048 }
1049bail:
1050#endif
1051
1052 if (!match)
1053 match = FcFontMatch(nullptr, pattern, &result);
1054
1055 int xftAntialias = 0;
1056 if (!forcedAntialiasSetting) {
1057 void *antialiasResource =
1058 QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled",
1060 xftAntialias = int(reinterpret_cast<qintptr>(antialiasResource));
1061 if ((preferXftConf || !match) && xftAntialias > 0) {
1062 antialias = xftAntialias - 1;
1063 forcedAntialiasSetting = true;
1064 }
1065 }
1066 if (match) {
1067 engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)fontDef.hintingPreference, match, preferXftConf));
1068
1069 FcBool fc_autohint;
1070 if (FcPatternGetBool(match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch)
1071 engine->forceAutoHint = fc_autohint;
1072
1073#if defined(FT_LCD_FILTER_H)
1074 int lcdFilter;
1075 if (FcPatternGetInteger(match, FC_LCD_FILTER, 0, &lcdFilter) == FcResultMatch)
1076 engine->lcdFilterType = lcdFilter;
1077#endif
1078
1079 if (!forcedAntialiasSetting) {
1080 FcBool fc_antialias;
1081 if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch)
1082 antialias = fc_antialias;
1083 }
1084
1085 if (antialias) {
1088 subpixelType = subpixelTypeFromMatch(match, preferXftConf);
1089 engine->subpixelType = subpixelType;
1090 }
1091
1092 FcPatternDestroy(match);
1093 } else {
1094 void *hintStyleResource =
1095 QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
1097 int xftHintStyle = int(reinterpret_cast<qintptr>(hintStyleResource));
1098 if (xftHintStyle > 0)
1099 engine->setDefaultHintStyle(QFontEngine::HintStyle(xftHintStyle - 1));
1100 if (antialias) {
1101 engine->subpixelType = QFontEngine::Subpixel_None;
1102 if (!(fontDef.styleStrategy & QFont::NoSubpixelAntialias)) {
1103 void *subpixelTypeResource =
1104 QGuiApplication::platformNativeInterface()->nativeResourceForScreen("subpixeltype",
1106 int xftSubpixelType = int(reinterpret_cast<qintptr>(subpixelTypeResource));
1107 if (xftSubpixelType > 1)
1108 engine->subpixelType = QFontEngine::SubpixelAntialiasingType(xftSubpixelType - 1);
1109 }
1110 }
1111 }
1112 if (antialias) {
1113 format = (engine->subpixelType == QFontEngine::Subpixel_None)
1115 : QFontEngine::Format_A32;
1116 } else {
1118 }
1119
1120 FcPatternDestroy(pattern);
1121
1122 engine->antialias = antialias;
1123 engine->defaultFormat = format;
1124 engine->glyphFormat = format;
1125}
1126
1128{
1129#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 20900
1130 return true;
1131#else
1132 return false;
1133#endif
1134}
1135
std::vector< ObjCStrongReference< CBMutableService > > services
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:611
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:409
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
Definition qfile.h:158
WritingSystem
\value Any \value Latin \value Greek \value Cyrillic \value Armenian \value Hebrew \value Arabic \val...
\reentrant
Definition qfont.h:22
StyleHint
Style hints are used by the \l{QFont}{font matching} algorithm to find an appropriate default family ...
Definition qfont.h:25
@ Monospace
Definition qfont.h:33
@ Serif
Definition qfont.h:27
@ Cursive
Definition qfont.h:32
@ Fantasy
Definition qfont.h:34
@ TypeWriter
Definition qfont.h:28
@ SansSerif
Definition qfont.h:26
HintingPreference
Definition qfont.h:55
@ PreferNoHinting
Definition qfont.h:57
@ PreferFullHinting
Definition qfont.h:59
@ PreferVerticalHinting
Definition qfont.h:58
@ PreferDefaultHinting
Definition qfont.h:56
Stretch
Predefined stretch values that follow the CSS naming convention.
Definition qfont.h:83
@ Unstretched
Definition qfont.h:89
@ NoSubpixelAntialias
Definition qfont.h:48
@ NoAntialias
Definition qfont.h:47
Weight
Qt uses a weighting scale from 1 to 1000 compatible with OpenType.
Definition qfont.h:63
@ DemiBold
Definition qfont.h:69
@ Thin
Definition qfont.h:64
@ ExtraBold
Definition qfont.h:71
@ Black
Definition qfont.h:72
@ Bold
Definition qfont.h:70
@ ExtraLight
Definition qfont.h:65
@ Normal
Definition qfont.h:67
@ Light
Definition qfont.h:66
@ Medium
Definition qfont.h:68
Style
This enum describes the different styles of glyphs that are used to display text.
Definition qfont.h:76
@ StyleItalic
Definition qfont.h:78
@ StyleNormal
Definition qfont.h:77
@ StyleOblique
Definition qfont.h:79
bool supportsVariableApplicationFonts() const override
Returns true if this font database supports loading named instances from variable application fonts.
QFontEngineMulti * fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) override
Returns a multi font engine in the specified script to encapsulate fontEngine with the option to fall...
void populateFontDatabase() override
This function is called once at startup by Qt's internal font database.
QString resolveFontFamilyAlias(const QString &family) const override
Resolve alias to actual font family names.
QFont defaultFont() const override
Returns the default system font.
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont=nullptr) override
Adds an application font described by the font contained supplied fontData or using the font containe...
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...
void invalidate() override
This function is called whenever the font database is invalidated.
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,...
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,...
static QPlatformIntegration * platformIntegration()
static QPlatformNativeInterface * platformNativeInterface()
QScreen * primaryScreen
the primary (or default) screen of the application.
virtual QString resolveFontFamilyAlias(const QString &family) const
Resolve alias to actual font family names.
static void registerAliasToFontFamily(const QString &familyName, const QString &alias)
Helper function that register the alias for the familyName.
static void registerFont(const QString &familyname, const QString &stylename, const QString &foundryname, QFont::Weight weight, QFont::Style style, QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize, bool fixedPitch, const QSupportedWritingSystems &writingSystems, void *handle)
Registers a font with the given set of attributes describing the font's foundry, family name,...
The QPlatformServices provides the backend for desktop-related functionality.
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5949
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
QString toCaseFolded() const &
Definition qstring.h:443
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
QByteArray toUtf8() const &
Definition qstring.h:634
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.
Combined button and popup list for selecting options.
size_t qstrlen(const char *str)
#define qApp
static const QCssKnownValue properties[NumProperties - 1]
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:349
#define QFONT_WEIGHT_MAX
Definition qfont_p.h:34
static int stretchFromFcWidth(int fcwidth)
static QT_BEGIN_NAMESPACE int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper, int qtLower, int qtUpper)
static FcPattern * queryFont(const FcChar8 *file, const QByteArray &data, int id, FcBlanks *blanks, int *count, FT_Face *face)
static int weightFromFcWeight(int fcweight)
static void populateFromPattern(FcPattern *pattern, QFontDatabasePrivate::ApplicationFont *applicationFont=nullptr, FT_Face face=nullptr, QFontconfigDatabase *db=nullptr)
static bool isDprScaling()
static bool requiresOpenType(int writingSystem)
static const char languageForWritingSystem[][6]
static const char specialLanguages[][6]
static const char * getFcFamilyForStyleHint(const QFont::StyleHint style)
FT_Library qt_getFreetype()
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLenum GLuint id
[7]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum face
GLfloat GLfloat f
GLuint GLuint GLfloat weight
GLint GLsizei GLsizei GLenum format
GLenum GLsizeiptr const void * fontData
GLuint res
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLenum GLenum variable
GLubyte * pattern
GLenum cap
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_UNUSED(x)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187
ptrdiff_t qintptr
Definition qtypes.h:166
struct _FcPattern FcPattern
QFuture< QSet< QChar > > set
[10]
QFile file
[0]
QFile defaults(defaultsPath)
QMimeDatabase db
[0]
QJSEngine engine
[0]
uint hintingPreference
Definition qfont_p.h:67
uint styleStrategy
Definition qfont_p.h:64
qreal pixelSize
Definition qfont_p.h:61
QStringList families
Definition qfont_p.h:54