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;
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 for (
int k = 0; k < foundry->count; ++k) {
665 QString name = foundry->name.isEmpty()
667 : f->name +
" ["_L1 + foundry->name + u']';
668 if (style == foundry->styles[k]->key.style)
669 preferredFallbacks.append(name);
671 otherFallbacks.append(name);
676 return preferredFallbacks + otherFallbacks;
681 QFont::StyleHint styleHint,
682 QFontDatabasePrivate::ExtendedScript script)
685 auto *db = QFontDatabasePrivate::ensureFontDatabase();
689 if (
const QStringList *fallbacks = db->fallbacksCache.object(cacheKey))
693 QStringList userFallbacks = db->applicationFallbackFontFamilies(script == QFontDatabasePrivate::Script_Latin ? QFontDatabasePrivate::Script_Common : script);
694 QStringList retList = userFallbacks + QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
696 QStringList::iterator i;
697 for (i = retList.begin(); i != retList.end(); ++i) {
698 bool contains =
false;
699 for (
int j = 0; j < db->count; j++) {
700 if (db->families[j]->matchesFamilyName(*i)) {
706 i = retList.erase(i);
711 db->fallbacksCache.insert(cacheKey,
new QStringList(retList));
719 return fallbacksForFamily(family, style, styleHint, script);
722QFontEngine *QFontDatabasePrivate::loadSingleEngine(
int script,
723 const QFontDef &request,
724 QtFontFamily *family, QtFontFoundry *foundry,
725 QtFontStyle *style, QtFontSize *size)
730 QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
731 int pixelSize = size->pixelSize;
732 if (!pixelSize || (style->smoothScalable && pixelSize ==
SMOOTH_SCALABLE)
733 || pfdb->fontsAlwaysScalable()) {
734 pixelSize = request.pixelSize;
737 QFontDef def = request;
738 def.pixelSize = pixelSize;
740 QFontCache *fontCache = QFontCache::instance();
742 QFontCache::Key key(def,script);
743 QFontEngine *engine = fontCache->findEngine(key);
745 const bool cacheForCommonScript = script != QFontDatabasePrivate::Script_Common
746 && (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0;
748 if (Q_LIKELY(cacheForCommonScript) && script < QChar::ScriptCount) {
750 key.script = QChar::Script_Common;
751 engine = fontCache->findEngine(key);
755 if (Q_UNLIKELY(!engine->supportsScript(QChar::Script(script)))) {
756 qCInfo(lcFontDb,
"OpenType support missing for \"%ls\", script %d",
757 qUtf16Printable(def.families.constFirst()), script);
761 engine->isSmoothlyScalable = style->smoothScalable;
762 fontCache->insertEngine(key, engine);
770 if (style->key.stretch != 0 && request.stretch != 0
771 && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
772 def.stretch = (request.stretch * 100 + style->key.stretch / 2) / style->key.stretch;
773 }
else if (request.stretch == QFont::AnyStretch) {
777 engine = pfdb->fontEngine(def, size->handle);
780 if (script < QChar::ScriptCount && !engine->supportsScript(QChar::Script(script))) {
781 qCInfo(lcFontDb,
"OpenType support missing for \"%ls\", script %d",
782 qUtf16Printable(def.families.constFirst()), script);
783 if (engine->ref.loadRelaxed() == 0)
788 engine->isSmoothlyScalable = style->smoothScalable;
789 fontCache->insertEngine(key, engine);
791 if (Q_LIKELY(cacheForCommonScript && !engine->symbol)) {
793 key.script = QChar::Script_Common;
794 if (!fontCache->findEngine(key))
795 fontCache->insertEngine(key, engine);
802QFontEngine *QFontDatabasePrivate::loadEngine(
int script,
const QFontDef &request,
803 QtFontFamily *family, QtFontFoundry *foundry,
804 QtFontStyle *style, QtFontSize *size)
806 QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size);
808 if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
809 Q_TRACE(QFontDatabase_loadEngine, request.families.join(QLatin1Char(
';')), request.pointSize);
811 QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
812 QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine,
813 QFontDatabasePrivate::ExtendedScript(script));
814 if (!request.fallBackFamilies.isEmpty()) {
815 QStringList fallbacks = request.fallBackFamilies;
817 QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
818 if (styleHint == QFont::AnyStyle && request.fixedPitch)
819 styleHint = QFont::TypeWriter;
821 fallbacks += fallbacksForFamily(family->name,
822 QFont::Style(style->key.style),
824 QFontDatabasePrivate::ExtendedScript(script));
826 pfMultiEngine->setFallbackFamiliesList(fallbacks);
828 engine = pfMultiEngine;
832 QFontCache::Key key(request, script, 1);
833 QFontCache::instance()->insertEngine(key, engine);
839QtFontStyle::~QtFontStyle()
844 QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
846 integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
853 const QString &styleName = QString())
858 for (
int i = 0; i < foundry->count; i++ ) {
859 QtFontStyle *style = foundry->styles[i];
861 if (!styleName.isEmpty() && styleName == style->styleName) {
867 int d = qAbs( (
int(styleKey.weight) -
int(style->key.weight)) / 10 );
869 if ( styleKey.stretch != 0 && style->key.stretch != 0 ) {
870 d += qAbs( styleKey.stretch - style->key.stretch );
873 if (styleKey.style != style->key.style) {
874 if (styleKey.style != QFont::StyleNormal && style->key.style != QFont::StyleNormal)
887 qCDebug(lcFontMatch,
" best style has distance 0x%x", dist );
888 return foundry->styles[best];
892unsigned int QFontDatabasePrivate::bestFoundry(
int script,
unsigned int score,
int styleStrategy,
893 const QtFontFamily *family,
const QString &foundry_name,
894 QtFontStyle::Key styleKey,
int pixelSize,
char pitch,
895 QtFontDesc *desc,
const QString &styleName)
900 desc->foundry =
nullptr;
901 desc->style =
nullptr;
902 desc->size =
nullptr;
904 qCDebug(lcFontMatch,
" REMARK: looking for best foundry for family '%s'%s [%d]",
905 family->name.toLatin1().constData(),
906 family->colorFont ?
" (color font)" :
"",
909 for (
int x = 0; x < family->count; ++x) {
910 QtFontFoundry *foundry = family->foundries[x];
911 if (!foundry_name.isEmpty() && foundry->name.compare(foundry_name, Qt::CaseInsensitive) != 0)
914 qCDebug(lcFontMatch,
" looking for matching style in foundry '%s' %d",
915 foundry->name.isEmpty() ?
"-- none --" : foundry->name.toLatin1().constData(), foundry->count);
917 QtFontStyle *style = bestStyle(foundry, styleKey, styleName);
919 if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) {
920 qCDebug(lcFontMatch,
" ForceOutline set, but not smoothly scalable");
925 QtFontSize *size =
nullptr;
928 if (!(styleStrategy & QFont::ForceOutline)) {
929 size = style->pixelSize(pixelSize);
931 qCDebug(lcFontMatch,
" found exact size match (%d pixels)", size->pixelSize);
932 px = size->pixelSize;
937 if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
940 qCDebug(lcFontMatch,
" found smoothly scalable font (%d pixels)", pixelSize);
946 if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
947 size = style->pixelSize(0);
949 qCDebug(lcFontMatch,
" found bitmap scalable font (%d pixels)", pixelSize);
957 unsigned int distance = ~0u;
958 for (
int x = 0; x < style->count; ++x) {
961 if (style->pixelSizes[x].pixelSize < pixelSize) {
965 d = pixelSize - style->pixelSizes[x].pixelSize + 1;
967 d = style->pixelSizes[x].pixelSize - pixelSize;
972 size = style->pixelSizes + x;
973 qCDebug(lcFontMatch,
" best size so far: %3d (%d)", size->pixelSize, pixelSize);
978 qCDebug(lcFontMatch,
" no size supports the script we want");
982 if (style->bitmapScalable && ! (styleStrategy & QFont::PreferQuality) &&
983 (distance * 10 / pixelSize) >= 2) {
986 size = style->pixelSize(0);
989 px = size->pixelSize;
994 unsigned int this_score = 0x0000;
996 PitchMismatch = 0x4000,
997 StyleMismatch = 0x2000,
998 BitmapScaledPenalty = 0x1000
1001 if ((pitch ==
'm' && !family->fixedPitch)
1002 || (pitch ==
'p' && family->fixedPitch))
1003 this_score += PitchMismatch;
1005 if (styleKey != style->key)
1006 this_score += StyleMismatch;
1007 if (!style->smoothScalable && px != size->pixelSize)
1008 this_score += BitmapScaledPenalty;
1009 if (px != pixelSize)
1010 this_score += qAbs(px - pixelSize);
1012 if (this_score < score) {
1013 qCDebug(lcFontMatch,
" found a match: score %x best score so far %x",
1017 desc->foundry = foundry;
1018 desc->style = style;
1021 qCDebug(lcFontMatch,
" score %x no better than best %x", this_score, score);
1030 if (familyName.isEmpty())
1032 return f->matchesFamilyName(familyName);
1036
1037
1038
1039
1040int QFontDatabasePrivate::match(
int script,
const QFontDef &request,
const QString &family_name,
1041 const QString &foundry_name, QtFontDesc *desc,
const QList<
int> &blacklistedFamilies,
1042 unsigned int *resultingScore)
1046 QtFontStyle::Key styleKey;
1047 styleKey.style = request.style;
1048 styleKey.weight = request.weight;
1050 styleKey.stretch = request.stretch ? request.stretch : 100;
1051 char pitch = request.ignorePitch ?
'*' : request.fixedPitch ?
'm' :
'p';
1054 qCDebug(lcFontMatch,
"QFontDatabasePrivate::match\n"
1056 " family: %s [%s], script: %d\n"
1058 " weight: %d, style: %d\n"
1062 family_name.isEmpty() ?
"-- first in script --" : family_name.toLatin1().constData(),
1063 foundry_name.isEmpty() ?
"-- any --" : foundry_name.toLatin1().constData(), script,
1064 request.styleName.isEmpty() ?
"-- any --" : request.styleName.toLatin1().constData(),
1065 request.weight, request.style, request.stretch, request.pixelSize, pitch);
1067 desc->family =
nullptr;
1068 desc->foundry =
nullptr;
1069 desc->style =
nullptr;
1070 desc->size =
nullptr;
1072 unsigned int score = ~0u;
1074 QMutexLocker locker(fontDatabaseMutex());
1075 QFontDatabasePrivate::ensureFontDatabase();
1077 auto writingSystem = qt_writing_system_for_script(script);
1078 if (writingSystem >= QFontDatabase::WritingSystemsCount)
1079 writingSystem = QFontDatabase::Any;
1081 auto *db = QFontDatabasePrivate::instance();
1082 for (
int x = 0; x < db->count; ++x) {
1083 if (blacklistedFamilies.contains(x))
1086 test.family = db->families[x];
1088 if (!matchFamilyName(family_name, test.family))
1090 if (!test.family->ensurePopulated())
1094 if (writingSystem != QFontDatabase::Any && !familySupportsWritingSystem(test.family, writingSystem))
1098 if (script == QFontDatabasePrivate::Script_Emoji && !test.family->colorFont)
1103 unsigned int newscore =
1104 bestFoundry(script, score, request.styleStrategy,
1105 test.family, foundry_name, styleKey, request.pixelSize, pitch,
1106 &test, request.styleName);
1107 if (test.foundry ==
nullptr && !foundry_name.isEmpty()) {
1110 newscore = bestFoundry(script, score, request.styleStrategy, test.family,
1111 QString(), styleKey, request.pixelSize,
1112 pitch, &test, request.styleName);
1115 if (newscore < score) {
1124 if (resultingScore !=
nullptr)
1125 *resultingScore = score;
1133 if (weight > QFont::Normal) {
1134 if (weight >= QFont::Black)
1135 result = QCoreApplication::translate(
"QFontDatabase",
"Black");
1136 else if (weight >= QFont::ExtraBold)
1137 result = QCoreApplication::translate(
"QFontDatabase",
"Extra Bold");
1138 else if (weight >= QFont::Bold)
1139 result = QCoreApplication::translate(
"QFontDatabase",
"Bold");
1140 else if (weight >= QFont::DemiBold)
1141 result = QCoreApplication::translate(
"QFontDatabase",
"Demi Bold");
1142 else if (weight >= QFont::Medium)
1143 result = QCoreApplication::translate(
"QFontDatabase",
"Medium",
"The Medium font weight");
1145 if (weight <= QFont::Thin)
1146 result = QCoreApplication::translate(
"QFontDatabase",
"Thin");
1147 else if (weight <= QFont::ExtraLight)
1148 result = QCoreApplication::translate(
"QFontDatabase",
"Extra Light");
1149 else if (weight <= QFont::Light)
1150 result = QCoreApplication::translate(
"QFontDatabase",
"Light");
1153 if (style == QFont::StyleItalic)
1154 result += u' ' + QCoreApplication::translate(
"QFontDatabase",
"Italic");
1155 else if (style == QFont::StyleOblique)
1156 result += u' ' + QCoreApplication::translate(
"QFontDatabase",
"Oblique");
1158 if (result.isEmpty())
1159 result = QCoreApplication::translate(
"QFontDatabase",
"Normal",
"The Normal or Regular font weight");
1161 return result.simplified();
1165
1166
1167
1168
1169QString QFontDatabase::styleString(
const QFont &font)
1171 return font.styleName().isEmpty() ? styleStringHelper(font.weight(), font.style())
1176
1177
1178
1179
1180QString QFontDatabase::styleString(
const QFontInfo &fontInfo)
1182 return fontInfo.styleName().isEmpty() ? styleStringHelper(fontInfo.weight(), fontInfo.style())
1183 : fontInfo.styleName();
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1239
1240
1241
1242
1243
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1288
1289
1290
1291
1292
1293
1294
1295
1296
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1349
1350
1351
1352
1353
1354QFontDatabasePrivate *QFontDatabasePrivate::ensureFontDatabase()
1356 auto *d = QFontDatabasePrivate::instance();
1357 if (!d->populated) {
1361 qCDebug(lcFontDb) <<
"Populating font database";
1363 if (Q_UNLIKELY(
qGuiApp ==
nullptr || QGuiApplicationPrivate::platformIntegration() ==
nullptr))
1364 qFatal(
"QFontDatabase: Must construct a QGuiApplication before accessing QFontDatabase");
1366 auto *platformFontDatabase = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
1367 platformFontDatabase->populateFontDatabase();
1369 for (
int i = 0; i < d->applicationFonts.size(); i++) {
1370 auto *font = &d->applicationFonts[i];
1371 if (!font->isNull() && !font->isPopulated())
1372 platformFontDatabase->addApplicationFont(font->data, font->fileName, font);
1378 d->populated =
true;
1384
1385
1386
1387
1388
1389
1390QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems()
1392 QMutexLocker locker(fontDatabaseMutex());
1393 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1395 quint64 writingSystemsFound = 0;
1396 static_assert(WritingSystemsCount < 64);
1398 for (
int i = 0; i < d->count; ++i) {
1399 QtFontFamily *family = d->families[i];
1400 if (!family->ensurePopulated())
1403 if (family->count == 0)
1405 for (uint x = Latin; x < uint(WritingSystemsCount); ++x) {
1406 if (family->writingSystems[x] & QtFontFamily::Supported)
1407 writingSystemsFound |= quint64(1) << x;
1414 QList<WritingSystem> list;
1415 list.reserve(qPopulationCount(writingSystemsFound));
1416 for (uint x = Latin ; x < uint(WritingSystemsCount); ++x) {
1417 if (writingSystemsFound & (quint64(1) << x))
1418 list.push_back(WritingSystem(x));
1425
1426
1427
1428
1429
1430QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems(
const QString &family)
1432 QString familyName, foundryName;
1433 parseFontName(family, foundryName, familyName);
1435 QMutexLocker locker(fontDatabaseMutex());
1436 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1438 QList<WritingSystem> list;
1439 QtFontFamily *f = d->family(familyName);
1440 if (!f || f->count == 0)
1443 for (
int x = Latin; x < WritingSystemsCount; ++x) {
1444 const WritingSystem writingSystem = WritingSystem(x);
1445 if (f->writingSystems[writingSystem] & QtFontFamily::Supported)
1446 list.append(writingSystem);
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462QStringList QFontDatabase::families(WritingSystem writingSystem)
1464 QMutexLocker locker(fontDatabaseMutex());
1465 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1468 for (
int i = 0; i < d->count; i++) {
1469 QtFontFamily *f = d->families[i];
1470 if (f->populated && f->count == 0)
1472 if (writingSystem != Any) {
1473 if (!f->ensurePopulated())
1475 if (f->writingSystems[writingSystem] != QtFontFamily::Supported)
1478 if (!f->populated || f->count == 1) {
1479 flist.append(f->name);
1481 for (
int j = 0; j < f->count; j++) {
1482 QString str = f->name;
1483 QString foundry = f->foundries[j]->name;
1484 if (!foundry.isEmpty()) {
1497
1498
1499
1500
1501
1502
1503QStringList QFontDatabase::styles(
const QString &family)
1505 QString familyName, foundryName;
1506 parseFontName(family, foundryName, familyName);
1508 QMutexLocker locker(fontDatabaseMutex());
1509 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1512 QtFontFamily *f = d->family(familyName);
1516 QtFontFoundry allStyles(foundryName);
1517 for (
int j = 0; j < f->count; j++) {
1518 QtFontFoundry *foundry = f->foundries[j];
1519 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1520 for (
int k = 0; k < foundry->count; k++) {
1521 QtFontStyle::Key ke(foundry->styles[k]->key);
1524 foundry->styles[k]->styleName,
1525 QtFontFoundry::AddWhenMissing);
1530 l.reserve(allStyles.count);
1531 for (
int i = 0; i < allStyles.count; i++) {
1532 l.append(allStyles.styles[i]->styleName.isEmpty() ?
1533 styleStringHelper(allStyles.styles[i]->key.weight,
1534 (QFont::Style)allStyles.styles[i]->key.style) :
1535 allStyles.styles[i]->styleName);
1541
1542
1543
1545bool QFontDatabase::isFixedPitch(
const QString &family,
1546 const QString &style)
1550 QString familyName, foundryName;
1551 parseFontName(family, foundryName, familyName);
1553 QMutexLocker locker(fontDatabaseMutex());
1554 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1556 QtFontFamily *f = d->family(familyName);
1557 return (f && f->fixedPitch);
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570bool QFontDatabase::isBitmapScalable(
const QString &family,
1571 const QString &style)
1573 QString familyName, foundryName;
1574 parseFontName(family, foundryName, familyName);
1576 QMutexLocker locker(fontDatabaseMutex());
1577 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1579 QtFontFamily *f = d->family(familyName);
1583 QtFontStyle::Key styleKey(style);
1584 for (
int j = 0; j < f->count; j++) {
1585 QtFontFoundry *foundry = f->foundries[j];
1586 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1587 for (
int k = 0; k < foundry->count; k++)
1588 if ((style.isEmpty() ||
1589 foundry->styles[k]->styleName == style ||
1590 foundry->styles[k]->key == styleKey)
1591 && foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
1601
1602
1603
1604
1605
1606
1607
1608bool QFontDatabase::isSmoothlyScalable(
const QString &family,
const QString &style)
1610 QString familyName, foundryName;
1611 parseFontName(family, foundryName, familyName);
1613 QMutexLocker locker(fontDatabaseMutex());
1614 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1616 QtFontFamily *f = d->family(familyName);
1618 for (
int i = 0; i < d->count; i++) {
1619 if (d->families[i]->matchesFamilyName(familyName)) {
1621 if (f->ensurePopulated())
1629 const QtFontStyle::Key styleKey(style);
1630 for (
int j = 0; j < f->count; j++) {
1631 QtFontFoundry *foundry = f->foundries[j];
1632 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1633 for (
int k = 0; k < foundry->count; k++) {
1634 const QtFontStyle *fontStyle = foundry->styles[k];
1635 const bool smoothScalable =
1636 fontStyle->smoothScalable
1637 && ((style.isEmpty()
1638 || fontStyle->styleName == style
1639 || fontStyle->key == styleKey)
1640 || (fontStyle->styleName.isEmpty()
1641 && style == styleStringHelper(fontStyle->key.weight,
1642 QFont::Style(fontStyle->key.style))));
1652
1653
1654
1655
1656
1657bool QFontDatabase::isScalable(
const QString &family,
1658 const QString &style)
1660 QMutexLocker locker(fontDatabaseMutex());
1661 if (isSmoothlyScalable(family, style))
1663 return isBitmapScalable(family, style);
1668
1669
1670
1671
1672
1673QList<
int> QFontDatabase::pointSizes(
const QString &family,
1674 const QString &styleName)
1676 if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable())
1677 return standardSizes();
1679 QString familyName, foundryName;
1680 parseFontName(family, foundryName, familyName);
1682 QMutexLocker locker(fontDatabaseMutex());
1683 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1687 QtFontFamily *fam = d->family(familyName);
1688 if (!fam)
return sizes;
1691 const int dpi = qt_defaultDpiY();
1693 QtFontStyle::Key styleKey(styleName);
1694 for (
int j = 0; j < fam->count; j++) {
1695 QtFontFoundry *foundry = fam->foundries[j];
1696 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1697 QtFontStyle *style = foundry->style(styleKey, styleName);
1698 if (!style)
continue;
1700 if (style->smoothScalable)
1701 return standardSizes();
1703 for (
int l = 0; l < style->count; l++) {
1704 const QtFontSize *size = style->pixelSizes + l;
1707 const int pointSize = qRound(size->pixelSize * 72.0 / dpi);
1708 if (! sizes.contains(pointSize))
1709 sizes.append(pointSize);
1715 std::sort(sizes.begin(), sizes.end());
1720
1721
1722
1723
1724
1725QFont QFontDatabase::font(
const QString &family,
const QString &style,
1728 QString familyName, foundryName;
1729 parseFontName(family, foundryName, familyName);
1730 QMutexLocker locker(fontDatabaseMutex());
1731 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1733 QtFontFoundry allStyles(foundryName);
1734 QtFontFamily *f = d->family(familyName);
1735 if (!f)
return QGuiApplication::font();
1737 for (
int j = 0; j < f->count; j++) {
1738 QtFontFoundry *foundry = f->foundries[j];
1739 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1740 for (
int k = 0; k < foundry->count; k++) {
1741 allStyles.style(foundry->styles[k]->key,
1742 foundry->styles[k]->styleName,
1743 QtFontFoundry::AddWhenMissing);
1748 QtFontStyle::Key styleKey(style);
1749 QtFontStyle *s = bestStyle(&allStyles, styleKey, style);
1752 return QGuiApplication::font();
1754 QFont fnt(QStringList{family}, pointSize, s->key.weight);
1755 fnt.setStyle((QFont::Style)s->key.style);
1756 if (!s->styleName.isEmpty())
1757 fnt.setStyleName(s->styleName);
1763
1764
1765
1766
1767
1768
1769
1770QList<
int> QFontDatabase::smoothSizes(
const QString &family,
1771 const QString &styleName)
1773 if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable())
1774 return standardSizes();
1776 QString familyName, foundryName;
1777 parseFontName(family, foundryName, familyName);
1779 QMutexLocker locker(fontDatabaseMutex());
1780 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1784 QtFontFamily *fam = d->family(familyName);
1788 const int dpi = qt_defaultDpiY();
1790 QtFontStyle::Key styleKey(styleName);
1791 for (
int j = 0; j < fam->count; j++) {
1792 QtFontFoundry *foundry = fam->foundries[j];
1793 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1794 QtFontStyle *style = foundry->style(styleKey, styleName);
1795 if (!style)
continue;
1797 if (style->smoothScalable)
1798 return QFontDatabase::standardSizes();
1800 for (
int l = 0; l < style->count; l++) {
1801 const QtFontSize *size = style->pixelSizes + l;
1804 const int pointSize = qRound(size->pixelSize * 72.0 / dpi);
1805 if (! sizes.contains(pointSize))
1806 sizes.append(pointSize);
1812 std::sort(sizes.begin(), sizes.end());
1818
1819
1820
1821
1822QList<
int> QFontDatabase::standardSizes()
1824 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->standardSizes();
1829
1830
1831
1832
1833
1834bool QFontDatabase::italic(
const QString &family,
const QString &style)
1836 QString familyName, foundryName;
1837 parseFontName(family, foundryName, familyName);
1839 QMutexLocker locker(fontDatabaseMutex());
1840 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1842 QtFontFoundry allStyles(foundryName);
1843 QtFontFamily *f = d->family(familyName);
1844 if (!f)
return false;
1846 for (
int j = 0; j < f->count; j++) {
1847 QtFontFoundry *foundry = f->foundries[j];
1848 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1849 for (
int k = 0; k < foundry->count; k++) {
1850 allStyles.style(foundry->styles[k]->key,
1851 foundry->styles[k]->styleName,
1852 QtFontFoundry::AddWhenMissing);
1857 QtFontStyle::Key styleKey(style);
1858 QtFontStyle *s = allStyles.style(styleKey, style);
1859 return s && s->key.style == QFont::StyleItalic;
1864
1865
1866
1867
1868
1869bool QFontDatabase::bold(
const QString &family,
1870 const QString &style)
1872 QString familyName, foundryName;
1873 parseFontName(family, foundryName, familyName);
1875 QMutexLocker locker(fontDatabaseMutex());
1876 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1878 QtFontFoundry allStyles(foundryName);
1879 QtFontFamily *f = d->family(familyName);
1880 if (!f)
return false;
1882 for (
int j = 0; j < f->count; j++) {
1883 QtFontFoundry *foundry = f->foundries[j];
1884 if (foundryName.isEmpty() ||
1885 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1886 for (
int k = 0; k < foundry->count; k++) {
1887 allStyles.style(foundry->styles[k]->key,
1888 foundry->styles[k]->styleName,
1889 QtFontFoundry::AddWhenMissing);
1894 QtFontStyle::Key styleKey(style);
1895 QtFontStyle *s = allStyles.style(styleKey, style);
1896 return s && s->key.weight >= QFont::Bold;
1901
1902
1903
1904
1905
1906
1907int QFontDatabase::weight(
const QString &family,
1908 const QString &style)
1910 QString familyName, foundryName;
1911 parseFontName(family, foundryName, familyName);
1913 QMutexLocker locker(fontDatabaseMutex());
1914 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1916 QtFontFoundry allStyles(foundryName);
1917 QtFontFamily *f = d->family(familyName);
1920 for (
int j = 0; j < f->count; j++) {
1921 QtFontFoundry *foundry = f->foundries[j];
1922 if (foundryName.isEmpty() ||
1923 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1924 for (
int k = 0; k < foundry->count; k++) {
1925 allStyles.style(foundry->styles[k]->key,
1926 foundry->styles[k]->styleName,
1927 QtFontFoundry::AddWhenMissing);
1932 QtFontStyle::Key styleKey(style);
1933 QtFontStyle *s = allStyles.style(styleKey, style);
1934 return s ? s->key.weight : -1;
1939bool QFontDatabase::hasFamily(
const QString &family)
1941 QString parsedFamily, foundry;
1942 parseFontName(family, foundry, parsedFamily);
1943 const QString familyAlias = QFontDatabasePrivate::resolveFontFamilyAlias(parsedFamily);
1945 QMutexLocker locker(fontDatabaseMutex());
1946 QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase();
1948 for (
int i = 0; i < d->count; i++) {
1949 QtFontFamily *f = d->families[i];
1950 if (f->populated && f->count == 0)
1952 if (familyAlias.compare(f->name, Qt::CaseInsensitive) == 0)
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972bool QFontDatabase::isPrivateFamily(
const QString &family)
1974 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->isPrivateFontFamily(family);
1979
1980
1981
1982QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
1984 const char *name =
nullptr;
1985 switch (writingSystem) {
1987 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Any");
1990 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Latin");
1993 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Greek");
1996 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Cyrillic");
1999 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Armenian");
2002 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Hebrew");
2005 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Arabic");
2008 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Syriac");
2011 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Thaana");
2014 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Devanagari");
2017 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Bengali");
2020 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Gurmukhi");
2023 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Gujarati");
2026 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Oriya");
2029 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Tamil");
2032 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Telugu");
2035 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Kannada");
2038 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Malayalam");
2041 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Sinhala");
2044 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Thai");
2047 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Lao");
2050 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Tibetan");
2053 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Myanmar");
2056 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Georgian");
2059 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Khmer");
2061 case SimplifiedChinese:
2062 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Simplified Chinese");
2064 case TraditionalChinese:
2065 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Traditional Chinese");
2068 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Japanese");
2071 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Korean");
2074 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Vietnamese");
2077 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Symbol");
2080 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Ogham");
2083 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"Runic");
2086 name = QT_TRANSLATE_NOOP(
"QFontDatabase",
"N'Ko");
2089 Q_ASSERT_X(
false,
"QFontDatabase::writingSystemName",
"invalid 'writingSystem' parameter");
2092 return QCoreApplication::translate(
"QFontDatabase", name);
2096
2097
2098QString QFontDatabase::writingSystemSample(WritingSystem writingSystem)
2100 return [&]() -> QStringView {
2101 switch (writingSystem) {
2102 case QFontDatabase::Any:
2103 case QFontDatabase::Symbol:
2106 case QFontDatabase::Latin:
2109 return u"Aa\x00C3\x00E1Zz";
2110 case QFontDatabase::Greek:
2111 return u"\x0393\x03B1\x03A9\x03C9";
2112 case QFontDatabase::Cyrillic:
2113 return u"\x0414\x0434\x0436\x044f";
2114 case QFontDatabase::Armenian:
2115 return u"\x053f\x054f\x056f\x057f";
2116 case QFontDatabase::Hebrew:
2117 return u"\x05D0\x05D1\x05D2\x05D3";
2118 case QFontDatabase::Arabic:
2119 return u"\x0623\x0628\x062C\x062F\x064A\x0629\x0020\x0639\x0631\x0628\x064A\x0629";
2120 case QFontDatabase::Syriac:
2121 return u"\x0715\x0725\x0716\x0726";
2122 case QFontDatabase::Thaana:
2123 return u"\x0784\x0794\x078c\x078d";
2124 case QFontDatabase::Devanagari:
2125 return u"\x0905\x0915\x0925\x0935";
2126 case QFontDatabase::Bengali:
2127 return u"\x0986\x0996\x09a6\x09b6";
2128 case QFontDatabase::Gurmukhi:
2129 return u"\x0a05\x0a15\x0a25\x0a35";
2130 case QFontDatabase::Gujarati:
2131 return u"\x0a85\x0a95\x0aa5\x0ab5";
2132 case QFontDatabase::Oriya:
2133 return u"\x0b06\x0b16\x0b2b\x0b36";
2134 case QFontDatabase::Tamil:
2135 return u"\x0b89\x0b99\x0ba9\x0bb9";
2136 case QFontDatabase::Telugu:
2137 return u"\x0c05\x0c15\x0c25\x0c35";
2138 case QFontDatabase::Kannada:
2139 return u"\x0c85\x0c95\x0ca5\x0cb5";
2140 case QFontDatabase::Malayalam:
2141 return u"\x0d05\x0d15\x0d25\x0d35";
2142 case QFontDatabase::Sinhala:
2143 return u"\x0d90\x0da0\x0db0\x0dc0";
2144 case QFontDatabase::Thai:
2145 return u"\x0e02\x0e12\x0e22\x0e32";
2146 case QFontDatabase::Lao:
2147 return u"\x0e8d\x0e9d\x0ead\x0ebd";
2148 case QFontDatabase::Tibetan:
2149 return u"\x0f00\x0f01\x0f02\x0f03";
2150 case QFontDatabase::Myanmar:
2151 return u"\x1000\x1001\x1002\x1003";
2152 case QFontDatabase::Georgian:
2153 return u"\x10a0\x10b0\x10c0\x10d0";
2154 case QFontDatabase::Khmer:
2155 return u"\x1780\x1790\x17b0\x17c0";
2156 case QFontDatabase::SimplifiedChinese:
2157 return u"\x4e2d\x6587\x8303\x4f8b";
2158 case QFontDatabase::TraditionalChinese:
2159 return u"\x4e2d\x6587\x7bc4\x4f8b";
2160 case QFontDatabase::Japanese:
2161 return u"\x30b5\x30f3\x30d7\x30eb\x3067\x3059";
2162 case QFontDatabase::Korean:
2163 return u"\xac00\xac11\xac1a\xac2f";
2164 case QFontDatabase::Vietnamese:
2165 return u"\x1ED7\x1ED9\x1ED1\x1ED3";
2166 case QFontDatabase::Ogham:
2167 return u"\x1681\x1682\x1683\x1684";
2168 case QFontDatabase::Runic:
2169 return u"\x16a0\x16a1\x16a2\x16a3";
2170 case QFontDatabase::Nko:
2171 return u"\x7ca\x7cb\x7cc\x7cd";
2178void QFontDatabasePrivate::parseFontName(
const QString &name, QString &foundry, QString &family)
2180 QT_PREPEND_NAMESPACE(parseFontName)(name, foundry, family);
2186 QMutexLocker locker(fontDatabaseMutex());
2187 return QFontDatabasePrivate::instance()->applicationFonts.value(index).data;
2190int QFontDatabasePrivate::addAppFont(
const QByteArray &fontData,
const QString &fileName)
2192 QFontDatabasePrivate::ApplicationFont font;
2193 font.data = fontData;
2194 font.fileName = fileName;
2196 Q_TRACE(QFontDatabasePrivate_addAppFont, fileName);
2199 for (i = 0; i < applicationFonts.size(); ++i)
2200 if (applicationFonts.at(i).isNull())
2202 if (i >= applicationFonts.size()) {
2203 applicationFonts.append(ApplicationFont());
2204 i = applicationFonts.size() - 1;
2207 if (font.fileName.isEmpty() && !fontData.isEmpty())
2208 font.fileName =
":qmemoryfonts/"_L1 + QString::number(i);
2210 auto *platformFontDatabase = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
2211 platformFontDatabase->addApplicationFont(font.data, font.fileName, &font);
2212 if (font.properties.isEmpty())
2215 applicationFonts[i] = font;
2219 QFontCache::instance()->clear();
2221 fallbacksCache.clear();
2223 emit
qApp->fontDatabaseChanged();
2228bool QFontDatabasePrivate::isApplicationFont(
const QString &fileName)
2230 for (
int i = 0; i < applicationFonts.size(); ++i)
2231 if (applicationFonts.at(i).fileName == fileName)
2236void QFontDatabasePrivate::setApplicationFallbackFontFamilies(ExtendedScript script,
const QStringList &familyNames)
2238 applicationFallbackFontFamiliesHash[script] = familyNames;
2240 QFontCache::instance()->clear();
2241 fallbacksCache.clear();
2244QStringList QFontDatabasePrivate::applicationFallbackFontFamilies(ExtendedScript script)
2246 return applicationFallbackFontFamiliesHash.value(script);
2249bool QFontDatabasePrivate::removeApplicationFallbackFontFamily(ExtendedScript script,
const QString &familyName)
2251 auto it = applicationFallbackFontFamiliesHash.find(script);
2252 if (it != applicationFallbackFontFamiliesHash.end()) {
2253 if (it->removeAll(familyName) > 0) {
2255 it = applicationFallbackFontFamiliesHash.erase(it);
2256 QFontCache::instance()->clear();
2257 fallbacksCache.clear();
2265void QFontDatabasePrivate::addApplicationFallbackFontFamily(ExtendedScript script,
const QString &familyName)
2267 auto it = applicationFallbackFontFamiliesHash.find(script);
2268 if (it == applicationFallbackFontFamiliesHash.end())
2269 it = applicationFallbackFontFamiliesHash.insert(script, QStringList{});
2271 it->prepend(familyName);
2273 QFontCache::instance()->clear();
2274 fallbacksCache.clear();
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295int QFontDatabase::addApplicationFont(
const QString &fileName)
2298 if (!QFileInfo(fileName).isNativePath()) {
2300 if (!f.open(QIODevice::ReadOnly))
2303 Q_TRACE(QFontDatabase_addApplicationFont, fileName);
2307 QMutexLocker locker(fontDatabaseMutex());
2308 return QFontDatabasePrivate::instance()->addAppFont(data, fileName);
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323int QFontDatabase::addApplicationFontFromData(
const QByteArray &fontData)
2325 QMutexLocker locker(fontDatabaseMutex());
2326 return QFontDatabasePrivate::instance()->addAppFont(fontData, QString() );
2330
2331
2332
2333
2334
2335
2336
2337QStringList QFontDatabase::applicationFontFamilies(
int id)
2339 QMutexLocker locker(fontDatabaseMutex());
2340 auto *d = QFontDatabasePrivate::instance();
2343 ret.reserve(d->applicationFonts.value(id).properties.size());
2345 for (
const auto &properties : d->applicationFonts.value(id).properties)
2346 ret.append(properties.familyName);
2352
2353
2354
2355
2356
2357
2358
2360QFont QFontDatabase::systemFont(QFontDatabase::SystemFont type)
2362 const QFont *font =
nullptr;
2363 if (
const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
2366 font = theme->font(QPlatformTheme::SystemFont);
2369 font = theme->font(QPlatformTheme::FixedFont);
2372 font = theme->font(QPlatformTheme::TitleBarFont);
2374 case SmallestReadableFont:
2375 font = theme->font(QPlatformTheme::MiniFont);
2382 else if (QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration())
2383 return integration->fontDatabase()->defaultFont();
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399bool QFontDatabase::removeApplicationFont(
int handle)
2401 QMutexLocker locker(fontDatabaseMutex());
2403 auto *db = QFontDatabasePrivate::instance();
2404 if (handle < 0 || handle >= db->applicationFonts.size())
2407 db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425bool QFontDatabase::removeAllApplicationFonts()
2427 QMutexLocker locker(fontDatabaseMutex());
2429 auto *db = QFontDatabasePrivate::instance();
2430 if (!db || db->applicationFonts.isEmpty())
2433 db->applicationFonts.clear();
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470void QFontDatabase::addApplicationFallbackFontFamily(QChar::Script script,
const QString &familyName)
2472 QMutexLocker locker(fontDatabaseMutex());
2474 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2475 qCWarning(lcFontDb) <<
"Invalid script passed to addApplicationFallbackFontFamily:" << script;
2479 if (script == QChar::Script_Latin)
2480 script = QChar::Script_Common;
2482 auto *db = QFontDatabasePrivate::instance();
2483 db->addApplicationFallbackFontFamily(QFontDatabasePrivate::ExtendedScript(script), familyName);
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496bool QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script script,
const QString &familyName)
2498 QMutexLocker locker(fontDatabaseMutex());
2500 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2501 qCWarning(lcFontDb) <<
"Invalid script passed to removeApplicationFallbackFontFamily:" << script;
2505 if (script == QChar::Script_Latin)
2506 script = QChar::Script_Common;
2508 auto *db = QFontDatabasePrivate::instance();
2509 return db->removeApplicationFallbackFontFamily(QFontDatabasePrivate::ExtendedScript(script),
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526void QFontDatabase::setApplicationFallbackFontFamilies(QChar::Script script,
const QStringList &familyNames)
2528 QMutexLocker locker(fontDatabaseMutex());
2530 if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
2531 qCWarning(lcFontDb) <<
"Invalid script passed to setApplicationFallbackFontFamilies:" << script;
2535 if (script == QChar::Script_Latin)
2536 script = QChar::Script_Common;
2538 auto *db = QFontDatabasePrivate::instance();
2539 db->setApplicationFallbackFontFamilies(QFontDatabasePrivate::ExtendedScript(script),
2544
2545
2546
2547
2548
2549
2550
2551QStringList QFontDatabase::applicationFallbackFontFamilies(QChar::Script script)
2553 QMutexLocker locker(fontDatabaseMutex());
2555 if (script >= QChar::ScriptCount) {
2556 qCWarning(lcFontDb) <<
"Invalid script passed to applicationFallbackFontFamilies:" << script;
2557 return QStringList{};
2560 if (script == QChar::Script_Latin)
2561 script = QChar::Script_Common;
2563 auto *db = QFontDatabasePrivate::instance();
2564 return db->applicationFallbackFontFamilies(QFontDatabasePrivate::ExtendedScript(script));
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578void QFontDatabase::addApplicationEmojiFontFamily(
const QString &familyName)
2580 QMutexLocker locker(fontDatabaseMutex());
2581 auto *db = QFontDatabasePrivate::instance();
2582 db->addApplicationFallbackFontFamily(QFontDatabasePrivate::Script_Emoji, familyName);
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595bool QFontDatabase::removeApplicationEmojiFontFamily(
const QString &familyName)
2597 QMutexLocker locker(fontDatabaseMutex());
2598 auto *db = QFontDatabasePrivate::instance();
2599 return db->removeApplicationFallbackFontFamily(QFontDatabasePrivate::Script_Emoji,
2604
2605
2606
2607
2608
2609
2610void QFontDatabase::setApplicationEmojiFontFamilies(
const QStringList &familyNames)
2612 QMutexLocker locker(fontDatabaseMutex());
2613 auto *db = QFontDatabasePrivate::instance();
2614 db->setApplicationFallbackFontFamilies(QFontDatabasePrivate::Script_Emoji,
2619
2620
2621
2622
2623
2624
2625QStringList QFontDatabase::applicationEmojiFontFamilies()
2627 QMutexLocker locker(fontDatabaseMutex());
2628 auto *db = QFontDatabasePrivate::instance();
2629 return db->applicationFallbackFontFamilies(QFontDatabasePrivate::Script_Emoji);
2633
2634
2635QFontEngine *QFontDatabasePrivate::findFont(
const QFontDef &req,
2637 bool preferScriptOverFamily)
2639 QMutexLocker locker(fontDatabaseMutex());
2640 ensureFontDatabase();
2642 QFontEngine *engine;
2645 const QFontDef request =
static_cast<QWindowsFontDatabaseBase *>(
2646 QGuiApplicationPrivate::platformIntegration()->fontDatabase())
2647 ->sanitizeRequest(req);
2649 const QFontDef &request = req;
2652#if defined(QT_BUILD_INTERNAL)
2654 if (qt_enable_test_font && request.families.first() ==
"__Qt__Box__Engine__"_L1) {
2655 engine =
new QTestFontEngine(request.pixelSize);
2656 engine->fontDef = request;
2661 QFontCache *fontCache = QFontCache::instance();
2666 bool multi = !(request.styleStrategy & QFont::NoFontMerging);
2667 QFontCache::Key key(request, script, multi ? 1 : 0);
2668 engine = fontCache->findEngine(key);
2670 qCDebug(lcFontMatch,
"Cache hit level 1");
2674 if (request.pixelSize > 0xffff) {
2676 qCDebug(lcFontMatch,
"Rejecting request for pixel size %g2, returning box engine",
double(request.pixelSize));
2677 return new QFontEngineBox(32);
2680 QString family_name, foundry_name;
2681 const QString requestFamily = request.families.at(0);
2682 parseFontName(requestFamily, foundry_name, family_name);
2684 QList<
int> blackListed;
2685 unsigned int score = UINT_MAX;
2696 qCDebug(lcFontMatch,
"Family name match pass: Looking for family name '%s'%s", qPrintable(family_name),
2697 script == QFontDatabasePrivate::Script_Emoji ?
" (color font required)" :
"");
2698 int index = match(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed, &score);
2703 if (score > 0 && QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamilyAliases(family_name)) {
2704 qCDebug(lcFontMatch,
"Alias match pass: Imperfect result and aliases populated, so trying again%s",
2705 script == QFontDatabasePrivate::Script_Emoji ?
" (color font required)" :
"");
2707 index = match(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
2715 if (index < 0 && !multi && !preferScriptOverFamily) {
2716 qCDebug(lcFontMatch,
"NoFontMerging pass: Font not found with requested script, but we try to load it anyway");
2717 index = match(QChar::Script_Common, request, family_name, foundry_name, &desc, blackListed);
2721 QFontDef fontDef = request;
2724 if (fontDef.families.isEmpty())
2725 fontDef.families = QStringList(desc.family->name);
2727 engine = loadEngine(script, fontDef, desc.family, desc.foundry, desc.style, desc.size);
2730 initFontDef(desc, request, &engine->fontDef, multi);
2732 qCDebug(lcFontMatch,
"Failed to create font engine for font '%s'. Blacklisting %d",
2733 qPrintable(desc.family->name), index);
2734 blackListed.append(index);
2737 qCDebug(lcFontMatch,
" NO MATCH FOUND\n");
2745 if (!requestFamily.isEmpty()) {
2746 qCDebug(lcFontMatch,
"Fallbacks pass: Looking for a fallback matching script %d", script);
2747 QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
2748 if (styleHint == QFont::AnyStyle && request.fixedPitch)
2749 styleHint = QFont::TypeWriter;
2751 QStringList fallbacks = request.fallBackFamilies
2752 + fallbacksForFamily(requestFamily,
2753 QFont::Style(request.style),
2755 QFontDatabasePrivate::ExtendedScript(script));
2756 if (script > QChar::Script_Common)
2757 fallbacks += QString();
2759 auto findMatchingFallback = [&fallbacks,
2764 &request](
int lookupScript,
int cacheScript) {
2765 QFontEngine *engine =
nullptr;
2766 for (
int i = 0; !engine && i < fallbacks.size(); i++) {
2767 QFontDef def = request;
2769 def.families = QStringList(fallbacks.at(i));
2770 QFontCache::Key key(def, cacheScript, multi ? 1 : 0);
2771 engine = fontCache->findEngine(key);
2775 index = match(lookupScript,
2777 def.families.constFirst(),
2783 QFontDef loadDef = def;
2784 if (loadDef.families.isEmpty())
2785 loadDef.families = QStringList(desc.family->name);
2786 engine = loadEngine(cacheScript,
2793 initFontDef(desc, loadDef, &engine->fontDef, multi);
2795 qCDebug(lcFontMatch,
"Failed to create font engine for fallback %d (%s). Blacklisting %d",
2796 i, qPrintable(desc.family->name), index);
2797 blackListed.append(index);
2800 }
while (index >= 0 && !engine);
2807 engine = findMatchingFallback(multi && script != QFontDatabasePrivate::Script_Emoji
2808 ? QChar::Script_Common
2815 if (!engine && script == QFontDatabasePrivate::Script_Emoji) {
2816 qCDebug(lcFontMatch,
"No color fonts found on system. Doing final fallback match.");
2820 if (!requestFamily.isEmpty())
2821 fallbacks.prepend(requestFamily);
2822 engine = findMatchingFallback(QChar::Script_Common, script);
2827 engine =
new QFontEngineBox(request.pixelSize);
2828 qCDebug(lcFontMatch,
"returning box engine");
2835void QFontDatabasePrivate::load(
const QFontPrivate *d,
int script)
2837 QFontDef req = d->request;
2839 if (req.pixelSize == -1) {
2840 req.pixelSize = std::floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100;
2841 req.pixelSize = qRound(req.pixelSize);
2844 if (req.pointSize < 0 && d->dpi > 0)
2845 req.pointSize = req.pixelSize*72.0/d->dpi;
2848 const QStringList fallBackFamilies = familyList(req);
2850 if (!d->engineData) {
2851 QFontCache *fontCache = QFontCache::instance();
2855 if (!d->request.families.isEmpty())
2856 req.families = fallBackFamilies;
2858 d->engineData = fontCache->findEngineData(req);
2859 if (!d->engineData) {
2861 d->engineData =
new QFontEngineData;
2862 fontCache->insertEngineData(req, d->engineData);
2864 d->engineData->ref.ref();
2868 if (d->engineData->engines[script])
2871 QFontEngine *fe =
nullptr;
2873 Q_TRACE(QFontDatabase_load, req.families.join(QLatin1Char(
';')), req.pointSize);
2875 req.fallBackFamilies = fallBackFamilies;
2876 if (!req.fallBackFamilies.isEmpty())
2877 req.families = QStringList(req.fallBackFamilies.takeFirst());
2880 QStringList family_list;
2882 if (!req.families.isEmpty()) {
2884 family_list << req.families.at(0);
2887 const auto families = QGuiApplication::font().families();
2888 if (!families.isEmpty()) {
2889 QString defaultFamily = families.first();
2890 if (! family_list.contains(defaultFamily))
2891 family_list << defaultFamily;
2897 family_list << QString();
2899 QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
2900 for (; !fe && it != end; ++it) {
2901 req.families = QStringList(*it);
2903 fe = QFontDatabasePrivate::findFont(req, script);
2905 if (fe->type() == QFontEngine::Box && !req.families.at(0).isEmpty()) {
2906 if (fe->ref.loadRelaxed() == 0)
2911 fe->fontDef.pointSize = qreal(
double((fe->fontDef.pixelSize * 72) / d->dpi));
2916 req.fallBackFamilies.clear();
2920 if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
2921 for (
int i = 0; i < QFontDatabasePrivate::ScriptCount; ++i) {
2922 if (!d->engineData->engines[i]) {
2923 d->engineData->engines[i] = fe;
2928 d->engineData->engines[script] = fe;
2933QString QFontDatabasePrivate::resolveFontFamilyAlias(
const QString &family)
2935 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->resolveFontFamilyAlias(family);
2938Q_GUI_EXPORT
QStringList qt_sort_families_by_writing_system(QFontDatabasePrivate::ExtendedScript script,
2939 const QStringList &families)
2941 size_t writingSystem = qt_writing_system_for_script(script);
2942 if (script != QFontDatabasePrivate::Script_Emoji
2943 && (writingSystem == QFontDatabase::Any
2944 || writingSystem >= QFontDatabase::WritingSystemsCount)) {
2948 auto *db = QFontDatabasePrivate::instance();
2949 QMultiMap<uint, QString> supported;
2950 for (
int i = 0; i < families.size(); ++i) {
2951 const QString &family = families.at(i);
2953 QtFontFamily *testFamily =
nullptr;
2954 for (
int x = 0; x < db->count; ++x) {
2955 if (Q_UNLIKELY(matchFamilyName(family, db->families[x]))) {
2956 testFamily = db->families[x];
2957 if (testFamily->ensurePopulated())
2963 if (testFamily ==
nullptr
2964 || (script == QFontDatabasePrivate::Script_Emoji && !testFamily->colorFont)
2965 || (script != QFontDatabasePrivate::Script_Emoji && !familySupportsWritingSystem(testFamily, writingSystem))) {
2969 supported.insert(order, family);
2972 return supported.values();
2977#include "moc_qfontdatabase.cpp"
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,...)