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>
19#include <QtGui/private/qhighdpiscaling_p.h>
21#include <QtGui/qguiapplication.h>
23#include <QtCore/private/qduplicatetracker_p.h>
25#include <fontconfig/fontconfig.h>
26#if FC_VERSION >= 20402
27#include <fontconfig/fcfreetype.h>
34 return qtLower + ((fcweight - fcLower) * (qtUpper - qtLower)) / (fcUpper - fcLower);
46 if (fcweight <= FC_WEIGHT_THIN)
48 if (fcweight <= FC_WEIGHT_ULTRALIGHT)
50 if (fcweight <= FC_WEIGHT_LIGHT)
52 if (fcweight <= FC_WEIGHT_NORMAL)
54 if (fcweight <= FC_WEIGHT_MEDIUM)
56 if (fcweight <= FC_WEIGHT_DEMIBOLD)
58 if (fcweight <= FC_WEIGHT_BOLD)
60 if (fcweight <= FC_WEIGHT_ULTRABOLD)
62 if (fcweight <= FC_WEIGHT_BLACK)
64 if (fcweight <= FC_WEIGHT_ULTRABLACK)
74 const int maxStretch = 4000;
78 else if (fcwidth > maxStretch)
79 qtstretch = maxStretch;
294#if FC_VERSION >= 20297
298static const char capabilityForWritingSystem[][5] = {
339 const char *stylehint =
nullptr;
342 stylehint =
"sans-serif";
349 stylehint =
"monospace";
352 stylehint =
"cursive";
355 stylehint =
"fantasy";
373 FcChar8 *
value =
nullptr;
380 FcChar8 *foundry_value;
381 FcChar8 *style_value;
385 if (FcPatternGetString(
pattern, FC_FAMILY, 0, &
value) != FcResultMatch)
390 if (FcPatternGetString(
pattern, FC_FAMILYLANG, 0, &
value) == FcResultMatch)
393 slant_value = FC_SLANT_ROMAN;
394 weight_value = FC_WEIGHT_REGULAR;
395 spacing_value = FC_PROPORTIONAL;
396 file_value =
nullptr;
401 if (FcPatternGetInteger(
pattern, FC_SLANT, 0, &slant_value) != FcResultMatch)
402 slant_value = FC_SLANT_ROMAN;
403 if (FcPatternGetInteger(
pattern, FC_WEIGHT, 0, &weight_value) != FcResultMatch)
404 weight_value = FC_WEIGHT_REGULAR;
405 if (FcPatternGetInteger(
pattern, FC_WIDTH, 0, &width_value) != FcResultMatch)
406 width_value = FC_WIDTH_NORMAL;
407 if (FcPatternGetInteger(
pattern, FC_SPACING, 0, &spacing_value) != FcResultMatch)
408 spacing_value = FC_PROPORTIONAL;
409 if (FcPatternGetString(
pattern, FC_FILE, 0, &file_value) != FcResultMatch)
410 file_value =
nullptr;
411 if (FcPatternGetInteger(
pattern, FC_INDEX, 0, &indexValue) != FcResultMatch)
413 if (FcPatternGetBool(
pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
415 if (FcPatternGetString(
pattern, FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
416 foundry_value =
nullptr;
417 if (FcPatternGetString(
pattern, FC_STYLE, 0, &style_value) != FcResultMatch)
418 style_value =
nullptr;
419 if (FcPatternGetBool(
pattern,FC_ANTIALIAS,0,&antialias) != FcResultMatch)
423 FcLangSet *langset =
nullptr;
424 FcResult
res = FcPatternGetLangSet(
pattern, FC_LANG, 0, &langset);
425 if (
res == FcResultMatch) {
426 bool hasLang =
false;
427#if FC_VERSION >= 20297
428 FcChar8 *
cap =
nullptr;
429 FcResult capRes = FcResultNoMatch;
434 FcLangResult langRes = FcLangSetHasLang(langset, lang);
435 if (langRes != FcLangDifferentLang) {
436#if FC_VERSION >= 20297
439 capRes = FcPatternGetString(
pattern, FC_CAPABILITY, 0, &
cap);
440 if (capRes == FcResultMatch && strstr(
reinterpret_cast<const char *
>(
cap), capabilityForWritingSystem[
j]) ==
nullptr)
465 : ((slant_value == FC_SLANT_OBLIQUE)
471 double pixel_size = 0;
473 FcPatternGetDouble (
pattern, FC_PIXEL_SIZE, 0, &pixel_size);
475 bool fixedPitch = spacing_value >= FC_MONO;
480 if (applicationFont !=
nullptr) {
488 applicationFont->properties.append(
properties);
491 QPlatformFontDatabase::registerFont(familyName,styleName,
QLatin1StringView((
const char *)foundry_value),
weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
494 for (
int k = 1; FcPatternGetString(
pattern, FC_FAMILY, k, &
value) == FcResultMatch; ++k) {
500 if (FcPatternGetString(
pattern, FC_STYLE, k, &
value) == FcResultMatch)
503 altStyleName = styleName;
506 if (FcPatternGetString(
pattern, FC_FAMILYLANG, k, &
value) == FcResultMatch)
509 altFamilyNameLang = familyNameLang;
511 if (familyNameLang == altFamilyNameLang && altStyleName != styleName) {
512 if (applicationFont !=
nullptr) {
520 applicationFont->properties.append(
properties);
523 QPlatformFontDatabase::registerFont(altFamilyName, altStyleName,
QLatin1StringView((
const char *)foundry_value),
weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,altFontFile);
533 FcConfigDestroy(FcConfigGetCurrent());
542 FcObjectSet *os = FcObjectSetCreate();
545 FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
546 FC_SPACING, FC_FILE, FC_INDEX,
547 FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
548 FC_WIDTH, FC_FAMILYLANG,
549#if FC_VERSION >= 20297
552 (
const char *)
nullptr
556 FcObjectSetAdd(os, *
p);
559 fonts = FcFontList(
nullptr,
pattern, os);
560 FcObjectSetDestroy(os);
566 for (
int i = 0;
i < fonts->nfont;
i++)
569 FcFontSetDestroy (fonts);
571 struct FcDefaultFont {
577 {
"Serif",
"serif",
false },
578 {
"Sans Serif",
"sans-serif",
false },
579 {
"Monospace",
"monospace",
true },
580 {
nullptr,
nullptr,
false }
589 registerFont(familyQtName,
QString(),
QString(),
QFont::Normal,
QFont::StyleNormal,
QFont::Unstretched,
true,
true,0,
f->fixed,ws,
nullptr);
590 registerFont(familyQtName,
QString(),
QString(),
QFont::Normal,
QFont::StyleItalic,
QFont::Unstretched,
true,
true,0,
f->fixed,ws,
nullptr);
591 registerFont(familyQtName,
QString(),
QString(),
QFont::Normal,
QFont::StyleOblique,
QFont::Unstretched,
true,
true,0,
f->fixed,ws,
nullptr);
607 FcConfigAppFontClear(
nullptr);
618 switch (hintingPreference) {
633 if (FcPatternGetInteger (
match, FC_HINT_STYLE, 0, &hint_style) == FcResultMatch) {
634 switch (hint_style) {
650 void *hintStyleResource =
653 int hintStyle = int(
reinterpret_cast<qintptr>(hintStyleResource));
663 int subpixel = FC_RGBA_UNKNOWN;
664 if (FcPatternGetInteger(
match, FC_RGBA, 0, &subpixel) == FcResultMatch) {
666 case FC_RGBA_UNKNOWN:
684 void *subpixelTypeResource =
687 int subpixelType = int(
reinterpret_cast<qintptr>(subpixelTypeResource));
688 if (subpixelType > 0)
736 return fallbackFamilies;
739 value.type = FcTypeString;
744 int slant_value = FC_SLANT_ROMAN;
746 slant_value = FC_SLANT_ITALIC;
748 slant_value = FC_SLANT_OBLIQUE;
749 FcPatternAddInteger(
pattern, FC_SLANT, slant_value);
753 FcLangSet *ls = FcLangSetCreate();
755 FcPatternAddLangSet(
pattern, FC_LANG, ls);
756 FcLangSetDestroy(ls);
757 }
else if (!family.
isEmpty()) {
764 FcDefaultSubstitute(dummy);
765 FcChar8 *lang =
nullptr;
766 FcResult
res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
767 if (
res == FcResultMatch)
768 FcPatternAddString(
pattern, FC_LANG, lang);
769 FcPatternDestroy(dummy);
774 value.u.s = (
const FcChar8 *)stylehint;
778 FcConfigSubstitute(
nullptr,
pattern, FcMatchPattern);
781 FcResult
result = FcResultMatch;
782 FcFontSet *fontSet = FcFontSort(
nullptr,
pattern,FcFalse,
nullptr,&
result);
788 for (
int i = 0;
i < fontSet->nfont;
i++) {
789 FcChar8 *
value =
nullptr;
790 if (FcPatternGetString(fontSet->fonts[
i], FC_FAMILY, 0, &
value) != FcResultMatch)
795 if (!duplicates.
hasSeen(familyNameCF)) {
796 fallbackFamilies << familyName;
799 FcFontSetDestroy(fontSet);
803 return fallbackFamilies;
808#if FC_VERSION < 20402
810 return FcFreeTypeQuery(
file,
id, blanks,
count);
813 return FcFreeTypeQuery(
file,
id, blanks,
count);
820 if (!FT_New_Memory_Face(lib, (
const FT_Byte *)
data.constData(),
data.size(),
id, &
face)) {
836 if (applicationFont !=
nullptr)
839 FcFontSet *
set = FcConfigGetFonts(
nullptr, FcSetApplication);
841 FcConfigAppFontAddFile(
nullptr, (
const FcChar8 *)
":/non-existent");
842 set = FcConfigGetFonts(
nullptr, FcSetApplication);
848 FcBlanks *blanks = FcConfigGetBlanks(
nullptr);
858 FcChar8 *fam =
nullptr;
859 if (FcPatternGetString(
pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
868 }
while (
id <
count);
876 if (!resolved.
isEmpty() && resolved != family)
886 FcConfigSubstitute(
nullptr,
pattern, FcMatchPattern);
889 FcChar8 *familyAfterSubstitution =
nullptr;
890 FcPatternGetString(
pattern, FC_FAMILY, 0, &familyAfterSubstitution);
903 FcDefaultSubstitute(dummy);
904 FcChar8 *lang =
nullptr;
905 FcResult
res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
908 if (
res == FcResultMatch) {
911 FcPatternAddString(
pattern, FC_LANG, lang);
913 FcConfigSubstitute(
nullptr,
pattern, FcMatchPattern);
916 FcChar8 *familyAfterSubstitution =
nullptr;
917 FcPatternGetString(
pattern, FC_FAMILY, 0, &familyAfterSubstitution);
920 FcPatternDestroy(dummy);
922 return QFont(resolved);
931 bool useXftConf =
false;
938 if (useXftConf && !forcedAntialiasSetting) {
939 void *antialiasResource =
942 int antialiasingEnabled = int(
reinterpret_cast<qintptr>(antialiasResource));
943 if (antialiasingEnabled > 0)
944 antialias = antialiasingEnabled - 1;
952 value.type = FcTypeString;
963 value.type = FcTypeInteger;
973 FcConfigSubstitute(
nullptr,
pattern, FcMatchPattern);
981 if (FcPatternGetBool(
match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch)
982 engine->forceAutoHint = fc_autohint;
984#if defined(FT_LCD_FILTER_H)
986 if (FcPatternGetInteger(
match, FC_LCD_FILTER, 0, &lcdFilter) == FcResultMatch)
987 engine->lcdFilterType = lcdFilter;
990 if (!forcedAntialiasSetting) {
992 if (FcPatternGetBool(
match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch)
993 antialias = fc_antialias;
999 subpixelType = subpixelTypeFromMatch(
match, useXftConf);
1000 engine->subpixelType = subpixelType;
1008 FcPatternDestroy(
match);
1014 engine->antialias = antialias;
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.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
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.
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...
QString toCaseFolded() const &
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
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.
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
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static int stretchFromFcWidth(int fcwidth)
static QT_BEGIN_NAMESPACE int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper, int qtLower, int qtUpper)
static int weightFromFcWeight(int fcweight)
static FcPattern * queryFont(const FcChar8 *file, const QByteArray &data, int id, FcBlanks *blanks, int *count)
static bool requiresOpenType(int writingSystem)
static const char languageForWritingSystem[][6]
static const char specialLanguages[][6]
static void populateFromPattern(FcPattern *pattern, QFontDatabasePrivate::ApplicationFont *applicationFont=nullptr)
static const char * getFcFamilyForStyleHint(const QFont::StyleHint style)
FT_Library qt_getFreetype()
GLenum GLenum GLsizei count
GLuint GLuint GLfloat weight
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
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)
QList< Properties > properties
bool contains(const AT &t) const noexcept