15#include <qpa/qplatformintegration.h>
17#include <QtGui/private/qguiapplication_p.h>
18#include <qpa/qplatformfontdatabase.h>
19#include <qpa/qplatformtheme.h>
21#include <QtCore/qcache.h>
22#include <QtCore/qmath.h>
27#include <qtgui_tracepoints_p.h>
30#include <QtGui/private/qwindowsfontdatabasebase_p.h>
35using namespace Qt::StringLiterals;
40#define SMOOTH_SCALABLE 0xffff
42#if defined(QT_BUILD_INTERNAL)
43bool qt_enable_test_font =
false;
45Q_AUTOTEST_EXPORT
void qt_setQtEnableTestFont(
bool value)
47 qt_enable_test_font = value;
58 QString s = weightString.toLower();
68 if (s ==
"normal"_L1 || s ==
"regular"_L1)
72 if (s ==
"semibold"_L1 || s ==
"semi bold"_L1 || s ==
"demibold"_L1 || s ==
"demi bold"_L1)
73 return QFont::DemiBold;
82 const QStringView s2 = QStringView{s}.mid(2);
83 if (s.startsWith(
"ex"_L1) || s.startsWith(
"ul"_L1)) {
84 if (s2 ==
"tralight"_L1 || s ==
"tra light"_L1)
85 return QFont::ExtraLight;
86 if (s2 ==
"trabold"_L1 || s2 ==
"tra bold"_L1)
87 return QFont::ExtraBold;
92 if (s.contains(
"bold"_L1)) {
93 if (s.contains(
"demi"_L1))
94 return QFont::DemiBold;
97 if (s.contains(
"thin"_L1))
99 if (s.contains(
"light"_L1))
101 if (s.contains(
"black"_L1))
108 if (s.compare(QCoreApplication::translate(
"QFontDatabase",
"Normal",
"The Normal or Regular font weight"), Qt::CaseInsensitive) == 0)
109 return QFont::Normal;
110 const QString translatedBold = QCoreApplication::translate(
"QFontDatabase",
"Bold").toLower();
111 if (s == translatedBold)
113 if (s.compare(QCoreApplication::translate(
"QFontDatabase",
"Demi Bold"), Qt::CaseInsensitive) == 0)
114 return QFont::DemiBold;
115 if (s.compare(QCoreApplication::translate(
"QFontDatabase",
"Medium",
"The Medium font weight"), Qt::CaseInsensitive) == 0)
116 return QFont::Medium;
117 if (s.compare(QCoreApplication::translate(
"QFontDatabase",
"Black"), Qt::CaseInsensitive) == 0)
119 const QString translatedLight = QCoreApplication::translate(
"QFontDatabase",
"Light").toLower();
120 if (s == translatedLight)
122 if (s.compare(QCoreApplication::translate(
"QFontDatabase",
"Thin"), Qt::CaseInsensitive) == 0)
124 if (s.compare(QCoreApplication::translate(
"QFontDatabase",
"Extra Light"), Qt::CaseInsensitive) == 0)
125 return QFont::ExtraLight;
126 if (s.compare(QCoreApplication::translate(
"QFontDatabase",
"Extra Bold"), Qt::CaseInsensitive) == 0)
127 return QFont::ExtraBold;
131 const QString translatedExtra = QCoreApplication::translate(
"QFontDatabase",
"Extra").toLower();
132 if (s.contains(translatedBold)) {
134 QString translatedDemi = QCoreApplication::translate(
"QFontDatabase",
"Demi").toLower();
135 if (s .contains(translatedDemi))
136 return QFont::DemiBold;
137 if (s.contains(translatedExtra))
138 return QFont::ExtraBold;
142 if (s.contains(translatedLight)) {
143 if (s.contains(translatedExtra))
144 return QFont::ExtraLight;
147 return QFont::Normal;
151QtFontStyle::Key::Key(
const QString &styleString)
152 : style(QFont::StyleNormal), weight(QFont::Normal), stretch(0)
154 weight = getFontWeight(styleString);
156 if (!styleString.isEmpty()) {
158 if (styleString.contains(
"Italic"_L1))
159 style = QFont::StyleItalic;
160 else if (styleString.contains(
"Oblique"_L1))
161 style = QFont::StyleOblique;
164 else if (styleString.contains(QCoreApplication::translate(
"QFontDatabase",
"Italic")))
165 style = QFont::StyleItalic;
166 else if (styleString.contains(QCoreApplication::translate(
"QFontDatabase",
"Oblique")))
167 style = QFont::StyleOblique;
171QtFontSize *QtFontStyle::pixelSize(
unsigned short size,
bool add)
173 for (
int i = 0; i < count; i++) {
174 if (pixelSizes[i].pixelSize == size)
175 return pixelSizes + i;
182 QtFontSize *newPixelSizes = (QtFontSize *)malloc(
sizeof(QtFontSize));
183 Q_CHECK_PTR(newPixelSizes);
184 pixelSizes = newPixelSizes;
185 }
else if (!(count % 8) || count == 1) {
186 QtFontSize *newPixelSizes = (QtFontSize *)
188 (((count+8) >> 3) << 3) *
sizeof(QtFontSize));
189 Q_CHECK_PTR(newPixelSizes);
190 pixelSizes = newPixelSizes;
192 pixelSizes[count].pixelSize = size;
193 pixelSizes[count].handle =
nullptr;
194 return pixelSizes + (count++);
197QtFontStyle *QtFontFoundry::style(
const QtFontStyle::Key &key,
const QString &styleName, StyleRetrievalFlags flags)
200 for (; pos < count; pos++) {
201 bool hasStyleName = !styleName.isEmpty() && !styles[pos]->styleName.isEmpty();
202 bool hasStyleNameMatch = styles[pos]->styleName == styleName;
203 bool hasKeyMatch = styles[pos]->key == key;
209 if (flags & MatchAllProperties) {
210 if (hasStyleNameMatch && hasKeyMatch)
212 }
else if (hasStyleName) {
213 if (hasStyleNameMatch)
215 }
else if (hasKeyMatch) {
219 if (!(flags & AddWhenMissing))
224 QtFontStyle **newStyles = (QtFontStyle **)
225 realloc(styles, (((count+8) >> 3) << 3) *
sizeof(QtFontStyle *));
226 Q_CHECK_PTR(newStyles);
230 QtFontStyle *style =
new QtFontStyle(key);
231 style->styleName = styleName;
237QtFontFoundry *QtFontFamily::foundry(
const QString &f,
bool create)
239 if (f.isNull() && count == 1)
242 for (
int i = 0; i < count; i++) {
243 if (foundries[i]->name.compare(f, Qt::CaseInsensitive) == 0)
250 QtFontFoundry **newFoundries = (QtFontFoundry **)
252 (((count+8) >> 3) << 3) *
sizeof(QtFontFoundry *));
253 Q_CHECK_PTR(newFoundries);
254 foundries = newFoundries;
257 foundries[count] =
new QtFontFoundry(f);
258 return foundries[count++];
263 return a.size() == b.size() && a.compare(b, Qt::CaseInsensitive) == 0;
266bool QtFontFamily::matchesFamilyName(
const QString &familyName)
const
268 return equalsCaseInsensitive(name, familyName) || aliases.contains(familyName, Qt::CaseInsensitive);
271bool QtFontFamily::ensurePopulated()
276 QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamily(name);
280void QFontDatabasePrivate::clearFamilies()
283 delete families[count];
288 for (
auto &font : applicationFonts)
289 font.properties.clear();
295void QFontDatabasePrivate::invalidate()
297 qCDebug(lcFontDb) <<
"Invalidating font database";
299 QFontCache::instance()->clear();
301 fallbacksCache.clear();
303 QGuiApplicationPrivate::platformIntegration()->fontDatabase()->invalidate();
304 emit
qGuiApp->fontDatabaseChanged();
307QtFontFamily *QFontDatabasePrivate::family(
const QString &f, FamilyRequestFlags flags)
309 QtFontFamily *fam =
nullptr;
316 while ((res = families[pos]->name.compare(f, Qt::CaseInsensitive)) && pos != low) {
321 pos = (high + low) / 2;
327 if (!fam && (flags & EnsureCreated)) {
333 QtFontFamily **newFamilies = (QtFontFamily **)
335 (((count+8) >> 3) << 3) *
sizeof(QtFontFamily *));
336 Q_CHECK_PTR(newFamilies);
337 families = newFamilies;
340 QtFontFamily *family =
new QtFontFamily(f);
341 memmove(families + pos + 1, families + pos, (count-pos)*
sizeof(QtFontFamily *));
342 families[pos] = family;
348 if (fam && (flags & EnsurePopulated)) {
349 if (!fam->ensurePopulated())
359 QChar::Script_Common,
362 QChar::Script_Cyrillic,
363 QChar::Script_Armenian,
364 QChar::Script_Hebrew,
365 QChar::Script_Arabic,
366 QChar::Script_Syriac,
367 QChar::Script_Thaana,
368 QChar::Script_Devanagari,
369 QChar::Script_Bengali,
370 QChar::Script_Gurmukhi,
371 QChar::Script_Gujarati,
374 QChar::Script_Telugu,
375 QChar::Script_Kannada,
376 QChar::Script_Malayalam,
377 QChar::Script_Sinhala,
380 QChar::Script_Tibetan,
381 QChar::Script_Myanmar,
382 QChar::Script_Georgian,
387 QChar::Script_Hangul,
389 QChar::Script_Common,
395static_assert(
sizeof(scriptForWritingSystem) /
sizeof(scriptForWritingSystem[0]) == QFontDatabase::WritingSystemsCount);
404
405
406
407
408
411 Q_ASSERT(family !=
nullptr);
412 Q_ASSERT(writingSystem != QFontDatabase::Any && writingSystem < QFontDatabase::WritingSystemsCount);
414 size_t ws = writingSystem;
416 if ((family->writingSystems[ws] & QtFontFamily::Supported) != 0)
418 }
while (writingSystem >= QFontDatabase::SimplifiedChinese && writingSystem <= QFontDatabase::Japanese && ++ws <= QFontDatabase::Japanese);
423Q_GUI_EXPORT QFontDatabase::WritingSystem qt_writing_system_for_script(
int script)
425 if (script >= QChar::ScriptCount)
426 return QFontDatabase::Any;
427 return QFontDatabase::WritingSystem(std::find(scriptForWritingSystem,
428 scriptForWritingSystem + QFontDatabase::WritingSystemsCount,
429 script) - scriptForWritingSystem);
433
434
435
436
437
438
439
440
441static void parseFontName(
const QString &name, QString &foundry, QString &family)
443 int i = name.indexOf(u'[');
444 int li = name.lastIndexOf(u']');
445 if (i >= 0 && li >= 0 && i < li) {
446 foundry = name.mid(i + 1, li - i - 1);
447 if (i > 0 && name[i - 1] == u' ')
449 family = name.left(i);
457 QChar *s = family.data();
458 int len = family.size();
460 if (space) *s = s->toUpper();
461 space = s->isSpace();
467 len = foundry.size();
469 if (space) *s = s->toUpper();
470 space = s->isSpace();
488 family = desc.family->name;
489 if (! desc.foundry->name.isEmpty() && desc.family->count > 1)
490 family +=
" ["_L1 + desc.foundry->name + u']';
491 fontDef->families = QStringList(family);
493 if (desc.style->smoothScalable
494 || QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable()
495 || (desc.style->bitmapScalable && (request.styleStrategy & QFont::PreferMatch))) {
496 fontDef->pixelSize = request.pixelSize;
498 fontDef->pixelSize = desc.size->pixelSize;
500 fontDef->pointSize = request.pointSize;
502 fontDef->styleHint = request.styleHint;
503 fontDef->styleStrategy = request.styleStrategy;
506 fontDef->weight = desc.style->key.weight;
508 fontDef->style = desc.style->key.style;
509 fontDef->fixedPitch = desc.family->fixedPitch;
510 fontDef->ignorePitch =
false;
516 QStringList family_list = req.families;
519 for (qsizetype i = 0, size = family_list.size(); i < size; ++i)
520 family_list += QFont::substitutes(family_list.at(i));
530 auto *db = QFontDatabasePrivate::instance();
531 db->fallbacksCache.clear();
538 return fontDatabaseMutex();
541QFontDatabasePrivate *QFontDatabasePrivate::instance()
543 static QFontDatabasePrivate instance;
548 const QString &foundryname,
int weight,
549 QFont::Style style,
int stretch,
bool antialiased,
550 bool scalable,
int pixelSize,
bool fixedPitch,
bool colorFont,
551 const QSupportedWritingSystems &writingSystems,
void *handle)
553 auto *d = QFontDatabasePrivate::instance();
554 qCDebug(lcFontDb) <<
"Adding font: familyName" << familyName <<
"stylename" << stylename <<
"weight" << weight
555 <<
"style" << style <<
"pixelSize" << pixelSize <<
"antialiased" << antialiased <<
"fixed" << fixedPitch <<
"colorFont" << colorFont;
556 QtFontStyle::Key styleKey;
557 styleKey.style = style;
558 styleKey.weight = weight;
559 styleKey.stretch = stretch;
560 QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::EnsureCreated);
561 f->fixedPitch = fixedPitch;
562 f->colorFont = colorFont;
564 for (
int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
565 if (writingSystems.supported(QFontDatabase::WritingSystem(i)))
566 f->writingSystems[i] = QtFontFamily::Supported;
569 QtFontFoundry *foundry = f->foundry(foundryname,
true);
570 QtFontStyle *fontStyle = foundry->style(styleKey,
572 QtFontFoundry::StyleRetrievalFlags::AllRetrievalFlags);
573 fontStyle->smoothScalable = scalable;
574 fontStyle->antialiased = antialiased;
575 QtFontSize *size = fontStyle->pixelSize(pixelSize ? pixelSize :
SMOOTH_SCALABLE,
true);
577 QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
579 integration->fontDatabase()->releaseHandle(size->handle);
581 size->handle = handle;
587 qCDebug(lcFontDb) <<
"Registering family" << familyName;
590 QFontDatabasePrivate::instance()->family(familyName, QFontDatabasePrivate::EnsureCreated);
598 qCDebug(lcFontDb) <<
"Registering alias" << alias <<
"to family" << familyName;
600 auto *d = QFontDatabasePrivate::instance();
601 QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::RequestFamily);
605 if (f->aliases.contains(alias, Qt::CaseInsensitive))
608 f->aliases.push_back(alias);
613 if (!alias.isEmpty()) {
614 const auto *d = QFontDatabasePrivate::instance();
615 for (
int i = 0; i < d->count; ++i)
616 if (d->families[i]->matchesFamilyName(alias))
617 return d->families[i]->name;
624 auto *d = QFontDatabasePrivate::instance();
625 QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::RequestFamily);
626 return f !=
nullptr && f->populated;
630
631
632
633
634
635
636QStringList QPlatformFontDatabase::fallbacksForFamily(
const QString &family,
638 QFont::StyleHint styleHint,
639 QFontDatabasePrivate::ExtendedScript script)
const
644 QStringList preferredFallbacks;
645 QStringList otherFallbacks;
646 QStringList lastResort;
648 auto writingSystem = qt_writing_system_for_script(script);
649 if (writingSystem >= QFontDatabase::WritingSystemsCount)
650 writingSystem = QFontDatabase::Any;
652 auto *db = QFontDatabasePrivate::instance();
654 i < db->count && preferredFallbacks.size() < QFontEngineMulti::maximumEngineCount() - 1;
656 QtFontFamily *f = db->families[i];
658 f->ensurePopulated();
660 if (writingSystem != QFontDatabase::Any && !familySupportsWritingSystem(f, writingSystem))
663 for (
int j = 0; j < f->count; ++j) {
664 QtFontFoundry *foundry = f->foundries[j];
666 QString name = foundry->name.isEmpty()
668 : f->name +
" ["_L1 + foundry->name + u']';
676 int score =
int(Score::LastResort);
677 for (
int k = 0; k < foundry->count; ++k) {
678 const bool styleMatch = style == foundry->styles[k]->key.style;
679 if (foundry->styles[k]->smoothScalable) {
681 score =
int(Score::Preferred);
684 score = std::max(score,
int(Score::Other));
686 }
else if (styleMatch) {
687 score = std::max(score,
int(Score::FirstLastResort));
691 switch (Score(score)) {
692 case Score::LastResort:
693 lastResort.append(name);
break;
694 case Score::FirstLastResort:
695 lastResort.prepend(name);
break;
697 otherFallbacks.append(name);
break;
698 case Score::Preferred:
699 preferredFallbacks.append(name);
break;
705 return preferredFallbacks + otherFallbacks + lastResort;
710 QFont::StyleHint styleHint,
711 QFontDatabasePrivate::ExtendedScript script)
714 auto *db = QFontDatabasePrivate::ensureFontDatabase();
718 if (
const QStringList *fallbacks = db->fallbacksCache.object(cacheKey))
722 QStringList userFallbacks = db->applicationFallbackFontFamilies(script == QFontDatabasePrivate::Script_Latin ? QFontDatabasePrivate::Script_Common : script);
723 QStringList retList = userFallbacks + QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
725 QStringList::iterator i;
726 for (i = retList.begin(); i != retList.end(); ++i) {
727 bool contains =
false;
728 for (
int j = 0; j < db->count; j++) {
729 if (db->families[j]->matchesFamilyName(*i)) {
735 i = retList.erase(i);
740 db->fallbacksCache.insert(cacheKey,
new QStringList(retList));
748 return fallbacksForFamily(family, style, styleHint, script);
751QFontEngine *QFontDatabasePrivate::loadSingleEngine(
int script,
752 const QFontDef &request,
753 QtFontFamily *family, QtFontFoundry *foundry,
754 QtFontStyle *style, QtFontSize *size)
759 QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
760 int pixelSize = size->pixelSize;
761 if (!pixelSize || (style->smoothScalable && pixelSize ==
SMOOTH_SCALABLE)
762 || pfdb->fontsAlwaysScalable()) {
763 pixelSize = request.pixelSize;
766 QFontDef def = request;
767 def.pixelSize = pixelSize;
769 QFontCache *fontCache = QFontCache::instance();
771 QFontCache::Key key(def,script);
772 QFontEngine *engine = fontCache->findEngine(key);
774 const bool cacheForCommonScript = script != QFontDatabasePrivate::Script_Common
775 && (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0;
777 if (Q_LIKELY(cacheForCommonScript) && script < QChar::ScriptCount) {
779 key.script = QChar::Script_Common;
780 engine = fontCache->findEngine(key);
784 if (Q_UNLIKELY(!engine->supportsScript(QChar::Script(script)))) {
785 qCInfo(lcFontDb,
"OpenType support missing for \"%ls\", script %d",
786 qUtf16Printable(def.family()), script);
790 engine->isSmoothlyScalable = style->smoothScalable;
791 fontCache->insertEngine(key, engine);
799 if (style->key.stretch != 0 && request.stretch != 0
800 && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
801 def.stretch = (request.stretch * 100 + style->key.stretch / 2) / style->key.stretch;
802 }
else if (request.stretch == QFont::AnyStretch) {
806 engine = pfdb->fontEngine(def, size->handle);
809 if (script < QChar::ScriptCount && !engine->supportsScript(QChar::Script(script))) {
810 qCInfo(lcFontDb,
"OpenType support missing for \"%ls\", script %d",
811 qUtf16Printable(def.family()), script);
812 if (engine->ref.loadRelaxed() == 0)
817 engine->isSmoothlyScalable = style->smoothScalable;
818 fontCache->insertEngine(key, engine);
820 if (Q_LIKELY(cacheForCommonScript && !engine->symbol)) {
822 key.script = QChar::Script_Common;
823 if (!fontCache->findEngine(key))
824 fontCache->insertEngine(key, engine);
831QFontEngine *QFontDatabasePrivate::loadEngine(
int script,
const QFontDef &request,
832 QtFontFamily *family, QtFontFoundry *foundry,
833 QtFontStyle *style, QtFontSize *size)
835 QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size);
837 if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
838 Q_TRACE(QFontDatabase_loadEngine, request.families.join(QLatin1Char(
';')), request.pointSize);
840 QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
841 QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine,
842 QFontDatabasePrivate::ExtendedScript(script));
843 if (!request.fallBackFamilies.isEmpty()) {
844 QStringList fallbacks = request.fallBackFamilies;
846 QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
847 if (styleHint == QFont::AnyStyle && request.fixedPitch)
848 styleHint = QFont::TypeWriter;
850 fallbacks += fallbacksForFamily(family->name,
851 QFont::Style(style->key.style),
853 QFontDatabasePrivate::ExtendedScript(script));
855 pfMultiEngine->setFallbackFamiliesList(fallbacks);
857 engine = pfMultiEngine;
861 QFontCache::Key key(request, script, 1);
862 QFontCache::instance()->insertEngine(key, engine);
868QtFontStyle::~QtFontStyle()
873 QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
875 integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
882 const QString &styleName = QString())
887 for (
int i = 0; i < foundry->count; i++ ) {
888 QtFontStyle *style = foundry->styles[i];
890 if (!styleName.isEmpty() && styleName == style->styleName) {
896 int d = qAbs( (
int(styleKey.weight) -
int(style->key.weight)) / 10 );
898 if ( styleKey.stretch != 0 && style->key.stretch != 0 ) {
899 d += qAbs( styleKey.stretch - style->key.stretch );
902 if (styleKey.style != style->key.style) {
903 if (styleKey.style != QFont::StyleNormal && style->key.style != QFont::StyleNormal)
916 qCDebug(lcFontMatch,
" best style has distance 0x%x", dist );
917 return foundry->styles[best];
921unsigned int QFontDatabasePrivate::bestFoundry(
int script,
unsigned int score,
int styleStrategy,
922 const QtFontFamily *family,
const QString &foundry_name,
923 QtFontStyle::Key styleKey,
int pixelSize,
char pitch,
924 QtFontDesc *desc,
const QString &styleName)
929 desc->foundry =
nullptr;
930 desc->style =
nullptr;
931 desc->size =
nullptr;
933 qCDebug(lcFontMatch,
" REMARK: looking for best foundry for family '%s'%s [%d]",
934 family->name.toLatin1().constData(),
935 family->colorFont ?
" (color font)" :
"",
938 for (
int x = 0; x < family->count; ++x) {
939 QtFontFoundry *foundry = family->foundries[x];
940 if (!foundry_name.isEmpty() && foundry->name.compare(foundry_name, Qt::CaseInsensitive) != 0)
943 qCDebug(lcFontMatch,
" looking for matching style in foundry '%s' %d",
944 foundry->name.isEmpty() ?
"-- none --" : foundry->name.toLatin1().constData(), foundry->count);
946 QtFontStyle *style = bestStyle(foundry, styleKey, styleName);
948 if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) {
949 qCDebug(lcFontMatch,
" ForceOutline set, but not smoothly scalable");
954 QtFontSize *size =
nullptr;
957 if (!(styleStrategy & QFont::ForceOutline)) {
958 size = style->pixelSize(pixelSize);
960 qCDebug(lcFontMatch,
" found exact size match (%d pixels)", size->pixelSize);
961 px = size->pixelSize;
966 if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
969 qCDebug(lcFontMatch,
" found smoothly scalable font (%d pixels)", pixelSize);
975 if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
976 size = style->pixelSize(0);
978 qCDebug(lcFontMatch,
" found bitmap scalable font (%d pixels)", pixelSize);
986 unsigned int distance = ~0u;
987 for (
int x = 0; x < style->count; ++x) {
990 if (style->pixelSizes[x].pixelSize < pixelSize) {
994 d = pixelSize - style->pixelSizes[x].pixelSize + 1;
996 d = style->pixelSizes[x].pixelSize - pixelSize;
1001 size = style->pixelSizes + x;
1002 qCDebug(lcFontMatch,
" best size so far: %3d (%d)", size->pixelSize, pixelSize);
1007 qCDebug(lcFontMatch,
" no size supports the script we want");
1011 if (style->bitmapScalable && ! (styleStrategy & QFont::PreferQuality) &&
1012 (distance * 10 / pixelSize) >= 2) {
1015 size = style->pixelSize(0);
1018 px = size->pixelSize;
1023 unsigned int this_score = 0x0000;
1025 PitchMismatch = 0x4000,
1026 StyleMismatch = 0x2000,
1027 BitmapScaledPenalty = 0x1000
1030 if ((pitch ==
'm' && !family->fixedPitch)
1031 || (pitch ==
'p' && family->fixedPitch))
1032 this_score += PitchMismatch;
1034 if (styleKey != style->key)
1035 this_score += StyleMismatch;
1036 if (!style->smoothScalable && px != size->pixelSize)
1037 this_score += BitmapScaledPenalty;
1038 if (px != pixelSize)
1039 this_score += qAbs(px - pixelSize);
1041 if (this_score < score) {
1042 qCDebug(lcFontMatch,
" found a match: score %x best score so far %x",
1046 desc->foundry = foundry;
1047 desc->style = style;
1050 qCDebug(lcFontMatch,
" score %x no better than best %x", this_score, score);
1059 if (familyName.isEmpty())
1061 return f->matchesFamilyName(familyName);
1065
1066
1067
1068
1069int QFontDatabasePrivate::match(
int script,
const QFontDef &request,
const QString &family_name,
1070 const QString &foundry_name, QtFontDesc *desc,
const QList<
int> &blacklistedFamilies,
1071 unsigned int *resultingScore)
1075 QtFontStyle::Key styleKey;
1076 styleKey.style = request.style;
1077 styleKey.weight = request.weight;
1079 styleKey.stretch = request.stretch ? request.stretch : 100;
1080 char pitch = request.ignorePitch ?
'*' : request.fixedPitch ?
'm' :
'p';
1083 qCDebug(lcFontMatch,
"QFontDatabasePrivate::match\n"
1085 " family: %s [%s], script: %d\n"
1087 " weight: %d, style: %d\n"
1091 family_name.isEmpty() ?
"-- first in script --" : family_name.toLatin1().constData(),
1092 foundry_name.isEmpty() ?
"-- any --" : foundry_name.toLatin1().constData(), script,
1093 request.styleName.isEmpty() ?
"-- any --" : request.styleName.toLatin1().constData(),
1094 request.weight, request.style, request.stretch, request.pixelSize, pitch);
1096 desc->family =
nullptr;
1097 desc->foundry =
nullptr;
1098 desc->style =
nullptr;
1099 desc->size =
nullptr;
1101 unsigned int score = ~0u;
1103 QMutexLocker locker(fontDatabaseMutex());
1104 QFontDatabasePrivate::ensureFontDatabase();
1106 auto writingSystem = qt_writing_system_for_script(script);
1107 if (writingSystem >= QFontDatabase::WritingSystemsCount)
1108 writingSystem = QFontDatabase::Any;
1110 auto *db = QFontDatabasePrivate::instance();
1111 for (
int x = 0; x < db->count; ++x) {
1112 if (blacklistedFamilies.contains(x))
1115 test.family = db->families[x];
1117 if (!matchFamilyName(family_name, test.family))
1119 if (!test.family->ensurePopulated())
1123 if (writingSystem != QFontDatabase::Any && !familySupportsWritingSystem(test.family, writingSystem))
1127 if (script == QFontDatabasePrivate::Script_Emoji && !test.family->colorFont)
1132 unsigned int newscore =
1133 bestFoundry(script, score, request.styleStrategy,
1134 test.family, foundry_name, styleKey, request.pixelSize, pitch,
1135 &test, request.styleName);
1136 if (test.foundry ==
nullptr && !foundry_name.isEmpty()) {
1139 newscore = bestFoundry(script, score, request.styleStrategy, test.family,
1140 QString(), styleKey, request.pixelSize,
1141 pitch, &test, request.styleName);
1144 if (newscore < score) {
1153 if (resultingScore !=
nullptr)
1154 *resultingScore = score;
1162 if (weight > QFont::Normal) {
1163 if (weight >= QFont::Black)
1164 result = QCoreApplication::translate(
"QFontDatabase",
"Black");
1165 else if (weight >= QFont::ExtraBold)
1166 result = QCoreApplication::translate(
"QFontDatabase",
"Extra Bold");
1167 else if (weight >= QFont::Bold)
1168 result = QCoreApplication::translate(
"QFontDatabase",
"Bold");
1169 else if (weight >= QFont::DemiBold)
1170 result = QCoreApplication::translate(
"QFontDatabase",
"Demi Bold");
1171 else if (weight >= QFont::Medium)
1172 result = QCoreApplication::translate(
"QFontDatabase",
"Medium",
"The Medium font weight");
1174 if (weight <= QFont::Thin)
1175 result = QCoreApplication::translate(
"QFontDatabase",
"Thin");
1176 else if (weight <= QFont::ExtraLight)
1177 result = QCoreApplication::translate(
"QFontDatabase",
"Extra Light");
1178 else if (weight <= QFont::Light)
1179 result = QCoreApplication::translate(
"QFontDatabase",
"Light");
1182 if (style == QFont::StyleItalic)
1183 result += u' ' + QCoreApplication::translate(
"QFontDatabase",
"Italic");
1184 else if (style == QFont::StyleOblique)
1185 result += u' ' + QCoreApplication::translate(
"QFontDatabase",
"Oblique");
1187 if (result.isEmpty())
1188 result = QCoreApplication::translate(
"QFontDatabase",
"Normal",
"The Normal or Regular font weight");
1190 return result.simplified();
1194
1195
1196
1197
1198QString QFontDatabase::styleString(
const QFont &font)
1200 return font.styleName().isEmpty() ? styleStringHelper(font.weight(), font.style())
1205
1206
1207
1208
1209QString QFontDatabase::styleString(
const QFontInfo &fontInfo)
1211 return fontInfo.styleName().isEmpty() ? styleStringHelper(fontInfo.weight(), fontInfo.style())
1212 : fontInfo.styleName();
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1268
1269
1270
1271
1272
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1317
1318
1319
1320
1321
1322
1323
1324
1325
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1378
1379
1380
1381
1382
1383QFontDatabasePrivate *QFontDatabasePrivate::ensureFontDatabase()
1385 auto *d = QFontDatabasePrivate::instance();
1386 if (!d->populated) {
1390 qCDebug(lcFontDb) <<
"Populating font database";
1392 if (Q_UNLIKELY(
qGuiApp ==
nullptr || QGuiApplicationPrivate::platformIntegration() ==
nullptr))
1393 qFatal(
"QFontDatabase: Must construct a QGuiApplication before accessing QFontDatabase");
1395 auto *platformFontDatabase = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
1396 platformFontDatabase->populateFontDatabase();
1398 for (
int i = 0; i < d->applicationFonts.size(); i++) {
1399 auto *font = &d->applicationFonts[i];
1400 if (!font->isNull() && !font->isPopulated())
1401 platformFontDatabase->addApplicationFont(font->data, font->fileName, font);
1407 d->populated =
true;
1413
1414
1415
1416
1417
1418
1419QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems()
1421 QMutexLocker locker(fontDatabaseMutex());
1422 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1424 quint64 writingSystemsFound = 0;
1425 static_assert(WritingSystemsCount < 64);
1427 for (
int i = 0; i < d->count; ++i) {
1428 QtFontFamily *family = d->families[i];
1429 if (!family->ensurePopulated())
1432 if (family->count == 0)
1434 for (uint x = Latin; x < uint(WritingSystemsCount); ++x) {
1435 if (family->writingSystems[x] & QtFontFamily::Supported)
1436 writingSystemsFound |= quint64(1) << x;
1443 QList<WritingSystem> list;
1444 list.reserve(qPopulationCount(writingSystemsFound));
1445 for (uint x = Latin ; x < uint(WritingSystemsCount); ++x) {
1446 if (writingSystemsFound & (quint64(1) << x))
1447 list.push_back(WritingSystem(x));
1454
1455
1456
1457
1458
1459QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems(
const QString &family)
1461 QString familyName, foundryName;
1462 parseFontName(family, foundryName, familyName);
1464 QMutexLocker locker(fontDatabaseMutex());
1465 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1467 QList<WritingSystem> list;
1468 QtFontFamily *f = d->family(familyName);
1469 if (!f || f->count == 0)
1472 for (
int x = Latin; x < WritingSystemsCount; ++x) {
1473 const WritingSystem writingSystem = WritingSystem(x);
1474 if (f->writingSystems[writingSystem] & QtFontFamily::Supported)
1475 list.append(writingSystem);
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491QStringList QFontDatabase::families(WritingSystem writingSystem)
1493 QMutexLocker locker(fontDatabaseMutex());
1494 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1497 for (
int i = 0; i < d->count; i++) {
1498 QtFontFamily *f = d->families[i];
1499 if (f->populated && f->count == 0)
1501 if (writingSystem != Any) {
1502 if (!f->ensurePopulated())
1504 if (f->writingSystems[writingSystem] != QtFontFamily::Supported)
1507 if (!f->populated || f->count == 1) {
1508 flist.append(f->name);
1510 for (
int j = 0; j < f->count; j++) {
1511 QString str = f->name;
1512 QString foundry = f->foundries[j]->name;
1513 if (!foundry.isEmpty()) {
1526
1527
1528
1529
1530
1531
1532QStringList QFontDatabase::styles(
const QString &family)
1534 QString familyName, foundryName;
1535 parseFontName(family, foundryName, familyName);
1537 QMutexLocker locker(fontDatabaseMutex());
1538 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1541 QtFontFamily *f = d->family(familyName);
1545 QtFontFoundry allStyles(foundryName);
1546 for (
int j = 0; j < f->count; j++) {
1547 QtFontFoundry *foundry = f->foundries[j];
1548 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1549 for (
int k = 0; k < foundry->count; k++) {
1550 QtFontStyle::Key ke(foundry->styles[k]->key);
1553 foundry->styles[k]->styleName,
1554 QtFontFoundry::AddWhenMissing);
1559 l.reserve(allStyles.count);
1560 for (
int i = 0; i < allStyles.count; i++) {
1561 l.append(allStyles.styles[i]->styleName.isEmpty() ?
1562 styleStringHelper(allStyles.styles[i]->key.weight,
1563 (QFont::Style)allStyles.styles[i]->key.style) :
1564 allStyles.styles[i]->styleName);
1570
1571
1572
1574bool QFontDatabase::isFixedPitch(
const QString &family,
1575 const QString &style)
1579 QString familyName, foundryName;
1580 parseFontName(family, foundryName, familyName);
1582 QMutexLocker locker(fontDatabaseMutex());
1583 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1585 QtFontFamily *f = d->family(familyName);
1586 return (f && f->fixedPitch);
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599bool QFontDatabase::isBitmapScalable(
const QString &family,
1600 const QString &style)
1602 QString familyName, foundryName;
1603 parseFontName(family, foundryName, familyName);
1605 QMutexLocker locker(fontDatabaseMutex());
1606 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1608 QtFontFamily *f = d->family(familyName);
1612 QtFontStyle::Key styleKey(style);
1613 for (
int j = 0; j < f->count; j++) {
1614 QtFontFoundry *foundry = f->foundries[j];
1615 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1616 for (
int k = 0; k < foundry->count; k++)
1617 if ((style.isEmpty() ||
1618 foundry->styles[k]->styleName == style ||
1619 foundry->styles[k]->key == styleKey)
1620 && foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
1630
1631
1632
1633
1634
1635
1636
1637bool QFontDatabase::isSmoothlyScalable(
const QString &family,
const QString &style)
1639 QString familyName, foundryName;
1640 parseFontName(family, foundryName, familyName);
1642 QMutexLocker locker(fontDatabaseMutex());
1643 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1645 QtFontFamily *f = d->family(familyName);
1647 for (
int i = 0; i < d->count; i++) {
1648 if (d->families[i]->matchesFamilyName(familyName)) {
1650 if (f->ensurePopulated())
1658 const QtFontStyle::Key styleKey(style);
1659 for (
int j = 0; j < f->count; j++) {
1660 QtFontFoundry *foundry = f->foundries[j];
1661 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1662 for (
int k = 0; k < foundry->count; k++) {
1663 const QtFontStyle *fontStyle = foundry->styles[k];
1664 const bool smoothScalable =
1665 fontStyle->smoothScalable
1666 && ((style.isEmpty()
1667 || fontStyle->styleName == style
1668 || fontStyle->key == styleKey)
1669 || (fontStyle->styleName.isEmpty()
1670 && style == styleStringHelper(fontStyle->key.weight,
1671 QFont::Style(fontStyle->key.style))));
1681
1682
1683
1684
1685
1686bool QFontDatabase::isScalable(
const QString &family,
1687 const QString &style)
1689 QMutexLocker locker(fontDatabaseMutex());
1690 if (isSmoothlyScalable(family, style))
1692 return isBitmapScalable(family, style);
1697
1698
1699
1700
1701
1702QList<
int> QFontDatabase::pointSizes(
const QString &family,
1703 const QString &styleName)
1705 if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable())
1706 return standardSizes();
1708 QString familyName, foundryName;
1709 parseFontName(family, foundryName, familyName);
1711 QMutexLocker locker(fontDatabaseMutex());
1712 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1716 QtFontFamily *fam = d->family(familyName);
1717 if (!fam)
return sizes;
1720 const int dpi = qt_defaultDpiY();
1722 QtFontStyle::Key styleKey(styleName);
1723 for (
int j = 0; j < fam->count; j++) {
1724 QtFontFoundry *foundry = fam->foundries[j];
1725 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1726 QtFontStyle *style = foundry->style(styleKey, styleName);
1727 if (!style)
continue;
1729 if (style->smoothScalable)
1730 return standardSizes();
1732 for (
int l = 0; l < style->count; l++) {
1733 const QtFontSize *size = style->pixelSizes + l;
1736 const int pointSize = qRound(size->pixelSize * 72.0 / dpi);
1737 if (! sizes.contains(pointSize))
1738 sizes.append(pointSize);
1744 std::sort(sizes.begin(), sizes.end());
1749
1750
1751
1752
1753
1754QFont QFontDatabase::font(
const QString &family,
const QString &style,
1757 QString familyName, foundryName;
1758 parseFontName(family, foundryName, familyName);
1759 QMutexLocker locker(fontDatabaseMutex());
1760 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1762 QtFontFoundry allStyles(foundryName);
1763 QtFontFamily *f = d->family(familyName);
1764 if (!f)
return QGuiApplication::font();
1766 for (
int j = 0; j < f->count; j++) {
1767 QtFontFoundry *foundry = f->foundries[j];
1768 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1769 for (
int k = 0; k < foundry->count; k++) {
1770 allStyles.style(foundry->styles[k]->key,
1771 foundry->styles[k]->styleName,
1772 QtFontFoundry::AddWhenMissing);
1777 QtFontStyle::Key styleKey(style);
1778 QtFontStyle *s = bestStyle(&allStyles, styleKey, style);
1781 return QGuiApplication::font();
1783 QFont fnt(QStringList{family}, pointSize, s->key.weight);
1784 fnt.setStyle((QFont::Style)s->key.style);
1785 if (!s->styleName.isEmpty())
1786 fnt.setStyleName(s->styleName);
1792
1793
1794
1795
1796
1797
1798
1799QList<
int> QFontDatabase::smoothSizes(
const QString &family,
1800 const QString &styleName)
1802 if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable())
1803 return standardSizes();
1805 QString familyName, foundryName;
1806 parseFontName(family, foundryName, familyName);
1808 QMutexLocker locker(fontDatabaseMutex());
1809 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1813 QtFontFamily *fam = d->family(familyName);
1817 const int dpi = qt_defaultDpiY();
1819 QtFontStyle::Key styleKey(styleName);
1820 for (
int j = 0; j < fam->count; j++) {
1821 QtFontFoundry *foundry = fam->foundries[j];
1822 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1823 QtFontStyle *style = foundry->style(styleKey, styleName);
1824 if (!style)
continue;
1826 if (style->smoothScalable)
1827 return QFontDatabase::standardSizes();
1829 for (
int l = 0; l < style->count; l++) {
1830 const QtFontSize *size = style->pixelSizes + l;
1833 const int pointSize = qRound(size->pixelSize * 72.0 / dpi);
1834 if (! sizes.contains(pointSize))
1835 sizes.append(pointSize);
1841 std::sort(sizes.begin(), sizes.end());
1847
1848
1849
1850
1851QList<
int> QFontDatabase::standardSizes()
1853 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->standardSizes();
1858
1859
1860
1861
1862
1863bool QFontDatabase::italic(
const QString &family,
const QString &style)
1865 QString familyName, foundryName;
1866 parseFontName(family, foundryName, familyName);
1868 QMutexLocker locker(fontDatabaseMutex());
1869 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1871 QtFontFoundry allStyles(foundryName);
1872 QtFontFamily *f = d->family(familyName);
1873 if (!f)
return false;
1875 for (
int j = 0; j < f->count; j++) {
1876 QtFontFoundry *foundry = f->foundries[j];
1877 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1878 for (
int k = 0; k < foundry->count; k++) {
1879 allStyles.style(foundry->styles[k]->key,
1880 foundry->styles[k]->styleName,
1881 QtFontFoundry::AddWhenMissing);
1886 QtFontStyle::Key styleKey(style);
1887 QtFontStyle *s = allStyles.style(styleKey, style);
1888 return s && s->key.style == QFont::StyleItalic;
1893
1894
1895
1896
1897
1898bool QFontDatabase::bold(
const QString &family,
1899 const QString &style)
1901 QString familyName, foundryName;
1902 parseFontName(family, foundryName, familyName);
1904 QMutexLocker locker(fontDatabaseMutex());
1905 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1907 QtFontFoundry allStyles(foundryName);
1908 QtFontFamily *f = d->family(familyName);
1909 if (!f)
return false;
1911 for (
int j = 0; j < f->count; j++) {
1912 QtFontFoundry *foundry = f->foundries[j];
1913 if (foundryName.isEmpty() ||
1914 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1915 for (
int k = 0; k < foundry->count; k++) {
1916 allStyles.style(foundry->styles[k]->key,
1917 foundry->styles[k]->styleName,
1918 QtFontFoundry::AddWhenMissing);
1923 QtFontStyle::Key styleKey(style);
1924 QtFontStyle *s = allStyles.style(styleKey, style);
1925 return s && s->key.weight >= QFont::Bold;
1930
1931
1932
1933
1934
1935
1936int QFontDatabase::weight(
const QString &family,
1937 const QString &style)
1939 QString familyName, foundryName;
1940 parseFontName(family, foundryName, familyName);
1942 QMutexLocker locker(fontDatabaseMutex());
1943 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1945 QtFontFoundry allStyles(foundryName);
1946 QtFontFamily *f = d->family(familyName);
1949 for (
int j = 0; j < f->count; j++) {
1950 QtFontFoundry *foundry = f->foundries[j];
1951 if (foundryName.isEmpty() ||
1952 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1953 for (
int k = 0; k < foundry->count; k++) {
1954 allStyles.style(foundry->styles[k]->key,
1955 foundry->styles[k]->styleName,
1956 QtFontFoundry::AddWhenMissing);
1961 QtFontStyle::Key styleKey(style);
1962 QtFontStyle *s = allStyles.style(styleKey, style);
1963 return s ? s->key.weight : -1;
1968bool QFontDatabase::hasFamily(
const QString &family)
1970 QString parsedFamily, foundry;
1971 parseFontName(family, foundry, parsedFamily);
1972 const QString familyAlias = QFontDatabasePrivate::resolveFontFamilyAlias(parsedFamily);
1974 QMutexLocker locker(fontDatabaseMutex());
1975 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1977 for (
int i = 0; i < d->count; i++) {
1978 QtFontFamily *f = d->families[i];
1979 if (f->populated && f->count == 0)
1981 if (familyAlias.compare(f->name, Qt::CaseInsensitive) == 0)
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001bool QFontDatabase::isPrivateFamily(
const QString &family)
2003 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->isPrivateFontFamily(family);
2008
2009
2010
2011QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
2013 const char *name =
nullptr;
2014 switch (writingSystem) {
2016 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Any");
2019 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Latin");
2022 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Greek");
2025 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Cyrillic");
2028 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Armenian");
2031 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Hebrew");
2034 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Arabic");
2037 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Syriac");
2040 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Thaana");
2043 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Devanagari");
2046 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Bengali");
2049 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Gurmukhi");
2052 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Gujarati");
2055 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Oriya");
2058 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Tamil");
2061 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Telugu");
2064 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Kannada");
2067 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Malayalam");
2070 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Sinhala");
2073 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Thai");
2076 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Lao");
2079 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Tibetan");
2082 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Myanmar");
2085 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Georgian");
2088 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Khmer");
2090 case SimplifiedChinese:
2091 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Simplified Chinese");
2093 case TraditionalChinese:
2094 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Traditional Chinese");
2097 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Japanese");
2100 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Korean");
2103 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Vietnamese");
2106 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Symbol");
2109 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Ogham");
2112 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Runic");
2115 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"N'Ko");
2118 Q_ASSERT_X(
false,
"QFontDatabase::writingSystemName",
"invalid 'writingSystem' parameter");
2121 return QCoreApplication::translate(
"QFontDatabase", name);
2125
2126
2127QString QFontDatabase::writingSystemSample(WritingSystem writingSystem)
2129 return [&]() -> QStringView {
2130 switch (writingSystem) {
2131 case QFontDatabase::Any:
2132 case QFontDatabase::Symbol:
2135 case QFontDatabase::Latin:
2138 return u"Aa\x00C3\x00E1Zz";
2139 case QFontDatabase::Greek:
2140 return u"\x0393\x03B1\x03A9\x03C9";
2141 case QFontDatabase::Cyrillic:
2142 return u"\x0414\x0434\x0436\x044f";
2143 case QFontDatabase::Armenian:
2144 return u"\x053f\x054f\x056f\x057f";
2145 case QFontDatabase::Hebrew:
2146 return u"\x05D0\x05D1\x05D2\x05D3";
2147 case QFontDatabase::Arabic:
2148 return u"\x0623\x0628\x062C\x062F\x064A\x0629\x0020\x0639\x0631\x0628\x064A\x0629";
2149 case QFontDatabase::Syriac:
2150 return u"\x0715\x0725\x0716\x0726";
2151 case QFontDatabase::Thaana:
2152 return u"\x0784\x0794\x078c\x078d";
2153 case QFontDatabase::Devanagari:
2154 return u"\x0905\x0915\x0925\x0935";
2155 case QFontDatabase::Bengali:
2156 return u"\x0986\x0996\x09a6\x09b6";
2157 case QFontDatabase::Gurmukhi:
2158 return u"\x0a05\x0a15\x0a25\x0a35";
2159 case QFontDatabase::Gujarati:
2160 return u"\x0a85\x0a95\x0aa5\x0ab5";
2161 case QFontDatabase::Oriya:
2162 return u"\x0b06\x0b16\x0b2b\x0b36";
2163 case QFontDatabase::Tamil:
2164 return u"\x0b89\x0b99\x0ba9\x0bb9";
2165 case QFontDatabase::Telugu:
2166 return u"\x0c05\x0c15\x0c25\x0c35";
2167 case QFontDatabase::Kannada:
2168 return u"\x0c85\x0c95\x0ca5\x0cb5";
2169 case QFontDatabase::Malayalam:
2170 return u"\x0d05\x0d15\x0d25\x0d35";
2171 case QFontDatabase::Sinhala:
2172 return u"\x0d90\x0da0\x0db0\x0dc0";
2173 case QFontDatabase::Thai:
2174 return u"\x0e02\x0e12\x0e22\x0e32";
2175 case QFontDatabase::Lao:
2176 return u"\x0e8d\x0e9d\x0ead\x0ebd";
2177 case QFontDatabase::Tibetan:
2178 return u"\x0f00\x0f01\x0f02\x0f03";
2179 case QFontDatabase::Myanmar:
2180 return u"\x1000\x1001\x1002\x1003";
2181 case QFontDatabase::Georgian:
2182 return u"\x10a0\x10b0\x10c0\x10d0";
2183 case QFontDatabase::Khmer:
2184 return u"\x1780\x1790\x17b0\x17c0";
2185 case QFontDatabase::SimplifiedChinese:
2186 return u"\x4e2d\x6587\x8303\x4f8b";
2187 case QFontDatabase::TraditionalChinese:
2188 return u"\x4e2d\x6587\x7bc4\x4f8b";
2189 case QFontDatabase::Japanese:
2190 return u"\x30b5\x30f3\x30d7\x30eb\x3067\x3059";
2191 case QFontDatabase::Korean:
2192 return u"\xac00\xac11\xac1a\xac2f";
2193 case QFontDatabase::Vietnamese:
2194 return u"\x1ED7\x1ED9\x1ED1\x1ED3";
2195 case QFontDatabase::Ogham:
2196 return u"\x1681\x1682\x1683\x1684";
2197 case QFontDatabase::Runic:
2198 return u"\x16a0\x16a1\x16a2\x16a3";
2199 case QFontDatabase::Nko:
2200 return u"\x7ca\x7cb\x7cc\x7cd";
2207void QFontDatabasePrivate::parseFontName(
const QString &name, QString &foundry, QString &family)
2209 QT_PREPEND_NAMESPACE(parseFontName)(name, foundry, family);
2215 QMutexLocker locker(fontDatabaseMutex());
2216 return QFontDatabasePrivate::instance()->applicationFonts.value(index).data;
2219int QFontDatabasePrivate::addAppFont(
const QByteArray &fontData,
const QString &fileName)
2221 QFontDatabasePrivate::ApplicationFont font;
2222 font.data = fontData;
2223 font.fileName = fileName;
2225 Q_TRACE(QFontDatabasePrivate_addAppFont, fileName);
2228 for (i = 0; i < applicationFonts.size(); ++i)
2229 if (applicationFonts.at(i).isNull())
2231 if (i >= applicationFonts.size()) {
2232 applicationFonts.append(ApplicationFont());
2233 i = applicationFonts.size() - 1;
2236 if (font.fileName.isEmpty() && !fontData.isEmpty())
2237 font.fileName =
":qmemoryfonts/"_L1 + QString::number(i);
2239 auto *platformFontDatabase = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
2240 platformFontDatabase->addApplicationFont(font.data, font.fileName, &font);
2241 if (font.properties.isEmpty())
2244 applicationFonts[i] = font;
2248 QFontCache::instance()->clear();
2250 fallbacksCache.clear();
2252 emit
qApp->fontDatabaseChanged();
2257bool QFontDatabasePrivate::isApplicationFont(
const QString &fileName)
2259 for (
int i = 0; i < applicationFonts.size(); ++i)
2260 if (applicationFonts.at(i).fileName == fileName)
2265void QFontDatabasePrivate::setApplicationFallbackFontFamilies(ExtendedScript script,
const QStringList &familyNames)
2267 applicationFallbackFontFamiliesHash[script] = familyNames;
2269 QFontCache::instance()->clear();
2270 fallbacksCache.clear();
2273QStringList QFontDatabasePrivate::applicationFallbackFontFamilies(ExtendedScript script)
2275 return applicationFallbackFontFamiliesHash.value(script);
2278bool QFontDatabasePrivate::removeApplicationFallbackFontFamily(ExtendedScript script,
const QString &familyName)
2280 auto it = applicationFallbackFontFamiliesHash.find(script);
2281 if (it != applicationFallbackFontFamiliesHash.end()) {
2282 if (it->removeAll(familyName) > 0) {
2284 it = applicationFallbackFontFamiliesHash.erase(it);
2285 QFontCache::instance()->clear();
2286 fallbacksCache.clear();
2294void QFontDatabasePrivate::addApplicationFallbackFontFamily(ExtendedScript script,
const QString &familyName)
2296 auto it = applicationFallbackFontFamiliesHash.find(script);
2297 if (it == applicationFallbackFontFamiliesHash.end())
2298 it = applicationFallbackFontFamiliesHash.insert(script, QStringList{});
2300 it->prepend(familyName);
2302 QFontCache::instance()->clear();
2303 fallbacksCache.clear();
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324int QFontDatabase::addApplicationFont(
const QString &fileName)
2327 if (!QFileInfo(fileName).isNativePath()) {
2329 if (!f.open(QIODevice::ReadOnly))
2332 Q_TRACE(QFontDatabase_addApplicationFont, fileName);
2336 QMutexLocker locker(fontDatabaseMutex());
2337 return QFontDatabasePrivate::instance()->addAppFont(data, fileName);
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352int QFontDatabase::addApplicationFontFromData(
const QByteArray &fontData)
2354 QMutexLocker locker(fontDatabaseMutex());
2355 return QFontDatabasePrivate::instance()->addAppFont(fontData, QString() );
2359
2360
2361
2362
2363
2364
2365
2366QStringList QFontDatabase::applicationFontFamilies(
int id)
2368 QMutexLocker locker(fontDatabaseMutex());
2369 auto *d = QFontDatabasePrivate::instance();
2372 ret.reserve(d->applicationFonts.value(id).properties.size());
2374 for (
const auto &properties : d->applicationFonts.value(id).properties)
2375 ret.append(properties.familyName);
2381
2382
2383
2384
2385
2386
2387
2389QFont QFontDatabase::systemFont(QFontDatabase::SystemFont type)
2391 const QFont *font =
nullptr;
2392 if (
const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
2395 font = theme->font(QPlatformTheme::SystemFont);
2398 font = theme->font(QPlatformTheme::FixedFont);
2401 font = theme->font(QPlatformTheme::TitleBarFont);
2403 case SmallestReadableFont:
2404 font = theme->font(QPlatformTheme::MiniFont);
2411 else if (QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration())
2412 return integration->fontDatabase()->defaultFont();
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428bool QFontDatabase::removeApplicationFont(
int handle)
2430 QMutexLocker locker(fontDatabaseMutex());
2432 auto *db = QFontDatabasePrivate::instance();
2433 if (handle < 0 || handle >= db->applicationFonts.size())
2436 db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454bool QFontDatabase::removeAllApplicationFonts()
2456 QMutexLocker locker(fontDatabaseMutex());
2458 auto *db = QFontDatabasePrivate::instance();
2459 if (!db || db->applicationFonts.isEmpty())
2462 db->applicationFonts.clear();
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499void QFontDatabase::addApplicationFallbackFontFamily(QChar::Script script,
const QString &familyName)
2501 QMutexLocker locker(fontDatabaseMutex());
2503 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2504 qCWarning(lcFontDb) <<
"Invalid script passed to addApplicationFallbackFontFamily:" << script;
2508 if (script == QChar::Script_Latin)
2509 script = QChar::Script_Common;
2511 auto *db = QFontDatabasePrivate::instance();
2512 db->addApplicationFallbackFontFamily(QFontDatabasePrivate::ExtendedScript(script), familyName);
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525bool QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script script,
const QString &familyName)
2527 QMutexLocker locker(fontDatabaseMutex());
2529 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2530 qCWarning(lcFontDb) <<
"Invalid script passed to removeApplicationFallbackFontFamily:" << script;
2534 if (script == QChar::Script_Latin)
2535 script = QChar::Script_Common;
2537 auto *db = QFontDatabasePrivate::instance();
2538 return db->removeApplicationFallbackFontFamily(QFontDatabasePrivate::ExtendedScript(script),
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555void QFontDatabase::setApplicationFallbackFontFamilies(QChar::Script script,
const QStringList &familyNames)
2557 QMutexLocker locker(fontDatabaseMutex());
2559 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2560 qCWarning(lcFontDb) <<
"Invalid script passed to setApplicationFallbackFontFamilies:" << script;
2564 if (script == QChar::Script_Latin)
2565 script = QChar::Script_Common;
2567 auto *db = QFontDatabasePrivate::instance();
2568 db->setApplicationFallbackFontFamilies(QFontDatabasePrivate::ExtendedScript(script),
2573
2574
2575
2576
2577
2578
2579
2580QStringList QFontDatabase::applicationFallbackFontFamilies(QChar::Script script)
2582 QMutexLocker locker(fontDatabaseMutex());
2584 if (script >= QChar::ScriptCount) {
2585 qCWarning(lcFontDb) <<
"Invalid script passed to applicationFallbackFontFamilies:" << script;
2586 return QStringList{};
2589 if (script == QChar::Script_Latin)
2590 script = QChar::Script_Common;
2592 auto *db = QFontDatabasePrivate::instance();
2593 return db->applicationFallbackFontFamilies(QFontDatabasePrivate::ExtendedScript(script));
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607void QFontDatabase::addApplicationEmojiFontFamily(
const QString &familyName)
2609 QMutexLocker locker(fontDatabaseMutex());
2610 auto *db = QFontDatabasePrivate::instance();
2611 db->addApplicationFallbackFontFamily(QFontDatabasePrivate::Script_Emoji, familyName);
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624bool QFontDatabase::removeApplicationEmojiFontFamily(
const QString &familyName)
2626 QMutexLocker locker(fontDatabaseMutex());
2627 auto *db = QFontDatabasePrivate::instance();
2628 return db->removeApplicationFallbackFontFamily(QFontDatabasePrivate::Script_Emoji,
2633
2634
2635
2636
2637
2638
2639void QFontDatabase::setApplicationEmojiFontFamilies(
const QStringList &familyNames)
2641 QMutexLocker locker(fontDatabaseMutex());
2642 auto *db = QFontDatabasePrivate::instance();
2643 db->setApplicationFallbackFontFamilies(QFontDatabasePrivate::Script_Emoji,
2648
2649
2650
2651
2652
2653
2654QStringList QFontDatabase::applicationEmojiFontFamilies()
2656 QMutexLocker locker(fontDatabaseMutex());
2657 auto *db = QFontDatabasePrivate::instance();
2658 return db->applicationFallbackFontFamilies(QFontDatabasePrivate::Script_Emoji);
2662
2663
2664QFontEngine *QFontDatabasePrivate::findFont(
const QFontDef &req,
2666 bool preferScriptOverFamily)
2668 QMutexLocker locker(fontDatabaseMutex());
2669 ensureFontDatabase();
2671 QFontEngine *engine;
2674 const QFontDef request =
static_cast<QWindowsFontDatabaseBase *>(
2675 QGuiApplicationPrivate::platformIntegration()->fontDatabase())
2676 ->sanitizeRequest(req);
2678 const QFontDef &request = req;
2681#if defined(QT_BUILD_INTERNAL)
2683 if (qt_enable_test_font && request.family() ==
"__Qt__Box__Engine__"_L1) {
2684 engine =
new QTestFontEngine(request.pixelSize);
2685 engine->fontDef = request;
2690 QFontCache *fontCache = QFontCache::instance();
2695 bool multi = !(request.styleStrategy & QFont::NoFontMerging);
2696 QFontCache::Key key(request, script, multi ? 1 : 0);
2697 engine = fontCache->findEngine(key);
2699 qCDebug(lcFontMatch,
"Cache hit level 1");
2703 if (request.pixelSize > 0xffff) {
2705 qCDebug(lcFontMatch,
"Rejecting request for pixel size %g2, returning box engine",
double(request.pixelSize));
2706 return new QFontEngineBox(32);
2709 QString family_name, foundry_name;
2710 const QString requestFamily = request.families.at(0);
2711 parseFontName(requestFamily, foundry_name, family_name);
2713 QList<
int> blackListed;
2714 unsigned int score = UINT_MAX;
2725 qCDebug(lcFontMatch,
"Family name match pass: Looking for family name '%s'%s", qPrintable(family_name),
2726 script == QFontDatabasePrivate::Script_Emoji ?
" (color font required)" :
"");
2727 int index = match(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed, &score);
2732 if (score > 0 && QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamilyAliases(family_name)) {
2733 qCDebug(lcFontMatch,
"Alias match pass: Imperfect result and aliases populated, so trying again%s",
2734 script == QFontDatabasePrivate::Script_Emoji ?
" (color font required)" :
"");
2736 index = match(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
2744 if (index < 0 && !multi && !preferScriptOverFamily) {
2745 qCDebug(lcFontMatch,
"NoFontMerging pass: Font not found with requested script, but we try to load it anyway");
2746 index = match(QChar::Script_Common, request, family_name, foundry_name, &desc, blackListed);
2750 QFontDef fontDef = request;
2753 if (fontDef.families.isEmpty())
2754 fontDef.families = QStringList(desc.family->name);
2756 engine = loadEngine(script, fontDef, desc.family, desc.foundry, desc.style, desc.size);
2759 initFontDef(desc, request, &engine->fontDef, multi);
2761 qCDebug(lcFontMatch,
"Failed to create font engine for font '%s'. Blacklisting %d",
2762 qPrintable(desc.family->name), index);
2763 blackListed.append(index);
2766 qCDebug(lcFontMatch,
" NO MATCH FOUND\n");
2774 if (!requestFamily.isEmpty()) {
2775 qCDebug(lcFontMatch,
"Fallbacks pass: Looking for a fallback matching script %d", script);
2776 QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
2777 if (styleHint == QFont::AnyStyle && request.fixedPitch)
2778 styleHint = QFont::TypeWriter;
2780 QStringList fallbacks = request.fallBackFamilies
2781 + fallbacksForFamily(requestFamily,
2782 QFont::Style(request.style),
2784 QFontDatabasePrivate::ExtendedScript(script));
2785 if (script > QChar::Script_Common)
2786 fallbacks += QString();
2788 auto findMatchingFallback = [&fallbacks,
2793 &request](
int lookupScript,
int cacheScript) {
2794 QFontEngine *engine =
nullptr;
2795 for (
int i = 0; !engine && i < fallbacks.size(); i++) {
2796 QFontDef def = request;
2798 def.families = QStringList(fallbacks.at(i));
2799 QFontCache::Key key(def, cacheScript, multi ? 1 : 0);
2800 engine = fontCache->findEngine(key);
2804 index = match(lookupScript,
2812 QFontDef loadDef = def;
2813 if (loadDef.families.isEmpty())
2814 loadDef.families = QStringList(desc.family->name);
2815 engine = loadEngine(cacheScript,
2822 initFontDef(desc, loadDef, &engine->fontDef, multi);
2824 qCDebug(lcFontMatch,
"Failed to create font engine for fallback %d (%s). Blacklisting %d",
2825 i, qPrintable(desc.family->name), index);
2826 blackListed.append(index);
2829 }
while (index >= 0 && !engine);
2836 engine = findMatchingFallback(multi && script != QFontDatabasePrivate::Script_Emoji
2837 ? QChar::Script_Common
2844 if (!engine && script == QFontDatabasePrivate::Script_Emoji) {
2845 qCDebug(lcFontMatch,
"No color fonts found on system. Doing final fallback match.");
2849 if (!requestFamily.isEmpty())
2850 fallbacks.prepend(requestFamily);
2851 engine = findMatchingFallback(QChar::Script_Common, script);
2856 engine =
new QFontEngineBox(request.pixelSize);
2857 qCDebug(lcFontMatch,
"returning box engine");
2864void QFontDatabasePrivate::load(
const QFontPrivate *d,
int script)
2866 QFontDef req = d->request;
2868 if (req.pixelSize == -1) {
2869 req.pixelSize = std::floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100;
2870 req.pixelSize = qRound(req.pixelSize);
2873 if (req.pointSize < 0 && d->dpi > 0)
2874 req.pointSize = req.pixelSize*72.0/d->dpi;
2877 const QStringList fallBackFamilies = familyList(req);
2879 if (!d->engineData) {
2880 QFontCache *fontCache = QFontCache::instance();
2884 if (!d->request.families.isEmpty())
2885 req.families = fallBackFamilies;
2887 d->engineData = fontCache->findEngineData(req);
2888 if (!d->engineData) {
2890 d->engineData =
new QFontEngineData;
2891 fontCache->insertEngineData(req, d->engineData);
2893 d->engineData->ref.ref();
2897 if (d->engineData->engines[script])
2900 QFontEngine *fe =
nullptr;
2902 Q_TRACE(QFontDatabase_load, req.families.join(QLatin1Char(
';')), req.pointSize);
2904 req.fallBackFamilies = fallBackFamilies;
2905 if (!req.fallBackFamilies.isEmpty())
2906 req.families = QStringList(req.fallBackFamilies.takeFirst());
2909 QStringList family_list;
2911 if (!req.families.isEmpty()) {
2913 family_list << req.families.at(0);
2916 const auto families = QGuiApplication::font().families();
2917 if (!families.isEmpty()) {
2918 QString defaultFamily = families.first();
2919 if (! family_list.contains(defaultFamily))
2920 family_list << defaultFamily;
2926 family_list << QString();
2928 QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
2929 for (; !fe && it != end; ++it) {
2930 req.families = QStringList(*it);
2932 fe = QFontDatabasePrivate::findFont(req, script);
2934 if (fe->type() == QFontEngine::Box && !req.families.at(0).isEmpty()) {
2935 if (fe->ref.loadRelaxed() == 0)
2940 fe->fontDef.pointSize = qreal(
double((fe->fontDef.pixelSize * 72) / d->dpi));
2945 req.fallBackFamilies.clear();
2949 if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
2950 for (
int i = 0; i < QFontDatabasePrivate::ScriptCount; ++i) {
2951 if (!d->engineData->engines[i]) {
2952 d->engineData->engines[i] = fe;
2957 d->engineData->engines[script] = fe;
2962QString QFontDatabasePrivate::resolveFontFamilyAlias(
const QString &family)
2964 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->resolveFontFamilyAlias(family);
2967Q_GUI_EXPORT
QStringList qt_sort_families_by_writing_system(QFontDatabasePrivate::ExtendedScript script,
2968 const QStringList &families)
2970 size_t writingSystem = qt_writing_system_for_script(script);
2971 if (script != QFontDatabasePrivate::Script_Emoji
2972 && (writingSystem == QFontDatabase::Any
2973 || writingSystem >= QFontDatabase::WritingSystemsCount)) {
2977 auto *db = QFontDatabasePrivate::instance();
2978 QMultiMap<uint, QString> supported;
2979 for (
int i = 0; i < families.size(); ++i) {
2980 const QString &family = families.at(i);
2982 QtFontFamily *testFamily =
nullptr;
2983 for (
int x = 0; x < db->count; ++x) {
2984 if (Q_UNLIKELY(matchFamilyName(family, db->families[x]))) {
2985 testFamily = db->families[x];
2986 if (testFamily->ensurePopulated())
2992 if (testFamily ==
nullptr
2993 || (script == QFontDatabasePrivate::Script_Emoji && !testFamily->colorFont)
2994 || (script != QFontDatabasePrivate::Script_Emoji && !familySupportsWritingSystem(testFamily, writingSystem))) {
2998 supported.insert(order, family);
3001 return supported.values();
3006#include "moc_qfontdatabase.cpp"
Combined button and popup list for selecting options.
QList< QString > QStringList
Constructs a string list that contains the given string, str.
Q_TRACE_POINT(qtcore, QFactoryLoader_update, const QString &fileName)
QRecursiveMutex * qt_fontdatabase_mutex()
static bool familySupportsWritingSystem(QtFontFamily *family, size_t writingSystem)
void qt_registerFont(const QString &familyName, const QString &stylename, const QString &foundryname, int weight, QFont::Style style, int stretch, bool antialiased, bool scalable, int pixelSize, bool fixedPitch, bool colorFont, const QSupportedWritingSystems &writingSystems, void *handle)
static bool equalsCaseInsensitive(const QString &a, const QString &b)
static void parseFontName(const QString &name, QString &foundry, QString &family)
static const int scriptForWritingSystem[]
bool qt_isFontFamilyPopulated(const QString &familyName)
static QString styleStringHelper(int weight, QFont::Style style)
static int getFontWeight(const QString &weightString)
static bool matchFamilyName(const QString &familyName, QtFontFamily *f)
Q_GUI_EXPORT int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem)
Q_TRACE_POINT(qtgui, QFontDatabase_loadEngine, const QString &families, int pointSize)
static QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QFontDatabasePrivate::ExtendedScript script)
static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef, bool multi)
QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QFontDatabasePrivate::ExtendedScript script)
void qt_registerFontFamily(const QString &familyName)
void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias)
QString qt_resolveFontFamilyAlias(const QString &alias)
static QStringList familyList(const QFontDef &req)
void qt_cleanupFontDatabase()
static QtFontStyle * bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey, const QString &styleName=QString())
#define Q_LOGGING_CATEGORY(name,...)
#define qCInfo(category,...)
#define qCWarning(category,...)
#define qCDebug(category,...)