7#include <QtGui/private/qfontengine_ft_p.h>
10#include <QtCore/QElapsedTimer>
11#include <QtCore/QFile>
13#include <qpa/qplatformnativeinterface.h>
14#include <qpa/qplatformscreen.h>
15#include <qpa/qplatformintegration.h>
16#include <qpa/qplatformservices.h>
18#include <QtGui/private/qguiapplication_p.h>
20#include <QtGui/qguiapplication.h>
22#include <QtCore/private/qduplicatetracker_p.h>
24#include <fontconfig/fontconfig.h>
25#if FC_VERSION >= 20402
26#include <fontconfig/fcfreetype.h>
35 return qtLower + ((fcweight - fcLower) * (qtUpper - qtLower)) / (fcUpper - fcLower);
47 if (fcweight <= FC_WEIGHT_THIN)
49 if (fcweight <= FC_WEIGHT_ULTRALIGHT)
51 if (fcweight <= FC_WEIGHT_LIGHT)
53 if (fcweight <= FC_WEIGHT_NORMAL)
55 if (fcweight <= FC_WEIGHT_MEDIUM)
57 if (fcweight <= FC_WEIGHT_DEMIBOLD)
59 if (fcweight <= FC_WEIGHT_BOLD)
61 if (fcweight <= FC_WEIGHT_ULTRABOLD)
63 if (fcweight <= FC_WEIGHT_BLACK)
65 if (fcweight <= FC_WEIGHT_ULTRABLACK)
75 const int maxStretch = 4000;
79 else if (fcwidth > maxStretch)
80 qtstretch = maxStretch;
295#if FC_VERSION >= 20297
299static const char capabilityForWritingSystem[][5] = {
340 const char *stylehint =
nullptr;
343 stylehint =
"sans-serif";
350 stylehint =
"monospace";
353 stylehint =
"cursive";
356 stylehint =
"fantasy";
372 FT_Face
face =
nullptr,
377 FcChar8 *
value =
nullptr;
384 FcChar8 *foundry_value;
385 FcChar8 *style_value;
389 if (FcPatternGetString(
pattern, FC_FAMILY, 0, &
value) != FcResultMatch)
394 if (FcPatternGetString(
pattern, FC_FAMILYLANG, 0, &
value) == FcResultMatch)
397 slant_value = FC_SLANT_ROMAN;
398 weight_value = FC_WEIGHT_REGULAR;
399 spacing_value = FC_PROPORTIONAL;
400 file_value =
nullptr;
405 if (FcPatternGetInteger(
pattern, FC_SLANT, 0, &slant_value) != FcResultMatch)
406 slant_value = FC_SLANT_ROMAN;
407 if (FcPatternGetInteger(
pattern, FC_WEIGHT, 0, &weight_value) != FcResultMatch)
408 weight_value = FC_WEIGHT_REGULAR;
409 if (FcPatternGetInteger(
pattern, FC_WIDTH, 0, &width_value) != FcResultMatch)
410 width_value = FC_WIDTH_NORMAL;
411 if (FcPatternGetInteger(
pattern, FC_SPACING, 0, &spacing_value) != FcResultMatch)
412 spacing_value = FC_PROPORTIONAL;
413 if (FcPatternGetString(
pattern, FC_FILE, 0, &file_value) != FcResultMatch)
414 file_value =
nullptr;
415 if (FcPatternGetInteger(
pattern, FC_INDEX, 0, &indexValue) != FcResultMatch)
417 if (FcPatternGetBool(
pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
419 if (FcPatternGetString(
pattern, FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
420 foundry_value =
nullptr;
421 if (FcPatternGetString(
pattern, FC_STYLE, 0, &style_value) != FcResultMatch)
422 style_value =
nullptr;
423 if (FcPatternGetBool(
pattern,FC_ANTIALIAS,0,&antialias) != FcResultMatch)
427 FcLangSet *langset =
nullptr;
428 FcResult
res = FcPatternGetLangSet(
pattern, FC_LANG, 0, &langset);
429 if (
res == FcResultMatch) {
430 bool hasLang =
false;
431#if FC_VERSION >= 20297
432 FcChar8 *
cap =
nullptr;
433 FcResult capRes = FcResultNoMatch;
438 FcLangResult langRes = FcLangSetHasLang(langset, lang);
439 if (langRes != FcLangDifferentLang) {
440#if FC_VERSION >= 20297
443 capRes = FcPatternGetString(
pattern, FC_CAPABILITY, 0, &
cap);
444 if (capRes == FcResultMatch && strstr(
reinterpret_cast<const char *
>(
cap), capabilityForWritingSystem[
j]) ==
nullptr)
465 fontFile->indexValue = indexValue;
469 : ((slant_value == FC_SLANT_OBLIQUE)
475 double pixel_size = 0;
477 FcPatternGetDouble (
pattern, FC_PIXEL_SIZE, 0, &pixel_size);
479 bool fixedPitch = spacing_value >= FC_MONO;
484 if (applicationFont !=
nullptr) {
492 applicationFont->properties.append(
properties);
495 QPlatformFontDatabase::registerFont(familyName,styleName,
QLatin1StringView((
const char *)foundry_value),
weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
496 if (applicationFont !=
nullptr &&
face !=
nullptr &&
db !=
nullptr) {
497 db->addNamedInstancesForFace(
face,
507 applicationFont->data);
512 for (
int k = 1; FcPatternGetString(
pattern, FC_FAMILY, k, &
value) == FcResultMatch; ++k) {
518 if (FcPatternGetString(
pattern, FC_STYLE, k, &
value) == FcResultMatch)
521 altStyleName = styleName;
524 if (FcPatternGetString(
pattern, FC_FAMILYLANG, k, &
value) == FcResultMatch)
527 altFamilyNameLang = familyNameLang;
529 if (familyNameLang == altFamilyNameLang && altStyleName != styleName) {
530 if (applicationFont !=
nullptr) {
538 applicationFont->properties.append(
properties);
541 QPlatformFontDatabase::registerFont(altFamilyName, altStyleName,
QLatin1StringView((
const char *)foundry_value),
weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,altFontFile);
556 FcConfigDestroy(FcConfigGetCurrent());
565 FcObjectSet *os = FcObjectSetCreate();
568 FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
569 FC_SPACING, FC_FILE, FC_INDEX,
570 FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
571 FC_WIDTH, FC_FAMILYLANG,
572#if FC_VERSION >= 20297
575 (
const char *)
nullptr
579 FcObjectSetAdd(os, *
p);
585 FcPatternAddBool(
pattern, FC_VARIABLE, FcFalse);
588 fonts = FcFontList(
nullptr,
pattern, os);
589 FcObjectSetDestroy(os);
595 for (
int i = 0;
i < fonts->nfont;
i++)
598 FcFontSetDestroy (fonts);
600 struct FcDefaultFont {
606 {
"Serif",
"serif",
false },
607 {
"Sans Serif",
"sans-serif",
false },
608 {
"Monospace",
"monospace",
true },
609 {
nullptr,
nullptr,
false }
618 registerFont(familyQtName,
QString(),
QString(),
QFont::Normal,
QFont::StyleNormal,
QFont::Unstretched,
true,
true,0,
f->fixed,ws,
nullptr);
619 registerFont(familyQtName,
QString(),
QString(),
QFont::Normal,
QFont::StyleItalic,
QFont::Unstretched,
true,
true,0,
f->fixed,ws,
nullptr);
620 registerFont(familyQtName,
QString(),
QString(),
QFont::Normal,
QFont::StyleOblique,
QFont::Unstretched,
true,
true,0,
f->fixed,ws,
nullptr);
636 FcConfigAppFontClear(
nullptr);
647 switch (hintingPreference) {
661 void *hintStyleResource =
664 int xftHintStyle = int(
reinterpret_cast<qintptr>(hintStyleResource));
665 if (preferXftConf && xftHintStyle > 0)
669 if (FcPatternGetInteger (
match, FC_HINT_STYLE, 0, &hint_style) == FcResultMatch) {
670 switch (hint_style) {
684 if (xftHintStyle > 0)
692 void *subpixelTypeResource =
695 int xftSubpixelType = int(
reinterpret_cast<qintptr>(subpixelTypeResource));
696 if (preferXftConf && xftSubpixelType > 0)
699 int subpixel = FC_RGBA_UNKNOWN;
700 if (FcPatternGetInteger(
match, FC_RGBA, 0, &subpixel) == FcResultMatch) {
702 case FC_RGBA_UNKNOWN:
719 if (xftSubpixelType > 0)
734 fid.index = fontfile->indexValue;
735 fid.instanceIndex = fontfile->instanceIndex;
736 fid.variableAxes =
f.variableAxisValues;
768 return fallbackFamilies;
771 value.type = FcTypeString;
776 int slant_value = FC_SLANT_ROMAN;
778 slant_value = FC_SLANT_ITALIC;
780 slant_value = FC_SLANT_OBLIQUE;
781 FcPatternAddInteger(
pattern, FC_SLANT, slant_value);
785 FcLangSet *ls = FcLangSetCreate();
787 FcPatternAddLangSet(
pattern, FC_LANG, ls);
788 FcLangSetDestroy(ls);
789 }
else if (!family.
isEmpty()) {
796 FcDefaultSubstitute(dummy);
797 FcChar8 *lang =
nullptr;
798 FcResult
res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
799 if (
res == FcResultMatch)
800 FcPatternAddString(
pattern, FC_LANG, lang);
801 FcPatternDestroy(dummy);
806 value.u.s = (
const FcChar8 *)stylehint;
810 FcConfigSubstitute(
nullptr,
pattern, FcMatchPattern);
813 FcResult
result = FcResultMatch;
814 FcFontSet *fontSet = FcFontSort(
nullptr,
pattern,FcFalse,
nullptr,&
result);
818 QDuplicateTracker<QString> duplicates(fontSet->nfont + 1);
820 for (
int i = 0;
i < fontSet->nfont;
i++) {
821 FcChar8 *
value =
nullptr;
822 if (FcPatternGetString(fontSet->fonts[
i], FC_FAMILY, 0, &
value) != FcResultMatch)
827 if (!duplicates.hasSeen(familyNameCF)) {
828 fallbackFamilies << familyName;
831 FcFontSetDestroy(fontSet);
835 return fallbackFamilies;
840#if FC_VERSION < 20402
843 return FcFreeTypeQuery(
file,
id, blanks,
count);
845 if (
data.isEmpty()) {
847 return FcFreeTypeQuery(
file,
id, blanks,
count);
854 if (!FT_New_Memory_Face(lib, (
const FT_Byte *)
data.constData(),
data.size(),
id,
face)) {
855 *
count = (*face)->num_faces;
870 if (applicationFont !=
nullptr)
871 applicationFont->properties.clear();
873 FcFontSet *
set = FcConfigGetFonts(
nullptr, FcSetApplication);
875 FcConfigAppFontAddFile(
nullptr, (
const FcChar8 *)
":/non-existent");
876 set = FcConfigGetFonts(
nullptr, FcSetApplication);
882 FcBlanks *blanks = FcConfigGetBlanks(
nullptr);
893 FcChar8 *fam =
nullptr;
894 if (FcPatternGetString(
pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
906 }
while (
id <
count);
914 if (!resolved.
isEmpty() && resolved != family)
924 FcConfigSubstitute(
nullptr,
pattern, FcMatchPattern);
927 FcChar8 *familyAfterSubstitution =
nullptr;
928 FcPatternGetString(
pattern, FC_FAMILY, 0, &familyAfterSubstitution);
941 FcDefaultSubstitute(dummy);
942 FcChar8 *lang =
nullptr;
943 FcResult
res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
946 if (
res == FcResultMatch) {
949 FcPatternAddString(
pattern, FC_LANG, lang);
951 FcConfigSubstitute(
nullptr,
pattern, FcMatchPattern);
954 FcChar8 *familyAfterSubstitution =
nullptr;
955 FcPatternGetString(
pattern, FC_FAMILY, 0, &familyAfterSubstitution);
958 FcPatternDestroy(dummy);
960 return QFont(resolved);
966 bool forcedAntialiasSetting = !antialias ||
isDprScaling();
969 bool preferXftConf =
false;
972 const QList<QByteArray> desktopEnv =
services->desktopEnvironment().split(
':');
973 preferXftConf = !(desktopEnv.contains(
"KDE") || desktopEnv.contains(
"LXQT") || desktopEnv.contains(
"UKUI"));
982 value.type = FcTypeString;
989 if (!fid.filename.isEmpty()) {
990 value.u.s = (
const FcChar8 *)fid.filename.data();
993 value.type = FcTypeInteger;
994 value.u.i = fid.index;
1003 FcConfigSubstitute(
nullptr,
pattern, FcMatchPattern);
1007 if (!fid.filename.isEmpty()) {
1010 FcFontSet *fcsets[2], *fcfs;
1012 fcsets[0] = FcConfigGetFonts(
nullptr, FcSetSystem);
1013 fcsets[1] = FcConfigGetFonts(
nullptr, FcSetApplication);
1014 for (
int nset = 0; nset < 2; nset++) {
1015 fcfs = fcsets[nset];
1016 if (fcfs ==
nullptr)
1018 for (
int fnum = 0; fnum < fcfs->nfont; fnum++) {
1026 if (FcPatternGetBool(fcpat, FC_VARIABLE, 0, &
variable) == FcResultMatch &&
1031 if (FcPatternGetDouble(fcpat, FC_PIXEL_SIZE, 0, &fcpixelsize) == FcResultMatch &&
1036 if (FcPatternGetString(fcpat, FC_FILE, 0, &fcfile) == FcResultMatch &&
1037 FcPatternGetInteger(fcpat, FC_INDEX, 0, &fcindex) == FcResultMatch) {
1039 qstrlen((
const char *)fcfile));
1040 if (
f == fid.filename && fcindex == fid.index) {
1055 int xftAntialias = 0;
1056 if (!forcedAntialiasSetting) {
1057 void *antialiasResource =
1060 xftAntialias = int(
reinterpret_cast<qintptr>(antialiasResource));
1061 if ((preferXftConf || !
match) && xftAntialias > 0) {
1062 antialias = xftAntialias - 1;
1063 forcedAntialiasSetting =
true;
1070 if (FcPatternGetBool(
match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch)
1071 engine->forceAutoHint = fc_autohint;
1073#if defined(FT_LCD_FILTER_H)
1075 if (FcPatternGetInteger(
match, FC_LCD_FILTER, 0, &lcdFilter) == FcResultMatch)
1076 engine->lcdFilterType = lcdFilter;
1079 if (!forcedAntialiasSetting) {
1080 FcBool fc_antialias;
1081 if (FcPatternGetBool(
match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch)
1082 antialias = fc_antialias;
1088 subpixelType = subpixelTypeFromMatch(
match, preferXftConf);
1089 engine->subpixelType = subpixelType;
1092 FcPatternDestroy(
match);
1094 void *hintStyleResource =
1097 int xftHintStyle = int(
reinterpret_cast<qintptr>(hintStyleResource));
1098 if (xftHintStyle > 0)
1103 void *subpixelTypeResource =
1106 int xftSubpixelType = int(
reinterpret_cast<qintptr>(subpixelTypeResource));
1107 if (xftSubpixelType > 1)
1122 engine->antialias = antialias;
1129#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 20900
std::vector< ObjCStrongReference< CBMutableService > > services
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
WritingSystem
\value Any \value Latin \value Greek \value Cyrillic \value Armenian \value Hebrew \value Arabic \val...
StyleHint
Style hints are used by the \l{QFont}{font matching} algorithm to find an appropriate default family ...
Stretch
Predefined stretch values that follow the CSS naming convention.
Weight
Qt uses a weighting scale from 1 to 1000 compatible with OpenType.
Style
This enum describes the different styles of glyphs that are used to display text.
bool supportsVariableApplicationFonts() const override
Returns true if this font database supports loading named instances from variable application fonts.
QFontEngineMulti * fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) override
Returns a multi font engine in the specified script to encapsulate fontEngine with the option to fall...
void populateFontDatabase() override
This function is called once at startup by Qt's internal font database.
QString resolveFontFamilyAlias(const QString &family) const override
Resolve alias to actual font family names.
~QFontconfigDatabase() override
QFont defaultFont() const override
Returns the default system font.
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont=nullptr) override
Adds an application font described by the font contained supplied fontData or using the font containe...
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override
Returns a list of alternative fonts for the specified family and style and script using the styleHint...
void invalidate() override
This function is called whenever the font database is invalidated.
QFontEngine * fontEngine(const QFontDef &fontDef, void *handle) override
Returns the font engine that can be used to render the font described by the font definition,...
QFontEngine * fontEngine(const QFontDef &fontDef, void *handle) override
Returns the font engine that can be used to render the font described by the font definition,...
static QPlatformIntegration * platformIntegration()
static QPlatformNativeInterface * platformNativeInterface()
QScreen * primaryScreen
the primary (or default) screen of the application.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
QString toCaseFolded() const &
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray toUtf8() const &
The QSupportedWritingSystems class is used when registering fonts with the internal Qt fontdatabase.
void setSupported(QFontDatabase::WritingSystem, bool supported=true)
Sets or clears support for the specified writingSystem based on the value given by support.
Combined button and popup list for selecting options.
size_t qstrlen(const char *str)
static const QCssKnownValue properties[NumProperties - 1]
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
bool qFuzzyIsNull(qfloat16 f) noexcept
static int stretchFromFcWidth(int fcwidth)
static QT_BEGIN_NAMESPACE int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper, int qtLower, int qtUpper)
static FcPattern * queryFont(const FcChar8 *file, const QByteArray &data, int id, FcBlanks *blanks, int *count, FT_Face *face)
static int weightFromFcWeight(int fcweight)
static void populateFromPattern(FcPattern *pattern, QFontDatabasePrivate::ApplicationFont *applicationFont=nullptr, FT_Face face=nullptr, QFontconfigDatabase *db=nullptr)
static bool isDprScaling()
static bool requiresOpenType(int writingSystem)
static const char languageForWritingSystem[][6]
static const char specialLanguages[][6]
static const char * getFcFamilyForStyleHint(const QFont::StyleHint style)
FT_Library qt_getFreetype()
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint GLuint GLfloat weight
GLint GLsizei GLsizei GLenum format
GLenum GLsizeiptr const void * fontData
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
struct _FcPattern FcPattern
QFuture< QSet< QChar > > set
[10]
QFile defaults(defaultsPath)