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();
653 for (
int i = 0; i < db->count; ++i) {
654 QtFontFamily *f = db->families[i];
656 f->ensurePopulated();
658 if (writingSystem != QFontDatabase::Any && !familySupportsWritingSystem(f, writingSystem))
661 for (
int j = 0; j < f->count; ++j) {
662 QtFontFoundry *foundry = f->foundries[j];
664 QString name = foundry->name.isEmpty()
666 : f->name +
" ["_L1 + foundry->name + u']';
674 int score =
int(Score::LastResort);
675 for (
int k = 0; k < foundry->count; ++k) {
676 const bool styleMatch = style == foundry->styles[k]->key.style;
677 if (foundry->styles[k]->smoothScalable) {
679 score =
int(Score::Preferred);
682 score = std::max(score,
int(Score::Other));
684 }
else if (styleMatch) {
685 score = std::max(score,
int(Score::FirstLastResort));
689 switch (Score(score)) {
690 case Score::LastResort:
691 lastResort.append(name);
break;
692 case Score::FirstLastResort:
693 lastResort.prepend(name);
break;
695 otherFallbacks.append(name);
break;
696 case Score::Preferred:
697 preferredFallbacks.append(name);
break;
703 return preferredFallbacks + otherFallbacks + lastResort;
708 QFont::StyleHint styleHint,
709 QFontDatabasePrivate::ExtendedScript script)
712 auto *db = QFontDatabasePrivate::ensureFontDatabase();
716 if (
const QStringList *fallbacks = db->fallbacksCache.object(cacheKey))
720 QStringList userFallbacks = db->applicationFallbackFontFamilies(script == QFontDatabasePrivate::Script_Latin ? QFontDatabasePrivate::Script_Common : script);
721 QStringList retList = userFallbacks + QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
723 QStringList::iterator i;
724 for (i = retList.begin(); i != retList.end(); ++i) {
725 bool contains =
false;
726 for (
int j = 0; j < db->count; j++) {
727 if (db->families[j]->matchesFamilyName(*i)) {
733 i = retList.erase(i);
738 db->fallbacksCache.insert(cacheKey,
new QStringList(retList));
746 return fallbacksForFamily(family, style, styleHint, script);
749QFontEngine *QFontDatabasePrivate::loadSingleEngine(
int script,
750 const QFontDef &request,
751 QtFontFamily *family, QtFontFoundry *foundry,
752 QtFontStyle *style, QtFontSize *size)
757 QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
758 int pixelSize = size->pixelSize;
759 if (!pixelSize || (style->smoothScalable && pixelSize ==
SMOOTH_SCALABLE)
760 || pfdb->fontsAlwaysScalable()) {
761 pixelSize = request.pixelSize;
764 QFontDef def = request;
765 def.pixelSize = pixelSize;
767 QFontCache *fontCache = QFontCache::instance();
769 QFontCache::Key key(def,script);
770 QFontEngine *engine = fontCache->findEngine(key);
772 const bool cacheForCommonScript = script != QFontDatabasePrivate::Script_Common
773 && (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0;
775 if (Q_LIKELY(cacheForCommonScript) && script < QChar::ScriptCount) {
777 key.script = QChar::Script_Common;
778 engine = fontCache->findEngine(key);
782 if (Q_UNLIKELY(!engine->supportsScript(QChar::Script(script)))) {
783 qCInfo(lcFontDb,
"OpenType support missing for \"%ls\", script %d",
784 qUtf16Printable(def.family()), script);
788 engine->isSmoothlyScalable = style->smoothScalable;
789 fontCache->insertEngine(key, engine);
797 if (style->key.stretch != 0 && request.stretch != 0
798 && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
799 def.stretch = (request.stretch * 100 + style->key.stretch / 2) / style->key.stretch;
800 }
else if (request.stretch == QFont::AnyStretch) {
804 engine = pfdb->fontEngine(def, size->handle);
807 if (script < QChar::ScriptCount && !engine->supportsScript(QChar::Script(script))) {
808 qCInfo(lcFontDb,
"OpenType support missing for \"%ls\", script %d",
809 qUtf16Printable(def.family()), script);
810 if (engine->ref.loadRelaxed() == 0)
815 engine->isSmoothlyScalable = style->smoothScalable;
816 fontCache->insertEngine(key, engine);
818 if (Q_LIKELY(cacheForCommonScript && !engine->symbol)) {
820 key.script = QChar::Script_Common;
821 if (!fontCache->findEngine(key))
822 fontCache->insertEngine(key, engine);
829QFontEngine *QFontDatabasePrivate::loadEngine(
int script,
const QFontDef &request,
830 QtFontFamily *family, QtFontFoundry *foundry,
831 QtFontStyle *style, QtFontSize *size)
833 QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size);
835 if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
836 Q_TRACE(QFontDatabase_loadEngine, request.families.join(QLatin1Char(
';')), request.pointSize);
838 QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
839 QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine,
840 QFontDatabasePrivate::ExtendedScript(script));
841 if (!request.fallBackFamilies.isEmpty()) {
842 QStringList fallbacks = request.fallBackFamilies;
844 QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
845 if (styleHint == QFont::AnyStyle && request.fixedPitch)
846 styleHint = QFont::TypeWriter;
848 fallbacks += fallbacksForFamily(family->name,
849 QFont::Style(style->key.style),
851 QFontDatabasePrivate::ExtendedScript(script));
853 pfMultiEngine->setFallbackFamiliesList(fallbacks);
855 engine = pfMultiEngine;
859 QFontCache::Key key(request, script, 1);
860 QFontCache::instance()->insertEngine(key, engine);
866QtFontStyle::~QtFontStyle()
871 QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
873 integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
880 const QString &styleName = QString())
885 for (
int i = 0; i < foundry->count; i++ ) {
886 QtFontStyle *style = foundry->styles[i];
888 if (!styleName.isEmpty() && styleName == style->styleName) {
894 int d = qAbs( (
int(styleKey.weight) -
int(style->key.weight)) / 10 );
896 if ( styleKey.stretch != 0 && style->key.stretch != 0 ) {
897 d += qAbs( styleKey.stretch - style->key.stretch );
900 if (styleKey.style != style->key.style) {
901 if (styleKey.style != QFont::StyleNormal && style->key.style != QFont::StyleNormal)
914 qCDebug(lcFontMatch,
" best style has distance 0x%x", dist );
915 return foundry->styles[best];
919unsigned int QFontDatabasePrivate::bestFoundry(
int script,
unsigned int score,
int styleStrategy,
920 const QtFontFamily *family,
const QString &foundry_name,
921 QtFontStyle::Key styleKey,
int pixelSize,
char pitch,
922 QtFontDesc *desc,
const QString &styleName)
927 desc->foundry =
nullptr;
928 desc->style =
nullptr;
929 desc->size =
nullptr;
931 qCDebug(lcFontMatch,
" REMARK: looking for best foundry for family '%s'%s [%d]",
932 family->name.toLatin1().constData(),
933 family->colorFont ?
" (color font)" :
"",
936 for (
int x = 0; x < family->count; ++x) {
937 QtFontFoundry *foundry = family->foundries[x];
938 if (!foundry_name.isEmpty() && foundry->name.compare(foundry_name, Qt::CaseInsensitive) != 0)
941 qCDebug(lcFontMatch,
" looking for matching style in foundry '%s' %d",
942 foundry->name.isEmpty() ?
"-- none --" : foundry->name.toLatin1().constData(), foundry->count);
944 QtFontStyle *style = bestStyle(foundry, styleKey, styleName);
946 if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) {
947 qCDebug(lcFontMatch,
" ForceOutline set, but not smoothly scalable");
952 QtFontSize *size =
nullptr;
955 if (!(styleStrategy & QFont::ForceOutline)) {
956 size = style->pixelSize(pixelSize);
958 qCDebug(lcFontMatch,
" found exact size match (%d pixels)", size->pixelSize);
959 px = size->pixelSize;
964 if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
967 qCDebug(lcFontMatch,
" found smoothly scalable font (%d pixels)", pixelSize);
973 if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
974 size = style->pixelSize(0);
976 qCDebug(lcFontMatch,
" found bitmap scalable font (%d pixels)", pixelSize);
984 unsigned int distance = ~0u;
985 for (
int x = 0; x < style->count; ++x) {
988 if (style->pixelSizes[x].pixelSize < pixelSize) {
992 d = pixelSize - style->pixelSizes[x].pixelSize + 1;
994 d = style->pixelSizes[x].pixelSize - pixelSize;
999 size = style->pixelSizes + x;
1000 qCDebug(lcFontMatch,
" best size so far: %3d (%d)", size->pixelSize, pixelSize);
1005 qCDebug(lcFontMatch,
" no size supports the script we want");
1009 if (style->bitmapScalable && ! (styleStrategy & QFont::PreferQuality) &&
1010 (distance * 10 / pixelSize) >= 2) {
1013 size = style->pixelSize(0);
1016 px = size->pixelSize;
1021 unsigned int this_score = 0x0000;
1023 PitchMismatch = 0x4000,
1024 StyleMismatch = 0x2000,
1025 BitmapScaledPenalty = 0x1000
1028 if ((pitch ==
'm' && !family->fixedPitch)
1029 || (pitch ==
'p' && family->fixedPitch))
1030 this_score += PitchMismatch;
1032 if (styleKey != style->key)
1033 this_score += StyleMismatch;
1034 if (!style->smoothScalable && px != size->pixelSize)
1035 this_score += BitmapScaledPenalty;
1036 if (px != pixelSize)
1037 this_score += qAbs(px - pixelSize);
1039 if (this_score < score) {
1040 qCDebug(lcFontMatch,
" found a match: score %x best score so far %x",
1044 desc->foundry = foundry;
1045 desc->style = style;
1048 qCDebug(lcFontMatch,
" score %x no better than best %x", this_score, score);
1057 if (familyName.isEmpty())
1059 return f->matchesFamilyName(familyName);
1063
1064
1065
1066
1067int QFontDatabasePrivate::match(
int script,
const QFontDef &request,
const QString &family_name,
1068 const QString &foundry_name, QtFontDesc *desc,
const QList<
int> &blacklistedFamilies,
1069 unsigned int *resultingScore)
1073 QtFontStyle::Key styleKey;
1074 styleKey.style = request.style;
1075 styleKey.weight = request.weight;
1077 styleKey.stretch = request.stretch ? request.stretch : 100;
1078 char pitch = request.ignorePitch ?
'*' : request.fixedPitch ?
'm' :
'p';
1081 qCDebug(lcFontMatch,
"QFontDatabasePrivate::match\n"
1083 " family: %s [%s], script: %d\n"
1085 " weight: %d, style: %d\n"
1089 family_name.isEmpty() ?
"-- first in script --" : family_name.toLatin1().constData(),
1090 foundry_name.isEmpty() ?
"-- any --" : foundry_name.toLatin1().constData(), script,
1091 request.styleName.isEmpty() ?
"-- any --" : request.styleName.toLatin1().constData(),
1092 request.weight, request.style, request.stretch, request.pixelSize, pitch);
1094 desc->family =
nullptr;
1095 desc->foundry =
nullptr;
1096 desc->style =
nullptr;
1097 desc->size =
nullptr;
1099 unsigned int score = ~0u;
1101 QMutexLocker locker(fontDatabaseMutex());
1102 QFontDatabasePrivate::ensureFontDatabase();
1104 auto writingSystem = qt_writing_system_for_script(script);
1105 if (writingSystem >= QFontDatabase::WritingSystemsCount)
1106 writingSystem = QFontDatabase::Any;
1108 auto *db = QFontDatabasePrivate::instance();
1109 for (
int x = 0; x < db->count; ++x) {
1110 if (blacklistedFamilies.contains(x))
1113 test.family = db->families[x];
1115 if (!matchFamilyName(family_name, test.family))
1117 if (!test.family->ensurePopulated())
1121 if (writingSystem != QFontDatabase::Any && !familySupportsWritingSystem(test.family, writingSystem))
1125 if (script == QFontDatabasePrivate::Script_Emoji && !test.family->colorFont)
1130 unsigned int newscore =
1131 bestFoundry(script, score, request.styleStrategy,
1132 test.family, foundry_name, styleKey, request.pixelSize, pitch,
1133 &test, request.styleName);
1134 if (test.foundry ==
nullptr && !foundry_name.isEmpty()) {
1137 newscore = bestFoundry(script, score, request.styleStrategy, test.family,
1138 QString(), styleKey, request.pixelSize,
1139 pitch, &test, request.styleName);
1142 if (newscore < score) {
1151 if (resultingScore !=
nullptr)
1152 *resultingScore = score;
1160 if (weight > QFont::Normal) {
1161 if (weight >= QFont::Black)
1162 result = QCoreApplication::translate(
"QFontDatabase",
"Black");
1163 else if (weight >= QFont::ExtraBold)
1164 result = QCoreApplication::translate(
"QFontDatabase",
"Extra Bold");
1165 else if (weight >= QFont::Bold)
1166 result = QCoreApplication::translate(
"QFontDatabase",
"Bold");
1167 else if (weight >= QFont::DemiBold)
1168 result = QCoreApplication::translate(
"QFontDatabase",
"Demi Bold");
1169 else if (weight >= QFont::Medium)
1170 result = QCoreApplication::translate(
"QFontDatabase",
"Medium",
"The Medium font weight");
1172 if (weight <= QFont::Thin)
1173 result = QCoreApplication::translate(
"QFontDatabase",
"Thin");
1174 else if (weight <= QFont::ExtraLight)
1175 result = QCoreApplication::translate(
"QFontDatabase",
"Extra Light");
1176 else if (weight <= QFont::Light)
1177 result = QCoreApplication::translate(
"QFontDatabase",
"Light");
1180 if (style == QFont::StyleItalic)
1181 result += u' ' + QCoreApplication::translate(
"QFontDatabase",
"Italic");
1182 else if (style == QFont::StyleOblique)
1183 result += u' ' + QCoreApplication::translate(
"QFontDatabase",
"Oblique");
1185 if (result.isEmpty())
1186 result = QCoreApplication::translate(
"QFontDatabase",
"Normal",
"The Normal or Regular font weight");
1188 return result.simplified();
1192
1193
1194
1195
1196QString QFontDatabase::styleString(
const QFont &font)
1198 return font.styleName().isEmpty() ? styleStringHelper(font.weight(), font.style())
1203
1204
1205
1206
1207QString QFontDatabase::styleString(
const QFontInfo &fontInfo)
1209 return fontInfo.styleName().isEmpty() ? styleStringHelper(fontInfo.weight(), fontInfo.style())
1210 : fontInfo.styleName();
1215
1216
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
1266
1267
1268
1269
1270
1273
1274
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
1315
1316
1317
1318
1319
1320
1321
1322
1323
1326
1327
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
1376
1377
1378
1379
1380
1381QFontDatabasePrivate *QFontDatabasePrivate::ensureFontDatabase()
1383 auto *d = QFontDatabasePrivate::instance();
1384 if (!d->populated) {
1388 qCDebug(lcFontDb) <<
"Populating font database";
1390 if (Q_UNLIKELY(
qGuiApp ==
nullptr || QGuiApplicationPrivate::platformIntegration() ==
nullptr))
1391 qFatal(
"QFontDatabase: Must construct a QGuiApplication before accessing QFontDatabase");
1393 auto *platformFontDatabase = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
1394 platformFontDatabase->populateFontDatabase();
1396 for (
int i = 0; i < d->applicationFonts.size(); i++) {
1397 auto *font = &d->applicationFonts[i];
1398 if (!font->isNull() && !font->isPopulated())
1399 platformFontDatabase->addApplicationFont(font->data, font->fileName, font);
1405 d->populated =
true;
1411
1412
1413
1414
1415
1416
1417QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems()
1419 QMutexLocker locker(fontDatabaseMutex());
1420 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1422 quint64 writingSystemsFound = 0;
1423 static_assert(WritingSystemsCount < 64);
1425 for (
int i = 0; i < d->count; ++i) {
1426 QtFontFamily *family = d->families[i];
1427 if (!family->ensurePopulated())
1430 if (family->count == 0)
1432 for (uint x = Latin; x < uint(WritingSystemsCount); ++x) {
1433 if (family->writingSystems[x] & QtFontFamily::Supported)
1434 writingSystemsFound |= quint64(1) << x;
1441 QList<WritingSystem> list;
1442 list.reserve(qPopulationCount(writingSystemsFound));
1443 for (uint x = Latin ; x < uint(WritingSystemsCount); ++x) {
1444 if (writingSystemsFound & (quint64(1) << x))
1445 list.push_back(WritingSystem(x));
1452
1453
1454
1455
1456
1457QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems(
const QString &family)
1459 QString familyName, foundryName;
1460 parseFontName(family, foundryName, familyName);
1462 QMutexLocker locker(fontDatabaseMutex());
1463 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1465 QList<WritingSystem> list;
1466 QtFontFamily *f = d->family(familyName);
1467 if (!f || f->count == 0)
1470 for (
int x = Latin; x < WritingSystemsCount; ++x) {
1471 const WritingSystem writingSystem = WritingSystem(x);
1472 if (f->writingSystems[writingSystem] & QtFontFamily::Supported)
1473 list.append(writingSystem);
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489QStringList QFontDatabase::families(WritingSystem writingSystem)
1491 QMutexLocker locker(fontDatabaseMutex());
1492 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1495 for (
int i = 0; i < d->count; i++) {
1496 QtFontFamily *f = d->families[i];
1497 if (f->populated && f->count == 0)
1499 if (writingSystem != Any) {
1500 if (!f->ensurePopulated())
1502 if (f->writingSystems[writingSystem] != QtFontFamily::Supported)
1505 if (!f->populated || f->count == 1) {
1506 flist.append(f->name);
1508 for (
int j = 0; j < f->count; j++) {
1509 QString str = f->name;
1510 QString foundry = f->foundries[j]->name;
1511 if (!foundry.isEmpty()) {
1524
1525
1526
1527
1528
1529
1530QStringList QFontDatabase::styles(
const QString &family)
1532 QString familyName, foundryName;
1533 parseFontName(family, foundryName, familyName);
1535 QMutexLocker locker(fontDatabaseMutex());
1536 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1539 QtFontFamily *f = d->family(familyName);
1543 QtFontFoundry allStyles(foundryName);
1544 for (
int j = 0; j < f->count; j++) {
1545 QtFontFoundry *foundry = f->foundries[j];
1546 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1547 for (
int k = 0; k < foundry->count; k++) {
1548 QtFontStyle::Key ke(foundry->styles[k]->key);
1551 foundry->styles[k]->styleName,
1552 QtFontFoundry::AddWhenMissing);
1557 l.reserve(allStyles.count);
1558 for (
int i = 0; i < allStyles.count; i++) {
1559 l.append(allStyles.styles[i]->styleName.isEmpty() ?
1560 styleStringHelper(allStyles.styles[i]->key.weight,
1561 (QFont::Style)allStyles.styles[i]->key.style) :
1562 allStyles.styles[i]->styleName);
1568
1569
1570
1572bool QFontDatabase::isFixedPitch(
const QString &family,
1573 const QString &style)
1577 QString familyName, foundryName;
1578 parseFontName(family, foundryName, familyName);
1580 QMutexLocker locker(fontDatabaseMutex());
1581 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1583 QtFontFamily *f = d->family(familyName);
1584 return (f && f->fixedPitch);
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597bool QFontDatabase::isBitmapScalable(
const QString &family,
1598 const QString &style)
1600 QString familyName, foundryName;
1601 parseFontName(family, foundryName, familyName);
1603 QMutexLocker locker(fontDatabaseMutex());
1604 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1606 QtFontFamily *f = d->family(familyName);
1610 QtFontStyle::Key styleKey(style);
1611 for (
int j = 0; j < f->count; j++) {
1612 QtFontFoundry *foundry = f->foundries[j];
1613 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1614 for (
int k = 0; k < foundry->count; k++)
1615 if ((style.isEmpty() ||
1616 foundry->styles[k]->styleName == style ||
1617 foundry->styles[k]->key == styleKey)
1618 && foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
1628
1629
1630
1631
1632
1633
1634
1635bool QFontDatabase::isSmoothlyScalable(
const QString &family,
const QString &style)
1637 QString familyName, foundryName;
1638 parseFontName(family, foundryName, familyName);
1640 QMutexLocker locker(fontDatabaseMutex());
1641 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1643 QtFontFamily *f = d->family(familyName);
1645 for (
int i = 0; i < d->count; i++) {
1646 if (d->families[i]->matchesFamilyName(familyName)) {
1648 if (f->ensurePopulated())
1656 const QtFontStyle::Key styleKey(style);
1657 for (
int j = 0; j < f->count; j++) {
1658 QtFontFoundry *foundry = f->foundries[j];
1659 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1660 for (
int k = 0; k < foundry->count; k++) {
1661 const QtFontStyle *fontStyle = foundry->styles[k];
1662 const bool smoothScalable =
1663 fontStyle->smoothScalable
1664 && ((style.isEmpty()
1665 || fontStyle->styleName == style
1666 || fontStyle->key == styleKey)
1667 || (fontStyle->styleName.isEmpty()
1668 && style == styleStringHelper(fontStyle->key.weight,
1669 QFont::Style(fontStyle->key.style))));
1679
1680
1681
1682
1683
1684bool QFontDatabase::isScalable(
const QString &family,
1685 const QString &style)
1687 QMutexLocker locker(fontDatabaseMutex());
1688 if (isSmoothlyScalable(family, style))
1690 return isBitmapScalable(family, style);
1695
1696
1697
1698
1699
1700QList<
int> QFontDatabase::pointSizes(
const QString &family,
1701 const QString &styleName)
1703 if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable())
1704 return standardSizes();
1706 QString familyName, foundryName;
1707 parseFontName(family, foundryName, familyName);
1709 QMutexLocker locker(fontDatabaseMutex());
1710 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1714 QtFontFamily *fam = d->family(familyName);
1715 if (!fam)
return sizes;
1718 const int dpi = qt_defaultDpiY();
1720 QtFontStyle::Key styleKey(styleName);
1721 for (
int j = 0; j < fam->count; j++) {
1722 QtFontFoundry *foundry = fam->foundries[j];
1723 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1724 QtFontStyle *style = foundry->style(styleKey, styleName);
1725 if (!style)
continue;
1727 if (style->smoothScalable)
1728 return standardSizes();
1730 for (
int l = 0; l < style->count; l++) {
1731 const QtFontSize *size = style->pixelSizes + l;
1734 const int pointSize = qRound(size->pixelSize * 72.0 / dpi);
1735 if (! sizes.contains(pointSize))
1736 sizes.append(pointSize);
1742 std::sort(sizes.begin(), sizes.end());
1747
1748
1749
1750
1751
1752QFont QFontDatabase::font(
const QString &family,
const QString &style,
1755 QString familyName, foundryName;
1756 parseFontName(family, foundryName, familyName);
1757 QMutexLocker locker(fontDatabaseMutex());
1758 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1760 QtFontFoundry allStyles(foundryName);
1761 QtFontFamily *f = d->family(familyName);
1762 if (!f)
return QGuiApplication::font();
1764 for (
int j = 0; j < f->count; j++) {
1765 QtFontFoundry *foundry = f->foundries[j];
1766 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1767 for (
int k = 0; k < foundry->count; k++) {
1768 allStyles.style(foundry->styles[k]->key,
1769 foundry->styles[k]->styleName,
1770 QtFontFoundry::AddWhenMissing);
1775 QtFontStyle::Key styleKey(style);
1776 QtFontStyle *s = bestStyle(&allStyles, styleKey, style);
1779 return QGuiApplication::font();
1781 QFont fnt(QStringList{family}, pointSize, s->key.weight);
1782 fnt.setStyle((QFont::Style)s->key.style);
1783 if (!s->styleName.isEmpty())
1784 fnt.setStyleName(s->styleName);
1790
1791
1792
1793
1794
1795
1796
1797QList<
int> QFontDatabase::smoothSizes(
const QString &family,
1798 const QString &styleName)
1800 if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable())
1801 return standardSizes();
1803 QString familyName, foundryName;
1804 parseFontName(family, foundryName, familyName);
1806 QMutexLocker locker(fontDatabaseMutex());
1807 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1811 QtFontFamily *fam = d->family(familyName);
1815 const int dpi = qt_defaultDpiY();
1817 QtFontStyle::Key styleKey(styleName);
1818 for (
int j = 0; j < fam->count; j++) {
1819 QtFontFoundry *foundry = fam->foundries[j];
1820 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1821 QtFontStyle *style = foundry->style(styleKey, styleName);
1822 if (!style)
continue;
1824 if (style->smoothScalable)
1825 return QFontDatabase::standardSizes();
1827 for (
int l = 0; l < style->count; l++) {
1828 const QtFontSize *size = style->pixelSizes + l;
1831 const int pointSize = qRound(size->pixelSize * 72.0 / dpi);
1832 if (! sizes.contains(pointSize))
1833 sizes.append(pointSize);
1839 std::sort(sizes.begin(), sizes.end());
1845
1846
1847
1848
1849QList<
int> QFontDatabase::standardSizes()
1851 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->standardSizes();
1856
1857
1858
1859
1860
1861bool QFontDatabase::italic(
const QString &family,
const QString &style)
1863 QString familyName, foundryName;
1864 parseFontName(family, foundryName, familyName);
1866 QMutexLocker locker(fontDatabaseMutex());
1867 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1869 QtFontFoundry allStyles(foundryName);
1870 QtFontFamily *f = d->family(familyName);
1871 if (!f)
return false;
1873 for (
int j = 0; j < f->count; j++) {
1874 QtFontFoundry *foundry = f->foundries[j];
1875 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1876 for (
int k = 0; k < foundry->count; k++) {
1877 allStyles.style(foundry->styles[k]->key,
1878 foundry->styles[k]->styleName,
1879 QtFontFoundry::AddWhenMissing);
1884 QtFontStyle::Key styleKey(style);
1885 QtFontStyle *s = allStyles.style(styleKey, style);
1886 return s && s->key.style == QFont::StyleItalic;
1891
1892
1893
1894
1895
1896bool QFontDatabase::bold(
const QString &family,
1897 const QString &style)
1899 QString familyName, foundryName;
1900 parseFontName(family, foundryName, familyName);
1902 QMutexLocker locker(fontDatabaseMutex());
1903 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1905 QtFontFoundry allStyles(foundryName);
1906 QtFontFamily *f = d->family(familyName);
1907 if (!f)
return false;
1909 for (
int j = 0; j < f->count; j++) {
1910 QtFontFoundry *foundry = f->foundries[j];
1911 if (foundryName.isEmpty() ||
1912 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1913 for (
int k = 0; k < foundry->count; k++) {
1914 allStyles.style(foundry->styles[k]->key,
1915 foundry->styles[k]->styleName,
1916 QtFontFoundry::AddWhenMissing);
1921 QtFontStyle::Key styleKey(style);
1922 QtFontStyle *s = allStyles.style(styleKey, style);
1923 return s && s->key.weight >= QFont::Bold;
1928
1929
1930
1931
1932
1933
1934int QFontDatabase::weight(
const QString &family,
1935 const QString &style)
1937 QString familyName, foundryName;
1938 parseFontName(family, foundryName, familyName);
1940 QMutexLocker locker(fontDatabaseMutex());
1941 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1943 QtFontFoundry allStyles(foundryName);
1944 QtFontFamily *f = d->family(familyName);
1947 for (
int j = 0; j < f->count; j++) {
1948 QtFontFoundry *foundry = f->foundries[j];
1949 if (foundryName.isEmpty() ||
1950 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1951 for (
int k = 0; k < foundry->count; k++) {
1952 allStyles.style(foundry->styles[k]->key,
1953 foundry->styles[k]->styleName,
1954 QtFontFoundry::AddWhenMissing);
1959 QtFontStyle::Key styleKey(style);
1960 QtFontStyle *s = allStyles.style(styleKey, style);
1961 return s ? s->key.weight : -1;
1966bool QFontDatabase::hasFamily(
const QString &family)
1968 QString parsedFamily, foundry;
1969 parseFontName(family, foundry, parsedFamily);
1970 const QString familyAlias = QFontDatabasePrivate::resolveFontFamilyAlias(parsedFamily);
1972 QMutexLocker locker(fontDatabaseMutex());
1973 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1975 for (
int i = 0; i < d->count; i++) {
1976 QtFontFamily *f = d->families[i];
1977 if (f->populated && f->count == 0)
1979 if (familyAlias.compare(f->name, Qt::CaseInsensitive) == 0)
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999bool QFontDatabase::isPrivateFamily(
const QString &family)
2001 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->isPrivateFontFamily(family);
2006
2007
2008
2009QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
2011 const char *name =
nullptr;
2012 switch (writingSystem) {
2014 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Any");
2017 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Latin");
2020 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Greek");
2023 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Cyrillic");
2026 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Armenian");
2029 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Hebrew");
2032 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Arabic");
2035 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Syriac");
2038 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Thaana");
2041 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Devanagari");
2044 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Bengali");
2047 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Gurmukhi");
2050 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Gujarati");
2053 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Oriya");
2056 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Tamil");
2059 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Telugu");
2062 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Kannada");
2065 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Malayalam");
2068 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Sinhala");
2071 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Thai");
2074 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Lao");
2077 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Tibetan");
2080 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Myanmar");
2083 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Georgian");
2086 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Khmer");
2088 case SimplifiedChinese:
2089 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Simplified Chinese");
2091 case TraditionalChinese:
2092 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Traditional Chinese");
2095 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Japanese");
2098 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Korean");
2101 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Vietnamese");
2104 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Symbol");
2107 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Ogham");
2110 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Runic");
2113 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"N'Ko");
2116 Q_ASSERT_X(
false,
"QFontDatabase::writingSystemName",
"invalid 'writingSystem' parameter");
2119 return QCoreApplication::translate(
"QFontDatabase", name);
2123
2124
2125QString QFontDatabase::writingSystemSample(WritingSystem writingSystem)
2127 return [&]() -> QStringView {
2128 switch (writingSystem) {
2129 case QFontDatabase::Any:
2130 case QFontDatabase::Symbol:
2133 case QFontDatabase::Latin:
2136 return u"Aa\x00C3\x00E1Zz";
2137 case QFontDatabase::Greek:
2138 return u"\x0393\x03B1\x03A9\x03C9";
2139 case QFontDatabase::Cyrillic:
2140 return u"\x0414\x0434\x0436\x044f";
2141 case QFontDatabase::Armenian:
2142 return u"\x053f\x054f\x056f\x057f";
2143 case QFontDatabase::Hebrew:
2144 return u"\x05D0\x05D1\x05D2\x05D3";
2145 case QFontDatabase::Arabic:
2146 return u"\x0623\x0628\x062C\x062F\x064A\x0629\x0020\x0639\x0631\x0628\x064A\x0629";
2147 case QFontDatabase::Syriac:
2148 return u"\x0715\x0725\x0716\x0726";
2149 case QFontDatabase::Thaana:
2150 return u"\x0784\x0794\x078c\x078d";
2151 case QFontDatabase::Devanagari:
2152 return u"\x0905\x0915\x0925\x0935";
2153 case QFontDatabase::Bengali:
2154 return u"\x0986\x0996\x09a6\x09b6";
2155 case QFontDatabase::Gurmukhi:
2156 return u"\x0a05\x0a15\x0a25\x0a35";
2157 case QFontDatabase::Gujarati:
2158 return u"\x0a85\x0a95\x0aa5\x0ab5";
2159 case QFontDatabase::Oriya:
2160 return u"\x0b06\x0b16\x0b2b\x0b36";
2161 case QFontDatabase::Tamil:
2162 return u"\x0b89\x0b99\x0ba9\x0bb9";
2163 case QFontDatabase::Telugu:
2164 return u"\x0c05\x0c15\x0c25\x0c35";
2165 case QFontDatabase::Kannada:
2166 return u"\x0c85\x0c95\x0ca5\x0cb5";
2167 case QFontDatabase::Malayalam:
2168 return u"\x0d05\x0d15\x0d25\x0d35";
2169 case QFontDatabase::Sinhala:
2170 return u"\x0d90\x0da0\x0db0\x0dc0";
2171 case QFontDatabase::Thai:
2172 return u"\x0e02\x0e12\x0e22\x0e32";
2173 case QFontDatabase::Lao:
2174 return u"\x0e8d\x0e9d\x0ead\x0ebd";
2175 case QFontDatabase::Tibetan:
2176 return u"\x0f00\x0f01\x0f02\x0f03";
2177 case QFontDatabase::Myanmar:
2178 return u"\x1000\x1001\x1002\x1003";
2179 case QFontDatabase::Georgian:
2180 return u"\x10a0\x10b0\x10c0\x10d0";
2181 case QFontDatabase::Khmer:
2182 return u"\x1780\x1790\x17b0\x17c0";
2183 case QFontDatabase::SimplifiedChinese:
2184 return u"\x4e2d\x6587\x8303\x4f8b";
2185 case QFontDatabase::TraditionalChinese:
2186 return u"\x4e2d\x6587\x7bc4\x4f8b";
2187 case QFontDatabase::Japanese:
2188 return u"\x30b5\x30f3\x30d7\x30eb\x3067\x3059";
2189 case QFontDatabase::Korean:
2190 return u"\xac00\xac11\xac1a\xac2f";
2191 case QFontDatabase::Vietnamese:
2192 return u"\x1ED7\x1ED9\x1ED1\x1ED3";
2193 case QFontDatabase::Ogham:
2194 return u"\x1681\x1682\x1683\x1684";
2195 case QFontDatabase::Runic:
2196 return u"\x16a0\x16a1\x16a2\x16a3";
2197 case QFontDatabase::Nko:
2198 return u"\x7ca\x7cb\x7cc\x7cd";
2205void QFontDatabasePrivate::parseFontName(
const QString &name, QString &foundry, QString &family)
2207 QT_PREPEND_NAMESPACE(parseFontName)(name, foundry, family);
2213 QMutexLocker locker(fontDatabaseMutex());
2214 return QFontDatabasePrivate::instance()->applicationFonts.value(index).data;
2217int QFontDatabasePrivate::addAppFont(
const QByteArray &fontData,
const QString &fileName)
2219 QFontDatabasePrivate::ApplicationFont font;
2220 font.data = fontData;
2221 font.fileName = fileName;
2223 Q_TRACE(QFontDatabasePrivate_addAppFont, fileName);
2226 for (i = 0; i < applicationFonts.size(); ++i)
2227 if (applicationFonts.at(i).isNull())
2229 if (i >= applicationFonts.size()) {
2230 applicationFonts.append(ApplicationFont());
2231 i = applicationFonts.size() - 1;
2234 if (font.fileName.isEmpty() && !fontData.isEmpty())
2235 font.fileName =
":qmemoryfonts/"_L1 + QString::number(i);
2237 auto *platformFontDatabase = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
2238 platformFontDatabase->addApplicationFont(font.data, font.fileName, &font);
2239 if (font.properties.isEmpty())
2242 applicationFonts[i] = font;
2246 QFontCache::instance()->clear();
2248 fallbacksCache.clear();
2250 emit
qApp->fontDatabaseChanged();
2255bool QFontDatabasePrivate::isApplicationFont(
const QString &fileName)
2257 for (
int i = 0; i < applicationFonts.size(); ++i)
2258 if (applicationFonts.at(i).fileName == fileName)
2263void QFontDatabasePrivate::setApplicationFallbackFontFamilies(ExtendedScript script,
const QStringList &familyNames)
2265 applicationFallbackFontFamiliesHash[script] = familyNames;
2267 QFontCache::instance()->clear();
2268 fallbacksCache.clear();
2271QStringList QFontDatabasePrivate::applicationFallbackFontFamilies(ExtendedScript script)
2273 return applicationFallbackFontFamiliesHash.value(script);
2276bool QFontDatabasePrivate::removeApplicationFallbackFontFamily(ExtendedScript script,
const QString &familyName)
2278 auto it = applicationFallbackFontFamiliesHash.find(script);
2279 if (it != applicationFallbackFontFamiliesHash.end()) {
2280 if (it->removeAll(familyName) > 0) {
2282 it = applicationFallbackFontFamiliesHash.erase(it);
2283 QFontCache::instance()->clear();
2284 fallbacksCache.clear();
2292void QFontDatabasePrivate::addApplicationFallbackFontFamily(ExtendedScript script,
const QString &familyName)
2294 auto it = applicationFallbackFontFamiliesHash.find(script);
2295 if (it == applicationFallbackFontFamiliesHash.end())
2296 it = applicationFallbackFontFamiliesHash.insert(script, QStringList{});
2298 it->prepend(familyName);
2300 QFontCache::instance()->clear();
2301 fallbacksCache.clear();
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322int QFontDatabase::addApplicationFont(
const QString &fileName)
2325 if (!QFileInfo(fileName).isNativePath()) {
2327 if (!f.open(QIODevice::ReadOnly))
2330 Q_TRACE(QFontDatabase_addApplicationFont, fileName);
2334 QMutexLocker locker(fontDatabaseMutex());
2335 return QFontDatabasePrivate::instance()->addAppFont(data, fileName);
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350int QFontDatabase::addApplicationFontFromData(
const QByteArray &fontData)
2352 QMutexLocker locker(fontDatabaseMutex());
2353 return QFontDatabasePrivate::instance()->addAppFont(fontData, QString() );
2357
2358
2359
2360
2361
2362
2363
2364QStringList QFontDatabase::applicationFontFamilies(
int id)
2366 QMutexLocker locker(fontDatabaseMutex());
2367 auto *d = QFontDatabasePrivate::instance();
2370 ret.reserve(d->applicationFonts.value(id).properties.size());
2372 for (
const auto &properties : d->applicationFonts.value(id).properties)
2373 ret.append(properties.familyName);
2379
2380
2381
2382
2383
2384
2385
2387QFont QFontDatabase::systemFont(QFontDatabase::SystemFont type)
2389 const QFont *font =
nullptr;
2390 if (
const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
2393 font = theme->font(QPlatformTheme::SystemFont);
2396 font = theme->font(QPlatformTheme::FixedFont);
2399 font = theme->font(QPlatformTheme::TitleBarFont);
2401 case SmallestReadableFont:
2402 font = theme->font(QPlatformTheme::MiniFont);
2409 else if (QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration())
2410 return integration->fontDatabase()->defaultFont();
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426bool QFontDatabase::removeApplicationFont(
int handle)
2428 QMutexLocker locker(fontDatabaseMutex());
2430 auto *db = QFontDatabasePrivate::instance();
2431 if (handle < 0 || handle >= db->applicationFonts.size())
2434 db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452bool QFontDatabase::removeAllApplicationFonts()
2454 QMutexLocker locker(fontDatabaseMutex());
2456 auto *db = QFontDatabasePrivate::instance();
2457 if (!db || db->applicationFonts.isEmpty())
2460 db->applicationFonts.clear();
2466
2467
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
2497void QFontDatabase::addApplicationFallbackFontFamily(QChar::Script script,
const QString &familyName)
2499 QMutexLocker locker(fontDatabaseMutex());
2501 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2502 qCWarning(lcFontDb) <<
"Invalid script passed to addApplicationFallbackFontFamily:" << script;
2506 if (script == QChar::Script_Latin)
2507 script = QChar::Script_Common;
2509 auto *db = QFontDatabasePrivate::instance();
2510 db->addApplicationFallbackFontFamily(QFontDatabasePrivate::ExtendedScript(script), familyName);
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523bool QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script script,
const QString &familyName)
2525 QMutexLocker locker(fontDatabaseMutex());
2527 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2528 qCWarning(lcFontDb) <<
"Invalid script passed to removeApplicationFallbackFontFamily:" << script;
2532 if (script == QChar::Script_Latin)
2533 script = QChar::Script_Common;
2535 auto *db = QFontDatabasePrivate::instance();
2536 return db->removeApplicationFallbackFontFamily(QFontDatabasePrivate::ExtendedScript(script),
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553void QFontDatabase::setApplicationFallbackFontFamilies(QChar::Script script,
const QStringList &familyNames)
2555 QMutexLocker locker(fontDatabaseMutex());
2557 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2558 qCWarning(lcFontDb) <<
"Invalid script passed to setApplicationFallbackFontFamilies:" << script;
2562 if (script == QChar::Script_Latin)
2563 script = QChar::Script_Common;
2565 auto *db = QFontDatabasePrivate::instance();
2566 db->setApplicationFallbackFontFamilies(QFontDatabasePrivate::ExtendedScript(script),
2571
2572
2573
2574
2575
2576
2577
2578QStringList QFontDatabase::applicationFallbackFontFamilies(QChar::Script script)
2580 QMutexLocker locker(fontDatabaseMutex());
2582 if (script >= QChar::ScriptCount) {
2583 qCWarning(lcFontDb) <<
"Invalid script passed to applicationFallbackFontFamilies:" << script;
2584 return QStringList{};
2587 if (script == QChar::Script_Latin)
2588 script = QChar::Script_Common;
2590 auto *db = QFontDatabasePrivate::instance();
2591 return db->applicationFallbackFontFamilies(QFontDatabasePrivate::ExtendedScript(script));
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605void QFontDatabase::addApplicationEmojiFontFamily(
const QString &familyName)
2607 QMutexLocker locker(fontDatabaseMutex());
2608 auto *db = QFontDatabasePrivate::instance();
2609 db->addApplicationFallbackFontFamily(QFontDatabasePrivate::Script_Emoji, familyName);
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622bool QFontDatabase::removeApplicationEmojiFontFamily(
const QString &familyName)
2624 QMutexLocker locker(fontDatabaseMutex());
2625 auto *db = QFontDatabasePrivate::instance();
2626 return db->removeApplicationFallbackFontFamily(QFontDatabasePrivate::Script_Emoji,
2631
2632
2633
2634
2635
2636
2637void QFontDatabase::setApplicationEmojiFontFamilies(
const QStringList &familyNames)
2639 QMutexLocker locker(fontDatabaseMutex());
2640 auto *db = QFontDatabasePrivate::instance();
2641 db->setApplicationFallbackFontFamilies(QFontDatabasePrivate::Script_Emoji,
2646
2647
2648
2649
2650
2651
2652QStringList QFontDatabase::applicationEmojiFontFamilies()
2654 QMutexLocker locker(fontDatabaseMutex());
2655 auto *db = QFontDatabasePrivate::instance();
2656 return db->applicationFallbackFontFamilies(QFontDatabasePrivate::Script_Emoji);
2660
2661
2662QFontEngine *QFontDatabasePrivate::findFont(
const QFontDef &req,
2664 bool preferScriptOverFamily)
2666 QMutexLocker locker(fontDatabaseMutex());
2667 ensureFontDatabase();
2669 QFontEngine *engine;
2672 const QFontDef request =
static_cast<QWindowsFontDatabaseBase *>(
2673 QGuiApplicationPrivate::platformIntegration()->fontDatabase())
2674 ->sanitizeRequest(req);
2676 const QFontDef &request = req;
2679#if defined(QT_BUILD_INTERNAL)
2681 if (qt_enable_test_font && request.family() ==
"__Qt__Box__Engine__"_L1) {
2682 engine =
new QTestFontEngine(request.pixelSize);
2683 engine->fontDef = request;
2688 QFontCache *fontCache = QFontCache::instance();
2693 bool multi = !(request.styleStrategy & QFont::NoFontMerging);
2694 QFontCache::Key key(request, script, multi ? 1 : 0);
2695 engine = fontCache->findEngine(key);
2697 qCDebug(lcFontMatch,
"Cache hit level 1");
2701 if (request.pixelSize > 0xffff) {
2703 qCDebug(lcFontMatch,
"Rejecting request for pixel size %g2, returning box engine",
double(request.pixelSize));
2704 return new QFontEngineBox(32);
2707 QString family_name, foundry_name;
2708 const QString requestFamily = request.families.at(0);
2709 parseFontName(requestFamily, foundry_name, family_name);
2711 QList<
int> blackListed;
2712 unsigned int score = UINT_MAX;
2723 qCDebug(lcFontMatch,
"Family name match pass: Looking for family name '%s'%s", qPrintable(family_name),
2724 script == QFontDatabasePrivate::Script_Emoji ?
" (color font required)" :
"");
2725 int index = match(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed, &score);
2730 if (score > 0 && QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamilyAliases(family_name)) {
2731 qCDebug(lcFontMatch,
"Alias match pass: Imperfect result and aliases populated, so trying again%s",
2732 script == QFontDatabasePrivate::Script_Emoji ?
" (color font required)" :
"");
2734 index = match(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
2742 if (index < 0 && !multi && !preferScriptOverFamily) {
2743 qCDebug(lcFontMatch,
"NoFontMerging pass: Font not found with requested script, but we try to load it anyway");
2744 index = match(QChar::Script_Common, request, family_name, foundry_name, &desc, blackListed);
2748 QFontDef fontDef = request;
2751 if (fontDef.families.isEmpty())
2752 fontDef.families = QStringList(desc.family->name);
2754 engine = loadEngine(script, fontDef, desc.family, desc.foundry, desc.style, desc.size);
2757 initFontDef(desc, request, &engine->fontDef, multi);
2759 qCDebug(lcFontMatch,
"Failed to create font engine for font '%s'. Blacklisting %d",
2760 qPrintable(desc.family->name), index);
2761 blackListed.append(index);
2764 qCDebug(lcFontMatch,
" NO MATCH FOUND\n");
2772 if (!requestFamily.isEmpty()) {
2773 qCDebug(lcFontMatch,
"Fallbacks pass: Looking for a fallback matching script %d", script);
2774 QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
2775 if (styleHint == QFont::AnyStyle && request.fixedPitch)
2776 styleHint = QFont::TypeWriter;
2778 QStringList fallbacks = request.fallBackFamilies
2779 + fallbacksForFamily(requestFamily,
2780 QFont::Style(request.style),
2782 QFontDatabasePrivate::ExtendedScript(script));
2783 if (script > QChar::Script_Common)
2784 fallbacks += QString();
2786 auto findMatchingFallback = [&fallbacks,
2791 &request](
int lookupScript,
int cacheScript) {
2792 QFontEngine *engine =
nullptr;
2793 for (
int i = 0; !engine && i < fallbacks.size(); i++) {
2794 QFontDef def = request;
2796 def.families = QStringList(fallbacks.at(i));
2797 QFontCache::Key key(def, cacheScript, multi ? 1 : 0);
2798 engine = fontCache->findEngine(key);
2802 index = match(lookupScript,
2810 QFontDef loadDef = def;
2811 if (loadDef.families.isEmpty())
2812 loadDef.families = QStringList(desc.family->name);
2813 engine = loadEngine(cacheScript,
2820 initFontDef(desc, loadDef, &engine->fontDef, multi);
2822 qCDebug(lcFontMatch,
"Failed to create font engine for fallback %d (%s). Blacklisting %d",
2823 i, qPrintable(desc.family->name), index);
2824 blackListed.append(index);
2827 }
while (index >= 0 && !engine);
2834 engine = findMatchingFallback(multi && script != QFontDatabasePrivate::Script_Emoji
2835 ? QChar::Script_Common
2842 if (!engine && script == QFontDatabasePrivate::Script_Emoji) {
2843 qCDebug(lcFontMatch,
"No color fonts found on system. Doing final fallback match.");
2847 if (!requestFamily.isEmpty())
2848 fallbacks.prepend(requestFamily);
2849 engine = findMatchingFallback(QChar::Script_Common, script);
2854 engine =
new QFontEngineBox(request.pixelSize);
2855 qCDebug(lcFontMatch,
"returning box engine");
2862void QFontDatabasePrivate::load(
const QFontPrivate *d,
int script)
2864 QFontDef req = d->request;
2866 if (req.pixelSize == -1) {
2867 req.pixelSize = std::floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100;
2868 req.pixelSize = qRound(req.pixelSize);
2871 if (req.pointSize < 0 && d->dpi > 0)
2872 req.pointSize = req.pixelSize*72.0/d->dpi;
2875 const QStringList fallBackFamilies = familyList(req);
2877 if (!d->engineData) {
2878 QFontCache *fontCache = QFontCache::instance();
2882 if (!d->request.families.isEmpty())
2883 req.families = fallBackFamilies;
2885 d->engineData = fontCache->findEngineData(req);
2886 if (!d->engineData) {
2888 d->engineData =
new QFontEngineData;
2889 fontCache->insertEngineData(req, d->engineData);
2891 d->engineData->ref.ref();
2895 if (d->engineData->engines[script])
2898 QFontEngine *fe =
nullptr;
2900 Q_TRACE(QFontDatabase_load, req.families.join(QLatin1Char(
';')), req.pointSize);
2902 req.fallBackFamilies = fallBackFamilies;
2903 if (!req.fallBackFamilies.isEmpty())
2904 req.families = QStringList(req.fallBackFamilies.takeFirst());
2907 QStringList family_list;
2909 if (!req.families.isEmpty()) {
2911 family_list << req.families.at(0);
2914 const auto families = QGuiApplication::font().families();
2915 if (!families.isEmpty()) {
2916 QString defaultFamily = families.first();
2917 if (! family_list.contains(defaultFamily))
2918 family_list << defaultFamily;
2924 family_list << QString();
2926 QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
2927 for (; !fe && it != end; ++it) {
2928 req.families = QStringList(*it);
2930 fe = QFontDatabasePrivate::findFont(req, script);
2932 if (fe->type() == QFontEngine::Box && !req.families.at(0).isEmpty()) {
2933 if (fe->ref.loadRelaxed() == 0)
2938 fe->fontDef.pointSize = qreal(
double((fe->fontDef.pixelSize * 72) / d->dpi));
2943 req.fallBackFamilies.clear();
2947 if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
2948 for (
int i = 0; i < QFontDatabasePrivate::ScriptCount; ++i) {
2949 if (!d->engineData->engines[i]) {
2950 d->engineData->engines[i] = fe;
2955 d->engineData->engines[script] = fe;
2960QString QFontDatabasePrivate::resolveFontFamilyAlias(
const QString &family)
2962 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->resolveFontFamilyAlias(family);
2965Q_GUI_EXPORT
QStringList qt_sort_families_by_writing_system(QFontDatabasePrivate::ExtendedScript script,
2966 const QStringList &families)
2968 size_t writingSystem = qt_writing_system_for_script(script);
2969 if (script != QFontDatabasePrivate::Script_Emoji
2970 && (writingSystem == QFontDatabase::Any
2971 || writingSystem >= QFontDatabase::WritingSystemsCount)) {
2975 auto *db = QFontDatabasePrivate::instance();
2976 QMultiMap<uint, QString> supported;
2977 for (
int i = 0; i < families.size(); ++i) {
2978 const QString &family = families.at(i);
2980 QtFontFamily *testFamily =
nullptr;
2981 for (
int x = 0; x < db->count; ++x) {
2982 if (Q_UNLIKELY(matchFamilyName(family, db->families[x]))) {
2983 testFamily = db->families[x];
2984 if (testFamily->ensurePopulated())
2990 if (testFamily ==
nullptr
2991 || (script == QFontDatabasePrivate::Script_Emoji && !testFamily->colorFont)
2992 || (script != QFontDatabasePrivate::Script_Emoji && !familySupportsWritingSystem(testFamily, writingSystem))) {
2996 supported.insert(order, family);
2999 return supported.values();
3004#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,...)