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;
518 family_list << req.families;
520 for (
int i = 0, size = family_list.size(); i < size; ++i)
521 family_list += QFont::substitutes(family_list.at(i));
531 auto *db = QFontDatabasePrivate::instance();
532 db->fallbacksCache.clear();
539 return fontDatabaseMutex();
542QFontDatabasePrivate *QFontDatabasePrivate::instance()
544 static QFontDatabasePrivate instance;
549 const QString &foundryname,
int weight,
550 QFont::Style style,
int stretch,
bool antialiased,
551 bool scalable,
int pixelSize,
bool fixedPitch,
bool colorFont,
552 const QSupportedWritingSystems &writingSystems,
void *handle)
554 auto *d = QFontDatabasePrivate::instance();
555 qCDebug(lcFontDb) <<
"Adding font: familyName" << familyName <<
"stylename" << stylename <<
"weight" << weight
556 <<
"style" << style <<
"pixelSize" << pixelSize <<
"antialiased" << antialiased <<
"fixed" << fixedPitch <<
"colorFont" << colorFont;
557 QtFontStyle::Key styleKey;
558 styleKey.style = style;
559 styleKey.weight = weight;
560 styleKey.stretch = stretch;
561 QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::EnsureCreated);
562 f->fixedPitch = fixedPitch;
563 f->colorFont = colorFont;
565 for (
int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
566 if (writingSystems.supported(QFontDatabase::WritingSystem(i)))
567 f->writingSystems[i] = QtFontFamily::Supported;
570 QtFontFoundry *foundry = f->foundry(foundryname,
true);
571 QtFontStyle *fontStyle = foundry->style(styleKey,
573 QtFontFoundry::StyleRetrievalFlags::AllRetrievalFlags);
574 fontStyle->smoothScalable = scalable;
575 fontStyle->antialiased = antialiased;
576 QtFontSize *size = fontStyle->pixelSize(pixelSize ? pixelSize :
SMOOTH_SCALABLE,
true);
578 QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
580 integration->fontDatabase()->releaseHandle(size->handle);
582 size->handle = handle;
588 qCDebug(lcFontDb) <<
"Registering family" << familyName;
591 QFontDatabasePrivate::instance()->family(familyName, QFontDatabasePrivate::EnsureCreated);
599 qCDebug(lcFontDb) <<
"Registering alias" << alias <<
"to family" << familyName;
601 auto *d = QFontDatabasePrivate::instance();
602 QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::RequestFamily);
606 if (f->aliases.contains(alias, Qt::CaseInsensitive))
609 f->aliases.push_back(alias);
614 if (!alias.isEmpty()) {
615 const auto *d = QFontDatabasePrivate::instance();
616 for (
int i = 0; i < d->count; ++i)
617 if (d->families[i]->matchesFamilyName(alias))
618 return d->families[i]->name;
625 auto *d = QFontDatabasePrivate::instance();
626 QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::RequestFamily);
627 return f !=
nullptr && f->populated;
631
632
633
634
635
636
637QStringList QPlatformFontDatabase::fallbacksForFamily(
const QString &family,
639 QFont::StyleHint styleHint,
640 QFontDatabasePrivate::ExtendedScript script)
const
645 QStringList preferredFallbacks;
646 QStringList otherFallbacks;
647 QStringList lastResort;
649 auto writingSystem = qt_writing_system_for_script(script);
650 if (writingSystem >= QFontDatabase::WritingSystemsCount)
651 writingSystem = QFontDatabase::Any;
653 auto *db = QFontDatabasePrivate::instance();
654 for (
int i = 0; i < db->count; ++i) {
655 QtFontFamily *f = db->families[i];
657 f->ensurePopulated();
659 if (writingSystem != QFontDatabase::Any && !familySupportsWritingSystem(f, writingSystem))
662 for (
int j = 0; j < f->count; ++j) {
663 QtFontFoundry *foundry = f->foundries[j];
665 QString name = foundry->name.isEmpty()
667 : f->name +
" ["_L1 + foundry->name + u']';
675 int score =
int(Score::LastResort);
676 for (
int k = 0; k < foundry->count; ++k) {
677 const bool styleMatch = style == foundry->styles[k]->key.style;
678 if (foundry->styles[k]->smoothScalable) {
680 score =
int(Score::Preferred);
683 score = std::max(score,
int(Score::Other));
685 }
else if (styleMatch) {
686 score = std::max(score,
int(Score::FirstLastResort));
690 switch (Score(score)) {
691 case Score::LastResort:
692 lastResort.append(name);
break;
693 case Score::FirstLastResort:
694 lastResort.prepend(name);
break;
696 otherFallbacks.append(name);
break;
697 case Score::Preferred:
698 preferredFallbacks.append(name);
break;
704 return preferredFallbacks + otherFallbacks + lastResort;
709 QFont::StyleHint styleHint,
710 QFontDatabasePrivate::ExtendedScript script)
713 auto *db = QFontDatabasePrivate::ensureFontDatabase();
717 if (
const QStringList *fallbacks = db->fallbacksCache.object(cacheKey))
721 QStringList userFallbacks = db->applicationFallbackFontFamilies(script == QFontDatabasePrivate::Script_Latin ? QFontDatabasePrivate::Script_Common : script);
722 QStringList retList = userFallbacks + QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
724 QStringList::iterator i;
725 for (i = retList.begin(); i != retList.end(); ++i) {
726 bool contains =
false;
727 for (
int j = 0; j < db->count; j++) {
728 if (db->families[j]->matchesFamilyName(*i)) {
734 i = retList.erase(i);
739 db->fallbacksCache.insert(cacheKey,
new QStringList(retList));
747 return fallbacksForFamily(family, style, styleHint, script);
750QFontEngine *QFontDatabasePrivate::loadSingleEngine(
int script,
751 const QFontDef &request,
752 QtFontFamily *family, QtFontFoundry *foundry,
753 QtFontStyle *style, QtFontSize *size)
758 QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
759 int pixelSize = size->pixelSize;
760 if (!pixelSize || (style->smoothScalable && pixelSize ==
SMOOTH_SCALABLE)
761 || pfdb->fontsAlwaysScalable()) {
762 pixelSize = request.pixelSize;
765 QFontDef def = request;
766 def.pixelSize = pixelSize;
768 QFontCache *fontCache = QFontCache::instance();
770 QFontCache::Key key(def,script);
771 QFontEngine *engine = fontCache->findEngine(key);
773 const bool cacheForCommonScript = script != QFontDatabasePrivate::Script_Common
774 && (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0;
776 if (Q_LIKELY(cacheForCommonScript) && script < QChar::ScriptCount) {
778 key.script = QChar::Script_Common;
779 engine = fontCache->findEngine(key);
783 if (Q_UNLIKELY(!engine->supportsScript(QChar::Script(script)))) {
784 qCInfo(lcFontDb,
"OpenType support missing for \"%ls\", script %d",
785 qUtf16Printable(def.family()), script);
789 engine->isSmoothlyScalable = style->smoothScalable;
790 fontCache->insertEngine(key, engine);
798 if (style->key.stretch != 0 && request.stretch != 0
799 && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
800 def.stretch = (request.stretch * 100 + style->key.stretch / 2) / style->key.stretch;
801 }
else if (request.stretch == QFont::AnyStretch) {
805 engine = pfdb->fontEngine(def, size->handle);
808 if (script < QChar::ScriptCount && !engine->supportsScript(QChar::Script(script))) {
809 qCInfo(lcFontDb,
"OpenType support missing for \"%ls\", script %d",
810 qUtf16Printable(def.family()), script);
811 if (engine->ref.loadRelaxed() == 0)
816 engine->isSmoothlyScalable = style->smoothScalable;
817 fontCache->insertEngine(key, engine);
819 if (Q_LIKELY(cacheForCommonScript && !engine->symbol)) {
821 key.script = QChar::Script_Common;
822 if (!fontCache->findEngine(key))
823 fontCache->insertEngine(key, engine);
830QFontEngine *QFontDatabasePrivate::loadEngine(
int script,
const QFontDef &request,
831 QtFontFamily *family, QtFontFoundry *foundry,
832 QtFontStyle *style, QtFontSize *size)
834 QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size);
836 if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
837 Q_TRACE(QFontDatabase_loadEngine, request.families.join(QLatin1Char(
';')), request.pointSize);
839 QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
840 QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine,
841 QFontDatabasePrivate::ExtendedScript(script));
842 if (!request.fallBackFamilies.isEmpty()) {
843 QStringList fallbacks = request.fallBackFamilies;
845 QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
846 if (styleHint == QFont::AnyStyle && request.fixedPitch)
847 styleHint = QFont::TypeWriter;
849 fallbacks += fallbacksForFamily(family->name,
850 QFont::Style(style->key.style),
852 QFontDatabasePrivate::ExtendedScript(script));
854 pfMultiEngine->setFallbackFamiliesList(fallbacks);
856 engine = pfMultiEngine;
860 QFontCache::Key key(request, script, 1);
861 QFontCache::instance()->insertEngine(key, engine);
867QtFontStyle::~QtFontStyle()
872 QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
874 integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
881 const QString &styleName = QString())
886 for (
int i = 0; i < foundry->count; i++ ) {
887 QtFontStyle *style = foundry->styles[i];
889 if (!styleName.isEmpty() && styleName == style->styleName) {
895 int d = qAbs( (
int(styleKey.weight) -
int(style->key.weight)) / 10 );
897 if ( styleKey.stretch != 0 && style->key.stretch != 0 ) {
898 d += qAbs( styleKey.stretch - style->key.stretch );
901 if (styleKey.style != style->key.style) {
902 if (styleKey.style != QFont::StyleNormal && style->key.style != QFont::StyleNormal)
915 qCDebug(lcFontMatch,
" best style has distance 0x%x", dist );
916 return foundry->styles[best];
920unsigned int QFontDatabasePrivate::bestFoundry(
int script,
unsigned int score,
int styleStrategy,
921 const QtFontFamily *family,
const QString &foundry_name,
922 QtFontStyle::Key styleKey,
int pixelSize,
char pitch,
923 QtFontDesc *desc,
const QString &styleName)
928 desc->foundry =
nullptr;
929 desc->style =
nullptr;
930 desc->size =
nullptr;
932 qCDebug(lcFontMatch,
" REMARK: looking for best foundry for family '%s'%s [%d]",
933 family->name.toLatin1().constData(),
934 family->colorFont ?
" (color font)" :
"",
937 for (
int x = 0; x < family->count; ++x) {
938 QtFontFoundry *foundry = family->foundries[x];
939 if (!foundry_name.isEmpty() && foundry->name.compare(foundry_name, Qt::CaseInsensitive) != 0)
942 qCDebug(lcFontMatch,
" looking for matching style in foundry '%s' %d",
943 foundry->name.isEmpty() ?
"-- none --" : foundry->name.toLatin1().constData(), foundry->count);
945 QtFontStyle *style = bestStyle(foundry, styleKey, styleName);
947 if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) {
948 qCDebug(lcFontMatch,
" ForceOutline set, but not smoothly scalable");
953 QtFontSize *size =
nullptr;
956 if (!(styleStrategy & QFont::ForceOutline)) {
957 size = style->pixelSize(pixelSize);
959 qCDebug(lcFontMatch,
" found exact size match (%d pixels)", size->pixelSize);
960 px = size->pixelSize;
965 if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
968 qCDebug(lcFontMatch,
" found smoothly scalable font (%d pixels)", pixelSize);
974 if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
975 size = style->pixelSize(0);
977 qCDebug(lcFontMatch,
" found bitmap scalable font (%d pixels)", pixelSize);
985 unsigned int distance = ~0u;
986 for (
int x = 0; x < style->count; ++x) {
989 if (style->pixelSizes[x].pixelSize < pixelSize) {
993 d = pixelSize - style->pixelSizes[x].pixelSize + 1;
995 d = style->pixelSizes[x].pixelSize - pixelSize;
1000 size = style->pixelSizes + x;
1001 qCDebug(lcFontMatch,
" best size so far: %3d (%d)", size->pixelSize, pixelSize);
1006 qCDebug(lcFontMatch,
" no size supports the script we want");
1010 if (style->bitmapScalable && ! (styleStrategy & QFont::PreferQuality) &&
1011 (distance * 10 / pixelSize) >= 2) {
1014 size = style->pixelSize(0);
1017 px = size->pixelSize;
1022 unsigned int this_score = 0x0000;
1024 PitchMismatch = 0x4000,
1025 StyleMismatch = 0x2000,
1026 BitmapScaledPenalty = 0x1000
1029 if ((pitch ==
'm' && !family->fixedPitch)
1030 || (pitch ==
'p' && family->fixedPitch))
1031 this_score += PitchMismatch;
1033 if (styleKey != style->key)
1034 this_score += StyleMismatch;
1035 if (!style->smoothScalable && px != size->pixelSize)
1036 this_score += BitmapScaledPenalty;
1037 if (px != pixelSize)
1038 this_score += qAbs(px - pixelSize);
1040 if (this_score < score) {
1041 qCDebug(lcFontMatch,
" found a match: score %x best score so far %x",
1045 desc->foundry = foundry;
1046 desc->style = style;
1049 qCDebug(lcFontMatch,
" score %x no better than best %x", this_score, score);
1058 if (familyName.isEmpty())
1060 return f->matchesFamilyName(familyName);
1064
1065
1066
1067
1068int QFontDatabasePrivate::match(
int script,
const QFontDef &request,
const QString &family_name,
1069 const QString &foundry_name, QtFontDesc *desc,
const QList<
int> &blacklistedFamilies,
1070 unsigned int *resultingScore)
1074 QtFontStyle::Key styleKey;
1075 styleKey.style = request.style;
1076 styleKey.weight = request.weight;
1078 styleKey.stretch = request.stretch ? request.stretch : 100;
1079 char pitch = request.ignorePitch ?
'*' : request.fixedPitch ?
'm' :
'p';
1082 qCDebug(lcFontMatch,
"QFontDatabasePrivate::match\n"
1084 " family: %s [%s], script: %d\n"
1086 " weight: %d, style: %d\n"
1090 family_name.isEmpty() ?
"-- first in script --" : family_name.toLatin1().constData(),
1091 foundry_name.isEmpty() ?
"-- any --" : foundry_name.toLatin1().constData(), script,
1092 request.styleName.isEmpty() ?
"-- any --" : request.styleName.toLatin1().constData(),
1093 request.weight, request.style, request.stretch, request.pixelSize, pitch);
1095 desc->family =
nullptr;
1096 desc->foundry =
nullptr;
1097 desc->style =
nullptr;
1098 desc->size =
nullptr;
1100 unsigned int score = ~0u;
1102 QMutexLocker locker(fontDatabaseMutex());
1103 QFontDatabasePrivate::ensureFontDatabase();
1105 auto writingSystem = qt_writing_system_for_script(script);
1106 if (writingSystem >= QFontDatabase::WritingSystemsCount)
1107 writingSystem = QFontDatabase::Any;
1109 auto *db = QFontDatabasePrivate::instance();
1110 for (
int x = 0; x < db->count; ++x) {
1111 if (blacklistedFamilies.contains(x))
1114 test.family = db->families[x];
1116 if (!matchFamilyName(family_name, test.family))
1118 if (!test.family->ensurePopulated())
1122 if (writingSystem != QFontDatabase::Any && !familySupportsWritingSystem(test.family, writingSystem))
1126 if (script == QFontDatabasePrivate::Script_Emoji && !test.family->colorFont)
1131 unsigned int newscore =
1132 bestFoundry(script, score, request.styleStrategy,
1133 test.family, foundry_name, styleKey, request.pixelSize, pitch,
1134 &test, request.styleName);
1135 if (test.foundry ==
nullptr && !foundry_name.isEmpty()) {
1138 newscore = bestFoundry(script, score, request.styleStrategy, test.family,
1139 QString(), styleKey, request.pixelSize,
1140 pitch, &test, request.styleName);
1143 if (newscore < score) {
1152 if (resultingScore !=
nullptr)
1153 *resultingScore = score;
1161 if (weight > QFont::Normal) {
1162 if (weight >= QFont::Black)
1163 result = QCoreApplication::translate(
"QFontDatabase",
"Black");
1164 else if (weight >= QFont::ExtraBold)
1165 result = QCoreApplication::translate(
"QFontDatabase",
"Extra Bold");
1166 else if (weight >= QFont::Bold)
1167 result = QCoreApplication::translate(
"QFontDatabase",
"Bold");
1168 else if (weight >= QFont::DemiBold)
1169 result = QCoreApplication::translate(
"QFontDatabase",
"Demi Bold");
1170 else if (weight >= QFont::Medium)
1171 result = QCoreApplication::translate(
"QFontDatabase",
"Medium",
"The Medium font weight");
1173 if (weight <= QFont::Thin)
1174 result = QCoreApplication::translate(
"QFontDatabase",
"Thin");
1175 else if (weight <= QFont::ExtraLight)
1176 result = QCoreApplication::translate(
"QFontDatabase",
"Extra Light");
1177 else if (weight <= QFont::Light)
1178 result = QCoreApplication::translate(
"QFontDatabase",
"Light");
1181 if (style == QFont::StyleItalic)
1182 result += u' ' + QCoreApplication::translate(
"QFontDatabase",
"Italic");
1183 else if (style == QFont::StyleOblique)
1184 result += u' ' + QCoreApplication::translate(
"QFontDatabase",
"Oblique");
1186 if (result.isEmpty())
1187 result = QCoreApplication::translate(
"QFontDatabase",
"Normal",
"The Normal or Regular font weight");
1189 return result.simplified();
1193
1194
1195
1196
1197QString QFontDatabase::styleString(
const QFont &font)
1199 return font.styleName().isEmpty() ? styleStringHelper(font.weight(), font.style())
1204
1205
1206
1207
1208QString QFontDatabase::styleString(
const QFontInfo &fontInfo)
1210 return fontInfo.styleName().isEmpty() ? styleStringHelper(fontInfo.weight(), fontInfo.style())
1211 : fontInfo.styleName();
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
1264
1267
1268
1269
1270
1271
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
1313
1316
1317
1318
1319
1320
1321
1322
1323
1324
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
1374
1377
1378
1379
1380
1381
1382QFontDatabasePrivate *QFontDatabasePrivate::ensureFontDatabase()
1384 auto *d = QFontDatabasePrivate::instance();
1385 if (!d->populated) {
1389 qCDebug(lcFontDb) <<
"Populating font database";
1391 if (Q_UNLIKELY(
qGuiApp ==
nullptr || QGuiApplicationPrivate::platformIntegration() ==
nullptr))
1392 qFatal(
"QFontDatabase: Must construct a QGuiApplication before accessing QFontDatabase");
1394 auto *platformFontDatabase = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
1395 platformFontDatabase->populateFontDatabase();
1397 for (
int i = 0; i < d->applicationFonts.size(); i++) {
1398 auto *font = &d->applicationFonts[i];
1399 if (!font->isNull() && !font->isPopulated())
1400 platformFontDatabase->addApplicationFont(font->data, font->fileName, font);
1406 d->populated =
true;
1412
1413
1414
1415
1416
1417
1418QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems()
1420 QMutexLocker locker(fontDatabaseMutex());
1421 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1423 quint64 writingSystemsFound = 0;
1424 static_assert(WritingSystemsCount < 64);
1426 for (
int i = 0; i < d->count; ++i) {
1427 QtFontFamily *family = d->families[i];
1428 if (!family->ensurePopulated())
1431 if (family->count == 0)
1433 for (uint x = Latin; x < uint(WritingSystemsCount); ++x) {
1434 if (family->writingSystems[x] & QtFontFamily::Supported)
1435 writingSystemsFound |= quint64(1) << x;
1442 QList<WritingSystem> list;
1443 list.reserve(qPopulationCount(writingSystemsFound));
1444 for (uint x = Latin ; x < uint(WritingSystemsCount); ++x) {
1445 if (writingSystemsFound & (quint64(1) << x))
1446 list.push_back(WritingSystem(x));
1453
1454
1455
1456
1457
1458QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems(
const QString &family)
1460 QString familyName, foundryName;
1461 parseFontName(family, foundryName, familyName);
1463 QMutexLocker locker(fontDatabaseMutex());
1464 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1466 QList<WritingSystem> list;
1467 QtFontFamily *f = d->family(familyName);
1468 if (!f || f->count == 0)
1471 for (
int x = Latin; x < WritingSystemsCount; ++x) {
1472 const WritingSystem writingSystem = WritingSystem(x);
1473 if (f->writingSystems[writingSystem] & QtFontFamily::Supported)
1474 list.append(writingSystem);
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490QStringList QFontDatabase::families(WritingSystem writingSystem)
1492 QMutexLocker locker(fontDatabaseMutex());
1493 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1496 for (
int i = 0; i < d->count; i++) {
1497 QtFontFamily *f = d->families[i];
1498 if (f->populated && f->count == 0)
1500 if (writingSystem != Any) {
1501 if (!f->ensurePopulated())
1503 if (f->writingSystems[writingSystem] != QtFontFamily::Supported)
1506 if (!f->populated || f->count == 1) {
1507 flist.append(f->name);
1509 for (
int j = 0; j < f->count; j++) {
1510 QString str = f->name;
1511 QString foundry = f->foundries[j]->name;
1512 if (!foundry.isEmpty()) {
1525
1526
1527
1528
1529
1530
1531QStringList QFontDatabase::styles(
const QString &family)
1533 QString familyName, foundryName;
1534 parseFontName(family, foundryName, familyName);
1536 QMutexLocker locker(fontDatabaseMutex());
1537 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1540 QtFontFamily *f = d->family(familyName);
1544 QtFontFoundry allStyles(foundryName);
1545 for (
int j = 0; j < f->count; j++) {
1546 QtFontFoundry *foundry = f->foundries[j];
1547 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1548 for (
int k = 0; k < foundry->count; k++) {
1549 QtFontStyle::Key ke(foundry->styles[k]->key);
1552 foundry->styles[k]->styleName,
1553 QtFontFoundry::AddWhenMissing);
1558 l.reserve(allStyles.count);
1559 for (
int i = 0; i < allStyles.count; i++) {
1560 l.append(allStyles.styles[i]->styleName.isEmpty() ?
1561 styleStringHelper(allStyles.styles[i]->key.weight,
1562 (QFont::Style)allStyles.styles[i]->key.style) :
1563 allStyles.styles[i]->styleName);
1569
1570
1571
1573bool QFontDatabase::isFixedPitch(
const QString &family,
1574 const QString &style)
1578 QString familyName, foundryName;
1579 parseFontName(family, foundryName, familyName);
1581 QMutexLocker locker(fontDatabaseMutex());
1582 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1584 QtFontFamily *f = d->family(familyName);
1585 return (f && f->fixedPitch);
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598bool QFontDatabase::isBitmapScalable(
const QString &family,
1599 const QString &style)
1601 QString familyName, foundryName;
1602 parseFontName(family, foundryName, familyName);
1604 QMutexLocker locker(fontDatabaseMutex());
1605 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1607 QtFontFamily *f = d->family(familyName);
1611 QtFontStyle::Key styleKey(style);
1612 for (
int j = 0; j < f->count; j++) {
1613 QtFontFoundry *foundry = f->foundries[j];
1614 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1615 for (
int k = 0; k < foundry->count; k++)
1616 if ((style.isEmpty() ||
1617 foundry->styles[k]->styleName == style ||
1618 foundry->styles[k]->key == styleKey)
1619 && foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
1629
1630
1631
1632
1633
1634
1635
1636bool QFontDatabase::isSmoothlyScalable(
const QString &family,
const QString &style)
1638 QString familyName, foundryName;
1639 parseFontName(family, foundryName, familyName);
1641 QMutexLocker locker(fontDatabaseMutex());
1642 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1644 QtFontFamily *f = d->family(familyName);
1646 for (
int i = 0; i < d->count; i++) {
1647 if (d->families[i]->matchesFamilyName(familyName)) {
1649 if (f->ensurePopulated())
1657 const QtFontStyle::Key styleKey(style);
1658 for (
int j = 0; j < f->count; j++) {
1659 QtFontFoundry *foundry = f->foundries[j];
1660 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1661 for (
int k = 0; k < foundry->count; k++) {
1662 const QtFontStyle *fontStyle = foundry->styles[k];
1663 const bool smoothScalable =
1664 fontStyle->smoothScalable
1665 && ((style.isEmpty()
1666 || fontStyle->styleName == style
1667 || fontStyle->key == styleKey)
1668 || (fontStyle->styleName.isEmpty()
1669 && style == styleStringHelper(fontStyle->key.weight,
1670 QFont::Style(fontStyle->key.style))));
1680
1681
1682
1683
1684
1685bool QFontDatabase::isScalable(
const QString &family,
1686 const QString &style)
1688 QMutexLocker locker(fontDatabaseMutex());
1689 if (isSmoothlyScalable(family, style))
1691 return isBitmapScalable(family, style);
1696
1697
1698
1699
1700
1701QList<
int> QFontDatabase::pointSizes(
const QString &family,
1702 const QString &styleName)
1704 if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable())
1705 return standardSizes();
1707 QString familyName, foundryName;
1708 parseFontName(family, foundryName, familyName);
1710 QMutexLocker locker(fontDatabaseMutex());
1711 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1715 QtFontFamily *fam = d->family(familyName);
1716 if (!fam)
return sizes;
1719 const int dpi = qt_defaultDpiY();
1721 QtFontStyle::Key styleKey(styleName);
1722 for (
int j = 0; j < fam->count; j++) {
1723 QtFontFoundry *foundry = fam->foundries[j];
1724 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1725 QtFontStyle *style = foundry->style(styleKey, styleName);
1726 if (!style)
continue;
1728 if (style->smoothScalable)
1729 return standardSizes();
1731 for (
int l = 0; l < style->count; l++) {
1732 const QtFontSize *size = style->pixelSizes + l;
1735 const int pointSize = qRound(size->pixelSize * 72.0 / dpi);
1736 if (! sizes.contains(pointSize))
1737 sizes.append(pointSize);
1743 std::sort(sizes.begin(), sizes.end());
1748
1749
1750
1751
1752
1753QFont QFontDatabase::font(
const QString &family,
const QString &style,
1756 QString familyName, foundryName;
1757 parseFontName(family, foundryName, familyName);
1758 QMutexLocker locker(fontDatabaseMutex());
1759 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1761 QtFontFoundry allStyles(foundryName);
1762 QtFontFamily *f = d->family(familyName);
1763 if (!f)
return QGuiApplication::font();
1765 for (
int j = 0; j < f->count; j++) {
1766 QtFontFoundry *foundry = f->foundries[j];
1767 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1768 for (
int k = 0; k < foundry->count; k++) {
1769 allStyles.style(foundry->styles[k]->key,
1770 foundry->styles[k]->styleName,
1771 QtFontFoundry::AddWhenMissing);
1776 QtFontStyle::Key styleKey(style);
1777 QtFontStyle *s = bestStyle(&allStyles, styleKey, style);
1780 return QGuiApplication::font();
1782 QFont fnt(QStringList{family}, pointSize, s->key.weight);
1783 fnt.setStyle((QFont::Style)s->key.style);
1784 if (!s->styleName.isEmpty())
1785 fnt.setStyleName(s->styleName);
1791
1792
1793
1794
1795
1796
1797
1798QList<
int> QFontDatabase::smoothSizes(
const QString &family,
1799 const QString &styleName)
1801 if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable())
1802 return standardSizes();
1804 QString familyName, foundryName;
1805 parseFontName(family, foundryName, familyName);
1807 QMutexLocker locker(fontDatabaseMutex());
1808 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1812 QtFontFamily *fam = d->family(familyName);
1816 const int dpi = qt_defaultDpiY();
1818 QtFontStyle::Key styleKey(styleName);
1819 for (
int j = 0; j < fam->count; j++) {
1820 QtFontFoundry *foundry = fam->foundries[j];
1821 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1822 QtFontStyle *style = foundry->style(styleKey, styleName);
1823 if (!style)
continue;
1825 if (style->smoothScalable)
1826 return QFontDatabase::standardSizes();
1828 for (
int l = 0; l < style->count; l++) {
1829 const QtFontSize *size = style->pixelSizes + l;
1832 const int pointSize = qRound(size->pixelSize * 72.0 / dpi);
1833 if (! sizes.contains(pointSize))
1834 sizes.append(pointSize);
1840 std::sort(sizes.begin(), sizes.end());
1846
1847
1848
1849
1850QList<
int> QFontDatabase::standardSizes()
1852 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->standardSizes();
1857
1858
1859
1860
1861
1862bool QFontDatabase::italic(
const QString &family,
const QString &style)
1864 QString familyName, foundryName;
1865 parseFontName(family, foundryName, familyName);
1867 QMutexLocker locker(fontDatabaseMutex());
1868 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1870 QtFontFoundry allStyles(foundryName);
1871 QtFontFamily *f = d->family(familyName);
1872 if (!f)
return false;
1874 for (
int j = 0; j < f->count; j++) {
1875 QtFontFoundry *foundry = f->foundries[j];
1876 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1877 for (
int k = 0; k < foundry->count; k++) {
1878 allStyles.style(foundry->styles[k]->key,
1879 foundry->styles[k]->styleName,
1880 QtFontFoundry::AddWhenMissing);
1885 QtFontStyle::Key styleKey(style);
1886 QtFontStyle *s = allStyles.style(styleKey, style);
1887 return s && s->key.style == QFont::StyleItalic;
1892
1893
1894
1895
1896
1897bool QFontDatabase::bold(
const QString &family,
1898 const QString &style)
1900 QString familyName, foundryName;
1901 parseFontName(family, foundryName, familyName);
1903 QMutexLocker locker(fontDatabaseMutex());
1904 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1906 QtFontFoundry allStyles(foundryName);
1907 QtFontFamily *f = d->family(familyName);
1908 if (!f)
return false;
1910 for (
int j = 0; j < f->count; j++) {
1911 QtFontFoundry *foundry = f->foundries[j];
1912 if (foundryName.isEmpty() ||
1913 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1914 for (
int k = 0; k < foundry->count; k++) {
1915 allStyles.style(foundry->styles[k]->key,
1916 foundry->styles[k]->styleName,
1917 QtFontFoundry::AddWhenMissing);
1922 QtFontStyle::Key styleKey(style);
1923 QtFontStyle *s = allStyles.style(styleKey, style);
1924 return s && s->key.weight >= QFont::Bold;
1929
1930
1931
1932
1933
1934
1935int QFontDatabase::weight(
const QString &family,
1936 const QString &style)
1938 QString familyName, foundryName;
1939 parseFontName(family, foundryName, familyName);
1941 QMutexLocker locker(fontDatabaseMutex());
1942 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1944 QtFontFoundry allStyles(foundryName);
1945 QtFontFamily *f = d->family(familyName);
1948 for (
int j = 0; j < f->count; j++) {
1949 QtFontFoundry *foundry = f->foundries[j];
1950 if (foundryName.isEmpty() ||
1951 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1952 for (
int k = 0; k < foundry->count; k++) {
1953 allStyles.style(foundry->styles[k]->key,
1954 foundry->styles[k]->styleName,
1955 QtFontFoundry::AddWhenMissing);
1960 QtFontStyle::Key styleKey(style);
1961 QtFontStyle *s = allStyles.style(styleKey, style);
1962 return s ? s->key.weight : -1;
1967bool QFontDatabase::hasFamily(
const QString &family)
1969 QString parsedFamily, foundry;
1970 parseFontName(family, foundry, parsedFamily);
1971 const QString familyAlias = QFontDatabasePrivate::resolveFontFamilyAlias(parsedFamily);
1973 QMutexLocker locker(fontDatabaseMutex());
1974 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1976 for (
int i = 0; i < d->count; i++) {
1977 QtFontFamily *f = d->families[i];
1978 if (f->populated && f->count == 0)
1980 if (familyAlias.compare(f->name, Qt::CaseInsensitive) == 0)
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000bool QFontDatabase::isPrivateFamily(
const QString &family)
2002 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->isPrivateFontFamily(family);
2007
2008
2009
2010QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
2012 const char *name =
nullptr;
2013 switch (writingSystem) {
2015 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Any");
2018 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Latin");
2021 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Greek");
2024 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Cyrillic");
2027 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Armenian");
2030 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Hebrew");
2033 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Arabic");
2036 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Syriac");
2039 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Thaana");
2042 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Devanagari");
2045 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Bengali");
2048 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Gurmukhi");
2051 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Gujarati");
2054 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Oriya");
2057 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Tamil");
2060 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Telugu");
2063 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Kannada");
2066 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Malayalam");
2069 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Sinhala");
2072 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Thai");
2075 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Lao");
2078 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Tibetan");
2081 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Myanmar");
2084 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Georgian");
2087 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Khmer");
2089 case SimplifiedChinese:
2090 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Simplified Chinese");
2092 case TraditionalChinese:
2093 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Traditional Chinese");
2096 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Japanese");
2099 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Korean");
2102 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Vietnamese");
2105 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Symbol");
2108 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Ogham");
2111 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Runic");
2114 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"N'Ko");
2117 Q_ASSERT_X(
false,
"QFontDatabase::writingSystemName",
"invalid 'writingSystem' parameter");
2120 return QCoreApplication::translate(
"QFontDatabase", name);
2124
2125
2126QString QFontDatabase::writingSystemSample(WritingSystem writingSystem)
2128 return [&]() -> QStringView {
2129 switch (writingSystem) {
2130 case QFontDatabase::Any:
2131 case QFontDatabase::Symbol:
2134 case QFontDatabase::Latin:
2137 return u"Aa\x00C3\x00E1Zz";
2138 case QFontDatabase::Greek:
2139 return u"\x0393\x03B1\x03A9\x03C9";
2140 case QFontDatabase::Cyrillic:
2141 return u"\x0414\x0434\x0436\x044f";
2142 case QFontDatabase::Armenian:
2143 return u"\x053f\x054f\x056f\x057f";
2144 case QFontDatabase::Hebrew:
2145 return u"\x05D0\x05D1\x05D2\x05D3";
2146 case QFontDatabase::Arabic:
2147 return u"\x0623\x0628\x062C\x062F\x064A\x0629\x0020\x0639\x0631\x0628\x064A\x0629";
2148 case QFontDatabase::Syriac:
2149 return u"\x0715\x0725\x0716\x0726";
2150 case QFontDatabase::Thaana:
2151 return u"\x0784\x0794\x078c\x078d";
2152 case QFontDatabase::Devanagari:
2153 return u"\x0905\x0915\x0925\x0935";
2154 case QFontDatabase::Bengali:
2155 return u"\x0986\x0996\x09a6\x09b6";
2156 case QFontDatabase::Gurmukhi:
2157 return u"\x0a05\x0a15\x0a25\x0a35";
2158 case QFontDatabase::Gujarati:
2159 return u"\x0a85\x0a95\x0aa5\x0ab5";
2160 case QFontDatabase::Oriya:
2161 return u"\x0b06\x0b16\x0b2b\x0b36";
2162 case QFontDatabase::Tamil:
2163 return u"\x0b89\x0b99\x0ba9\x0bb9";
2164 case QFontDatabase::Telugu:
2165 return u"\x0c05\x0c15\x0c25\x0c35";
2166 case QFontDatabase::Kannada:
2167 return u"\x0c85\x0c95\x0ca5\x0cb5";
2168 case QFontDatabase::Malayalam:
2169 return u"\x0d05\x0d15\x0d25\x0d35";
2170 case QFontDatabase::Sinhala:
2171 return u"\x0d90\x0da0\x0db0\x0dc0";
2172 case QFontDatabase::Thai:
2173 return u"\x0e02\x0e12\x0e22\x0e32";
2174 case QFontDatabase::Lao:
2175 return u"\x0e8d\x0e9d\x0ead\x0ebd";
2176 case QFontDatabase::Tibetan:
2177 return u"\x0f00\x0f01\x0f02\x0f03";
2178 case QFontDatabase::Myanmar:
2179 return u"\x1000\x1001\x1002\x1003";
2180 case QFontDatabase::Georgian:
2181 return u"\x10a0\x10b0\x10c0\x10d0";
2182 case QFontDatabase::Khmer:
2183 return u"\x1780\x1790\x17b0\x17c0";
2184 case QFontDatabase::SimplifiedChinese:
2185 return u"\x4e2d\x6587\x8303\x4f8b";
2186 case QFontDatabase::TraditionalChinese:
2187 return u"\x4e2d\x6587\x7bc4\x4f8b";
2188 case QFontDatabase::Japanese:
2189 return u"\x30b5\x30f3\x30d7\x30eb\x3067\x3059";
2190 case QFontDatabase::Korean:
2191 return u"\xac00\xac11\xac1a\xac2f";
2192 case QFontDatabase::Vietnamese:
2193 return u"\x1ED7\x1ED9\x1ED1\x1ED3";
2194 case QFontDatabase::Ogham:
2195 return u"\x1681\x1682\x1683\x1684";
2196 case QFontDatabase::Runic:
2197 return u"\x16a0\x16a1\x16a2\x16a3";
2198 case QFontDatabase::Nko:
2199 return u"\x7ca\x7cb\x7cc\x7cd";
2206void QFontDatabasePrivate::parseFontName(
const QString &name, QString &foundry, QString &family)
2208 QT_PREPEND_NAMESPACE(parseFontName)(name, foundry, family);
2214 QMutexLocker locker(fontDatabaseMutex());
2215 return QFontDatabasePrivate::instance()->applicationFonts.value(index).data;
2218int QFontDatabasePrivate::addAppFont(
const QByteArray &fontData,
const QString &fileName)
2220 QFontDatabasePrivate::ApplicationFont font;
2221 font.data = fontData;
2222 font.fileName = fileName;
2224 Q_TRACE(QFontDatabasePrivate_addAppFont, fileName);
2227 for (i = 0; i < applicationFonts.size(); ++i)
2228 if (applicationFonts.at(i).isNull())
2230 if (i >= applicationFonts.size()) {
2231 applicationFonts.append(ApplicationFont());
2232 i = applicationFonts.size() - 1;
2235 if (font.fileName.isEmpty() && !fontData.isEmpty())
2236 font.fileName =
":qmemoryfonts/"_L1 + QString::number(i);
2238 auto *platformFontDatabase = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
2239 platformFontDatabase->addApplicationFont(font.data, font.fileName, &font);
2240 if (font.properties.isEmpty())
2243 applicationFonts[i] = font;
2247 QFontCache::instance()->clear();
2249 fallbacksCache.clear();
2251 emit
qApp->fontDatabaseChanged();
2256bool QFontDatabasePrivate::isApplicationFont(
const QString &fileName)
2258 for (
int i = 0; i < applicationFonts.size(); ++i)
2259 if (applicationFonts.at(i).fileName == fileName)
2264void QFontDatabasePrivate::setApplicationFallbackFontFamilies(ExtendedScript script,
const QStringList &familyNames)
2266 applicationFallbackFontFamiliesHash[script] = familyNames;
2268 QFontCache::instance()->clear();
2269 fallbacksCache.clear();
2272QStringList QFontDatabasePrivate::applicationFallbackFontFamilies(ExtendedScript script)
2274 return applicationFallbackFontFamiliesHash.value(script);
2277bool QFontDatabasePrivate::removeApplicationFallbackFontFamily(ExtendedScript script,
const QString &familyName)
2279 auto it = applicationFallbackFontFamiliesHash.find(script);
2280 if (it != applicationFallbackFontFamiliesHash.end()) {
2281 if (it->removeAll(familyName) > 0) {
2283 it = applicationFallbackFontFamiliesHash.erase(it);
2284 QFontCache::instance()->clear();
2285 fallbacksCache.clear();
2293void QFontDatabasePrivate::addApplicationFallbackFontFamily(ExtendedScript script,
const QString &familyName)
2295 auto it = applicationFallbackFontFamiliesHash.find(script);
2296 if (it == applicationFallbackFontFamiliesHash.end())
2297 it = applicationFallbackFontFamiliesHash.insert(script, QStringList{});
2299 it->prepend(familyName);
2301 QFontCache::instance()->clear();
2302 fallbacksCache.clear();
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323int QFontDatabase::addApplicationFont(
const QString &fileName)
2326 if (!QFileInfo(fileName).isNativePath()) {
2328 if (!f.open(QIODevice::ReadOnly))
2331 Q_TRACE(QFontDatabase_addApplicationFont, fileName);
2335 QMutexLocker locker(fontDatabaseMutex());
2336 return QFontDatabasePrivate::instance()->addAppFont(data, fileName);
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351int QFontDatabase::addApplicationFontFromData(
const QByteArray &fontData)
2353 QMutexLocker locker(fontDatabaseMutex());
2354 return QFontDatabasePrivate::instance()->addAppFont(fontData, QString() );
2358
2359
2360
2361
2362
2363
2364
2365QStringList QFontDatabase::applicationFontFamilies(
int id)
2367 QMutexLocker locker(fontDatabaseMutex());
2368 auto *d = QFontDatabasePrivate::instance();
2371 ret.reserve(d->applicationFonts.value(id).properties.size());
2373 for (
const auto &properties : d->applicationFonts.value(id).properties)
2374 ret.append(properties.familyName);
2380
2381
2382
2383
2384
2385
2386
2388QFont QFontDatabase::systemFont(QFontDatabase::SystemFont type)
2390 const QFont *font =
nullptr;
2391 if (
const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
2394 font = theme->font(QPlatformTheme::SystemFont);
2397 font = theme->font(QPlatformTheme::FixedFont);
2400 font = theme->font(QPlatformTheme::TitleBarFont);
2402 case SmallestReadableFont:
2403 font = theme->font(QPlatformTheme::MiniFont);
2410 else if (QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration())
2411 return integration->fontDatabase()->defaultFont();
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427bool QFontDatabase::removeApplicationFont(
int handle)
2429 QMutexLocker locker(fontDatabaseMutex());
2431 auto *db = QFontDatabasePrivate::instance();
2432 if (handle < 0 || handle >= db->applicationFonts.size())
2435 db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453bool QFontDatabase::removeAllApplicationFonts()
2455 QMutexLocker locker(fontDatabaseMutex());
2457 auto *db = QFontDatabasePrivate::instance();
2458 if (!db || db->applicationFonts.isEmpty())
2461 db->applicationFonts.clear();
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
2497
2498void QFontDatabase::addApplicationFallbackFontFamily(QChar::Script script,
const QString &familyName)
2500 QMutexLocker locker(fontDatabaseMutex());
2502 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2503 qCWarning(lcFontDb) <<
"Invalid script passed to addApplicationFallbackFontFamily:" << script;
2507 if (script == QChar::Script_Latin)
2508 script = QChar::Script_Common;
2510 auto *db = QFontDatabasePrivate::instance();
2511 db->addApplicationFallbackFontFamily(QFontDatabasePrivate::ExtendedScript(script), familyName);
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524bool QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script script,
const QString &familyName)
2526 QMutexLocker locker(fontDatabaseMutex());
2528 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2529 qCWarning(lcFontDb) <<
"Invalid script passed to removeApplicationFallbackFontFamily:" << script;
2533 if (script == QChar::Script_Latin)
2534 script = QChar::Script_Common;
2536 auto *db = QFontDatabasePrivate::instance();
2537 return db->removeApplicationFallbackFontFamily(QFontDatabasePrivate::ExtendedScript(script),
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554void QFontDatabase::setApplicationFallbackFontFamilies(QChar::Script script,
const QStringList &familyNames)
2556 QMutexLocker locker(fontDatabaseMutex());
2558 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2559 qCWarning(lcFontDb) <<
"Invalid script passed to setApplicationFallbackFontFamilies:" << script;
2563 if (script == QChar::Script_Latin)
2564 script = QChar::Script_Common;
2566 auto *db = QFontDatabasePrivate::instance();
2567 db->setApplicationFallbackFontFamilies(QFontDatabasePrivate::ExtendedScript(script),
2572
2573
2574
2575
2576
2577
2578
2579QStringList QFontDatabase::applicationFallbackFontFamilies(QChar::Script script)
2581 QMutexLocker locker(fontDatabaseMutex());
2583 if (script >= QChar::ScriptCount) {
2584 qCWarning(lcFontDb) <<
"Invalid script passed to applicationFallbackFontFamilies:" << script;
2585 return QStringList{};
2588 if (script == QChar::Script_Latin)
2589 script = QChar::Script_Common;
2591 auto *db = QFontDatabasePrivate::instance();
2592 return db->applicationFallbackFontFamilies(QFontDatabasePrivate::ExtendedScript(script));
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606void QFontDatabase::addApplicationEmojiFontFamily(
const QString &familyName)
2608 QMutexLocker locker(fontDatabaseMutex());
2609 auto *db = QFontDatabasePrivate::instance();
2610 db->addApplicationFallbackFontFamily(QFontDatabasePrivate::Script_Emoji, familyName);
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623bool QFontDatabase::removeApplicationEmojiFontFamily(
const QString &familyName)
2625 QMutexLocker locker(fontDatabaseMutex());
2626 auto *db = QFontDatabasePrivate::instance();
2627 return db->removeApplicationFallbackFontFamily(QFontDatabasePrivate::Script_Emoji,
2632
2633
2634
2635
2636
2637
2638void QFontDatabase::setApplicationEmojiFontFamilies(
const QStringList &familyNames)
2640 QMutexLocker locker(fontDatabaseMutex());
2641 auto *db = QFontDatabasePrivate::instance();
2642 db->setApplicationFallbackFontFamilies(QFontDatabasePrivate::Script_Emoji,
2647
2648
2649
2650
2651
2652
2653QStringList QFontDatabase::applicationEmojiFontFamilies()
2655 QMutexLocker locker(fontDatabaseMutex());
2656 auto *db = QFontDatabasePrivate::instance();
2657 return db->applicationFallbackFontFamilies(QFontDatabasePrivate::Script_Emoji);
2661
2662
2663QFontEngine *QFontDatabasePrivate::findFont(
const QFontDef &req,
2665 bool preferScriptOverFamily)
2667 QMutexLocker locker(fontDatabaseMutex());
2668 ensureFontDatabase();
2670 QFontEngine *engine;
2673 const QFontDef request =
static_cast<QWindowsFontDatabaseBase *>(
2674 QGuiApplicationPrivate::platformIntegration()->fontDatabase())
2675 ->sanitizeRequest(req);
2677 const QFontDef &request = req;
2680#if defined(QT_BUILD_INTERNAL)
2682 if (qt_enable_test_font && request.family() ==
"__Qt__Box__Engine__"_L1) {
2683 engine =
new QTestFontEngine(request.pixelSize);
2684 engine->fontDef = request;
2689 QFontCache *fontCache = QFontCache::instance();
2694 bool multi = !(request.styleStrategy & QFont::NoFontMerging);
2695 QFontCache::Key key(request, script, multi ? 1 : 0);
2696 engine = fontCache->findEngine(key);
2698 qCDebug(lcFontMatch,
"Cache hit level 1");
2702 if (request.pixelSize > 0xffff) {
2704 qCDebug(lcFontMatch,
"Rejecting request for pixel size %g2, returning box engine",
double(request.pixelSize));
2705 return new QFontEngineBox(32);
2708 QString family_name, foundry_name;
2709 const QString requestFamily = request.families.at(0);
2710 parseFontName(requestFamily, foundry_name, family_name);
2712 QList<
int> blackListed;
2713 unsigned int score = UINT_MAX;
2724 qCDebug(lcFontMatch,
"Family name match pass: Looking for family name '%s'%s", qPrintable(family_name),
2725 script == QFontDatabasePrivate::Script_Emoji ?
" (color font required)" :
"");
2726 int index = match(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed, &score);
2731 if (score > 0 && QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamilyAliases(family_name)) {
2732 qCDebug(lcFontMatch,
"Alias match pass: Imperfect result and aliases populated, so trying again%s",
2733 script == QFontDatabasePrivate::Script_Emoji ?
" (color font required)" :
"");
2735 index = match(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
2743 if (index < 0 && !multi && !preferScriptOverFamily) {
2744 qCDebug(lcFontMatch,
"NoFontMerging pass: Font not found with requested script, but we try to load it anyway");
2745 index = match(QChar::Script_Common, request, family_name, foundry_name, &desc, blackListed);
2749 QFontDef fontDef = request;
2752 if (fontDef.families.isEmpty())
2753 fontDef.families = QStringList(desc.family->name);
2755 engine = loadEngine(script, fontDef, desc.family, desc.foundry, desc.style, desc.size);
2758 initFontDef(desc, request, &engine->fontDef, multi);
2760 qCDebug(lcFontMatch,
"Failed to create font engine for font '%s'. Blacklisting %d",
2761 qPrintable(desc.family->name), index);
2762 blackListed.append(index);
2765 qCDebug(lcFontMatch,
" NO MATCH FOUND\n");
2773 if (!requestFamily.isEmpty()) {
2774 qCDebug(lcFontMatch,
"Fallbacks pass: Looking for a fallback matching script %d", script);
2775 QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
2776 if (styleHint == QFont::AnyStyle && request.fixedPitch)
2777 styleHint = QFont::TypeWriter;
2779 QStringList fallbacks = request.fallBackFamilies
2780 + fallbacksForFamily(requestFamily,
2781 QFont::Style(request.style),
2783 QFontDatabasePrivate::ExtendedScript(script));
2784 if (script > QChar::Script_Common)
2785 fallbacks += QString();
2787 auto findMatchingFallback = [&fallbacks,
2792 &request](
int lookupScript,
int cacheScript) {
2793 QFontEngine *engine =
nullptr;
2794 for (
int i = 0; !engine && i < fallbacks.size(); i++) {
2795 QFontDef def = request;
2797 def.families = QStringList(fallbacks.at(i));
2798 QFontCache::Key key(def, cacheScript, multi ? 1 : 0);
2799 engine = fontCache->findEngine(key);
2803 index = match(lookupScript,
2811 QFontDef loadDef = def;
2812 if (loadDef.families.isEmpty())
2813 loadDef.families = QStringList(desc.family->name);
2814 engine = loadEngine(cacheScript,
2821 initFontDef(desc, loadDef, &engine->fontDef, multi);
2823 qCDebug(lcFontMatch,
"Failed to create font engine for fallback %d (%s). Blacklisting %d",
2824 i, qPrintable(desc.family->name), index);
2825 blackListed.append(index);
2828 }
while (index >= 0 && !engine);
2835 engine = findMatchingFallback(multi && script != QFontDatabasePrivate::Script_Emoji
2836 ? QChar::Script_Common
2843 if (!engine && script == QFontDatabasePrivate::Script_Emoji) {
2844 qCDebug(lcFontMatch,
"No color fonts found on system. Doing final fallback match.");
2848 if (!requestFamily.isEmpty())
2849 fallbacks.prepend(requestFamily);
2850 engine = findMatchingFallback(QChar::Script_Common, script);
2855 engine =
new QFontEngineBox(request.pixelSize);
2856 qCDebug(lcFontMatch,
"returning box engine");
2863void QFontDatabasePrivate::load(
const QFontPrivate *d,
int script)
2865 QFontDef req = d->request;
2867 if (req.pixelSize == -1) {
2868 req.pixelSize = std::floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100;
2869 req.pixelSize = qRound(req.pixelSize);
2872 if (req.pointSize < 0 && d->dpi > 0)
2873 req.pointSize = req.pixelSize*72.0/d->dpi;
2876 const QStringList fallBackFamilies = familyList(req);
2878 if (!d->engineData) {
2879 QFontCache *fontCache = QFontCache::instance();
2883 if (!d->request.families.isEmpty())
2884 req.families = fallBackFamilies;
2886 d->engineData = fontCache->findEngineData(req);
2887 if (!d->engineData) {
2889 d->engineData =
new QFontEngineData;
2890 fontCache->insertEngineData(req, d->engineData);
2892 d->engineData->ref.ref();
2896 if (d->engineData->engines[script])
2899 QFontEngine *fe =
nullptr;
2901 Q_TRACE(QFontDatabase_load, req.families.join(QLatin1Char(
';')), req.pointSize);
2903 req.fallBackFamilies = fallBackFamilies;
2904 if (!req.fallBackFamilies.isEmpty())
2905 req.families = QStringList(req.fallBackFamilies.takeFirst());
2908 QStringList family_list;
2910 if (!req.families.isEmpty()) {
2912 family_list << req.families.at(0);
2915 const auto families = QGuiApplication::font().families();
2916 if (!families.isEmpty()) {
2917 QString defaultFamily = families.first();
2918 if (! family_list.contains(defaultFamily))
2919 family_list << defaultFamily;
2925 family_list << QString();
2927 QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
2928 for (; !fe && it != end; ++it) {
2929 req.families = QStringList(*it);
2931 fe = QFontDatabasePrivate::findFont(req, script);
2933 if (fe->type() == QFontEngine::Box && !req.families.at(0).isEmpty()) {
2934 if (fe->ref.loadRelaxed() == 0)
2939 fe->fontDef.pointSize = qreal(
double((fe->fontDef.pixelSize * 72) / d->dpi));
2944 req.fallBackFamilies.clear();
2948 if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
2949 for (
int i = 0; i < QFontDatabasePrivate::ScriptCount; ++i) {
2950 if (!d->engineData->engines[i]) {
2951 d->engineData->engines[i] = fe;
2956 d->engineData->engines[script] = fe;
2961QString QFontDatabasePrivate::resolveFontFamilyAlias(
const QString &family)
2963 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->resolveFontFamilyAlias(family);
2966Q_GUI_EXPORT
QStringList qt_sort_families_by_writing_system(QFontDatabasePrivate::ExtendedScript script,
2967 const QStringList &families)
2969 size_t writingSystem = qt_writing_system_for_script(script);
2970 if (script != QFontDatabasePrivate::Script_Emoji
2971 && (writingSystem == QFontDatabase::Any
2972 || writingSystem >= QFontDatabase::WritingSystemsCount)) {
2976 auto *db = QFontDatabasePrivate::instance();
2977 QMultiMap<uint, QString> supported;
2978 for (
int i = 0; i < families.size(); ++i) {
2979 const QString &family = families.at(i);
2981 QtFontFamily *testFamily =
nullptr;
2982 for (
int x = 0; x < db->count; ++x) {
2983 if (Q_UNLIKELY(matchFamilyName(family, db->families[x]))) {
2984 testFamily = db->families[x];
2985 if (testFamily->ensurePopulated())
2991 if (testFamily ==
nullptr
2992 || (script == QFontDatabasePrivate::Script_Emoji && !testFamily->colorFont)
2993 || (script != QFontDatabasePrivate::Script_Emoji && !familySupportsWritingSystem(testFamily, writingSystem))) {
2997 supported.insert(order, family);
3000 return supported.values();
3005#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,...)