Coverage Report

Created: 2026-04-01 07:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/text/qfontdatabase_p.h
Line
Count
Source
1
// Copyright (C) 2020 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#ifndef QFONTDATABASE_P_H
5
#define QFONTDATABASE_P_H
6
7
//
8
//  W A R N I N G
9
//  -------------
10
//
11
// This file is not part of the Qt API.  It exists for the convenience
12
// of internal files.  This header file may change from version to version
13
// without notice, or even be removed.
14
//
15
// We mean it.
16
//
17
18
#include <QtCore/qcache.h>
19
#include <QtCore/qloggingcategory.h>
20
21
#include <QtGui/qfontdatabase.h>
22
#include <QtCore/private/qglobal_p.h>
23
24
QT_BEGIN_NAMESPACE
25
26
Q_DECLARE_LOGGING_CATEGORY(lcFontDb)
27
Q_DECLARE_LOGGING_CATEGORY(lcFontMatch)
28
29
struct QtFontDesc;
30
31
struct QtFontFallbacksCacheKey
32
{
33
    QString family;
34
    QFont::Style style;
35
    QFont::StyleHint styleHint;
36
    int script;
37
};
38
39
inline bool operator==(const QtFontFallbacksCacheKey &lhs, const QtFontFallbacksCacheKey &rhs) noexcept
40
0
{
41
0
    return lhs.script == rhs.script &&
42
0
            lhs.styleHint == rhs.styleHint &&
43
0
            lhs.style == rhs.style &&
44
0
            lhs.family == rhs.family;
45
0
}
46
47
inline bool operator!=(const QtFontFallbacksCacheKey &lhs, const QtFontFallbacksCacheKey &rhs) noexcept
48
0
{
49
0
    return !operator==(lhs, rhs);
50
0
}
51
52
inline size_t qHash(const QtFontFallbacksCacheKey &key, size_t seed = 0) noexcept
53
0
{
54
0
    QtPrivate::QHashCombineWithSeed hash(seed);
55
0
    seed = hash(seed, key.family);
56
0
    seed = hash(seed, int(key.style));
57
0
    seed = hash(seed, int(key.styleHint));
58
0
    seed = hash(seed, int(key.script));
59
0
    return seed;
60
0
}
61
62
struct Q_GUI_EXPORT QtFontSize
63
{
64
    void *handle;
65
    unsigned short pixelSize : 16;
66
};
67
68
struct Q_GUI_EXPORT QtFontStyle
69
{
70
    struct Key
71
    {
72
        Key(const QString &styleString);
73
74
        Key()
75
0
            : style(QFont::StyleNormal)
76
0
            , weight(QFont::Normal)
77
0
            , stretch(0)
78
0
        {}
79
80
        Key(const Key &o)
81
0
            : style(o.style)
82
0
            , weight(o.weight)
83
0
            , stretch(o.stretch)
84
0
        {}
85
86
        uint style          : 2;
87
        uint weight         : 10;
88
        signed int stretch  : 12;
89
90
        bool operator==(const Key &other) const noexcept
91
0
        {
92
0
            return (style == other.style && weight == other.weight &&
93
0
                    (stretch == 0 || other.stretch == 0 || stretch == other.stretch));
94
0
        }
95
96
        bool operator!=(const Key &other) const noexcept
97
0
        {
98
0
            return !operator==(other);
99
0
        }
100
    };
101
102
    QtFontStyle(const Key &k)
103
0
        : key(k)
104
0
        , bitmapScalable(false)
105
0
        , smoothScalable(false)
106
0
        , count(0)
107
0
        , pixelSizes(nullptr)
108
0
    {
109
0
    }
110
111
    ~QtFontStyle();
112
113
    QtFontSize *pixelSize(unsigned short size, bool = false);
114
115
    Key key;
116
    bool bitmapScalable : 1;
117
    bool smoothScalable : 1;
118
    signed int count    : 30;
119
    QtFontSize *pixelSizes;
120
    QString styleName;
121
    bool antialiased;
122
};
123
124
struct Q_GUI_EXPORT QtFontFoundry
125
{
126
    QtFontFoundry(const QString &n)
127
0
        : name(n)
128
0
        , count(0)
129
0
        , styles(nullptr)
130
0
    {}
131
132
    ~QtFontFoundry()
133
0
    {
134
0
        while (count--)
135
0
            delete styles[count];
136
0
        free(styles);
137
0
    }
138
139
    QString name;
140
    int count;
141
    QtFontStyle **styles;
142
143
    enum StyleRetrievalFlags : quint8 {
144
        NoRetrievalFlags = 0,
145
        AddWhenMissing = 1,
146
        MatchAllProperties = 2,
147
        AllRetrievalFlags = 3,
148
    };
149
150
    QtFontStyle *style(const QtFontStyle::Key &,
151
                       const QString & = QString(),
152
                       StyleRetrievalFlags flags = NoRetrievalFlags);
153
};
154
155
struct Q_GUI_EXPORT QtFontFamily
156
{
157
    enum WritingSystemStatus {
158
        Unknown         = 0,
159
        Supported       = 1,
160
        UnsupportedFT  = 2,
161
        Unsupported     = UnsupportedFT
162
    };
163
164
    QtFontFamily(const QString &n)
165
        :
166
0
        populated(false),
167
0
        fixedPitch(false),
168
0
        colorFont(false),
169
0
        name(n), count(0), foundries(nullptr)
170
0
    {
171
0
        memset(writingSystems, 0, sizeof(writingSystems));
172
0
    }
173
0
    ~QtFontFamily() {
174
0
        while (count--)
175
0
            delete foundries[count];
176
0
        free(foundries);
177
0
    }
178
179
    bool populated : 1;
180
    bool fixedPitch : 1;
181
    bool colorFont : 1;
182
183
    QString name;
184
    QStringList aliases;
185
    int count;
186
    QtFontFoundry **foundries;
187
188
    unsigned char writingSystems[QFontDatabase::WritingSystemsCount];
189
190
    bool matchesFamilyName(const QString &familyName) const;
191
    QtFontFoundry *foundry(const QString &f, bool = false);
192
193
    bool ensurePopulated();
194
};
195
196
class Q_GUI_EXPORT QFontDatabasePrivate
197
{
198
public:
199
    QFontDatabasePrivate()
200
0
        : count(0)
201
0
        , families(nullptr)
202
0
        , fallbacksCache(64)
203
0
    { }
204
205
0
    ~QFontDatabasePrivate() {
206
0
        clearFamilies();
207
0
    }
208
209
    void clearFamilies();
210
211
    enum FamilyRequestFlags {
212
        RequestFamily = 0,
213
        EnsureCreated,
214
        EnsurePopulated
215
    };
216
217
    // Expands QChar::Script by adding a special "script" for emoji sequences
218
    enum ExtendedScript {
219
        Script_Common = QChar::Script_Common,
220
        Script_Latin = QChar::Script_Latin,
221
        Script_Emoji = QChar::ScriptCount,
222
        ScriptCount
223
    };
224
225
    QtFontFamily *family(const QString &f, FamilyRequestFlags flags = EnsurePopulated);
226
227
    int count;
228
    QtFontFamily **families;
229
    bool populated = false;
230
231
    QHash<ExtendedScript, QStringList> applicationFallbackFontFamiliesHash;
232
233
    QCache<QtFontFallbacksCacheKey, QStringList> fallbacksCache;
234
    struct ApplicationFont {
235
        QString fileName;
236
237
        // Note: The data may be implicitly shared throughout the
238
        // font database and platform font database, so be careful
239
        // to never detach when accessing this member!
240
        QByteArray data;
241
242
0
        bool isNull() const { return fileName.isEmpty(); }
243
0
        bool isPopulated() const { return !properties.isEmpty(); }
244
245
        struct Properties {
246
            QString familyName;
247
            QString styleName;
248
            int weight = 0;
249
            QFont::Style style = QFont::StyleNormal;
250
            int stretch = QFont::Unstretched;
251
        };
252
253
        QList<Properties> properties;
254
    };
255
    QList<ApplicationFont> applicationFonts;
256
    int addAppFont(const QByteArray &fontData, const QString &fileName);
257
    bool isApplicationFont(const QString &fileName);
258
259
    void setApplicationFallbackFontFamilies(ExtendedScript script, const QStringList &familyNames);
260
    QStringList applicationFallbackFontFamilies(ExtendedScript script);
261
    bool removeApplicationFallbackFontFamily(ExtendedScript script, const QString &familyName);
262
    void addApplicationFallbackFontFamily(ExtendedScript script, const QString &familyName);
263
264
    static QFontDatabasePrivate *instance();
265
266
    static void parseFontName(const QString &name, QString &foundry, QString &family);
267
    static QString resolveFontFamilyAlias(const QString &family);
268
    static QFontEngine *findFont(const QFontDef &request,
269
                                 int script /* QFontDatabasePrivate::ExtendedScript */,
270
                                 bool preferScriptOverFamily = false);
271
    static void load(const QFontPrivate *d, int script /* QFontDatabasePrivate::ExtendedScript */);
272
    static QFontDatabasePrivate *ensureFontDatabase();
273
274
    void invalidate();
275
276
private:
277
    static int match(int script,
278
                     const QFontDef &request,
279
                     const QString &family_name,
280
                     const QString &foundry_name,
281
                     QtFontDesc *desc,
282
                     const QList<int> &blacklistedFamilies,
283
                     unsigned int *resultingScore = nullptr);
284
285
    static unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
286
                            const QtFontFamily *family, const QString &foundry_name,
287
                            QtFontStyle::Key styleKey, int pixelSize, char pitch,
288
                            QtFontDesc *desc, const QString &styleName = QString());
289
290
    static QFontEngine *loadSingleEngine(int script, const QFontDef &request,
291
                            QtFontFamily *family, QtFontFoundry *foundry,
292
                            QtFontStyle *style, QtFontSize *size);
293
294
    static QFontEngine *loadEngine(int script, const QFontDef &request,
295
                            QtFontFamily *family, QtFontFoundry *foundry,
296
                            QtFontStyle *style, QtFontSize *size);
297
298
};
299
Q_DECLARE_TYPEINFO(QFontDatabasePrivate::ApplicationFont, Q_RELOCATABLE_TYPE);
300
301
QT_END_NAMESPACE
302
303
#endif // QFONTDATABASE_P_H