Coverage Report

Created: 2025-07-12 07:23

/src/qtbase/src/gui/text/qfont_p.h
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
**
3
** Copyright (C) 2016 The Qt Company Ltd.
4
** Contact: https://www.qt.io/licensing/
5
**
6
** This file is part of the QtGui module of the Qt Toolkit.
7
**
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and The Qt Company. For licensing terms
14
** and conditions see https://www.qt.io/terms-conditions. For further
15
** information use the contact form at https://www.qt.io/contact-us.
16
**
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 3 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL3 included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 3 requirements
23
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24
**
25
** GNU General Public License Usage
26
** Alternatively, this file may be used under the terms of the GNU
27
** General Public License version 2.0 or (at your option) the GNU General
28
** Public license version 3 or any later version approved by the KDE Free
29
** Qt Foundation. The licenses are as published by the Free Software
30
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31
** included in the packaging of this file. Please review the following
32
** information to ensure the GNU General Public License requirements will
33
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34
** https://www.gnu.org/licenses/gpl-3.0.html.
35
**
36
** $QT_END_LICENSE$
37
**
38
****************************************************************************/
39
40
#ifndef QFONT_P_H
41
#define QFONT_P_H
42
43
//
44
//  W A R N I N G
45
//  -------------
46
//
47
// This file is not part of the Qt API.  It exists for the convenience
48
// of internal files.  This header file may change from version to version
49
// without notice, or even be removed.
50
//
51
// We mean it.
52
//
53
54
#include <QtGui/private/qtguiglobal_p.h>
55
#include "QtGui/qfont.h"
56
#include "QtCore/qmap.h"
57
#include "QtCore/qhash.h"
58
#include "QtCore/qobject.h"
59
#include "QtCore/qstringlist.h"
60
#include <QtGui/qfontdatabase.h>
61
#include "private/qfixed_p.h"
62
63
QT_BEGIN_NAMESPACE
64
65
// forwards
66
class QFontCache;
67
class QFontEngine;
68
69
struct QFontDef
70
{
71
    inline QFontDef()
72
7.97k
        : pointSize(-1.0), pixelSize(-1),
73
7.97k
          styleStrategy(QFont::PreferDefault), styleHint(QFont::AnyStyle),
74
7.97k
          weight(50), fixedPitch(false), style(QFont::StyleNormal), stretch(QFont::AnyStretch),
75
7.97k
          hintingPreference(QFont::PreferDefaultHinting), ignorePitch(true),
76
7.97k
          fixedPitchComputed(0), reserved(0)
77
7.97k
    {
78
7.97k
    }
79
80
    QString family;
81
    QStringList families;
82
    QString styleName;
83
84
    QStringList fallBackFamilies;
85
86
    qreal pointSize;
87
    qreal pixelSize;
88
89
    uint styleStrategy : 16;
90
    uint styleHint     : 8;
91
92
    uint weight     :  7; // 0-99
93
    uint fixedPitch :  1;
94
    uint style      :  2;
95
    uint stretch    : 12; // 0-4000
96
97
    uint hintingPreference : 2;
98
    uint ignorePitch : 1;
99
    uint fixedPitchComputed : 1; // for Mac OS X only
100
    uint reserved   : 14; // for future extensions
101
102
    bool exactMatch(const QFontDef &other) const;
103
    bool operator==(const QFontDef &other) const
104
0
    {
105
0
        return pixelSize == other.pixelSize
106
0
                    && weight == other.weight
107
0
                    && style == other.style
108
0
                    && stretch == other.stretch
109
0
                    && styleHint == other.styleHint
110
0
                    && styleStrategy == other.styleStrategy
111
0
                    && ignorePitch == other.ignorePitch && fixedPitch == other.fixedPitch
112
0
                    && family == other.family
113
0
                    && families == other.families
114
0
                    && styleName == other.styleName
115
0
                    && hintingPreference == other.hintingPreference
116
0
                          ;
117
0
    }
118
    inline bool operator<(const QFontDef &other) const
119
0
    {
120
0
        if (pixelSize != other.pixelSize) return pixelSize < other.pixelSize;
121
0
        if (weight != other.weight) return weight < other.weight;
122
0
        if (style != other.style) return style < other.style;
123
0
        if (stretch != other.stretch) return stretch < other.stretch;
124
0
        if (styleHint != other.styleHint) return styleHint < other.styleHint;
125
0
        if (styleStrategy != other.styleStrategy) return styleStrategy < other.styleStrategy;
126
0
        if (family != other.family) return family < other.family;
127
0
        if (families != other.families) return families < other.families;
128
0
        if (styleName != other.styleName)
129
0
            return styleName < other.styleName;
130
0
        if (hintingPreference != other.hintingPreference) return hintingPreference < other.hintingPreference;
131
132
133
0
        if (ignorePitch != other.ignorePitch) return ignorePitch < other.ignorePitch;
134
0
        if (fixedPitch != other.fixedPitch) return fixedPitch < other.fixedPitch;
135
0
        return false;
136
0
    }
137
};
138
139
inline uint qHash(const QFontDef &fd, uint seed = 0) noexcept
140
0
{
141
0
    QtPrivate::QHashCombine hash;
142
0
    seed = hash(seed, qRound64(fd.pixelSize*10000)); // use only 4 fractional digits
143
0
    seed = hash(seed, fd.weight);
144
0
    seed = hash(seed, fd.style);
145
0
    seed = hash(seed, fd.stretch);
146
0
    seed = hash(seed, fd.styleHint);
147
0
    seed = hash(seed, fd.styleStrategy);
148
0
    seed = hash(seed, fd.ignorePitch);
149
0
    seed = hash(seed, fd.fixedPitch);
150
0
    seed = hash(seed, fd.family);
151
0
    seed = hash(seed, fd.families);
152
0
    seed = hash(seed, fd.styleName);
153
0
    seed = hash(seed, fd.hintingPreference);
154
0
    return seed;
155
0
}
156
157
class QFontEngineData
158
{
159
public:
160
    QFontEngineData();
161
    ~QFontEngineData();
162
163
    QAtomicInt ref;
164
    const int fontCacheId;
165
166
    QFontEngine *engines[QChar::ScriptCount];
167
168
private:
169
    Q_DISABLE_COPY_MOVE(QFontEngineData)
170
};
171
172
173
class Q_GUI_EXPORT QFontPrivate
174
{
175
public:
176
177
    QFontPrivate();
178
    QFontPrivate(const QFontPrivate &other);
179
    ~QFontPrivate();
180
181
    QFontEngine *engineForScript(int script) const;
182
    void alterCharForCapitalization(QChar &c) const;
183
184
    QAtomicInt ref;
185
    QFontDef request;
186
    mutable QFontEngineData *engineData;
187
    int dpi;
188
189
    uint underline  :  1;
190
    uint overline   :  1;
191
    uint strikeOut  :  1;
192
    uint kerning    :  1;
193
    uint capital    :  3;
194
    bool letterSpacingIsAbsolute : 1;
195
196
    QFixed letterSpacing;
197
    QFixed wordSpacing;
198
199
    mutable QFontPrivate *scFont;
200
0
    QFont smallCapsFont() const { return QFont(smallCapsFontPrivate()); }
201
    QFontPrivate *smallCapsFontPrivate() const;
202
203
    static QFontPrivate *get(const QFont &font)
204
0
    {
205
0
        return font.d.data();
206
0
    }
207
208
    void resolve(uint mask, const QFontPrivate *other);
209
210
    static void detachButKeepEngineData(QFont *font);
211
212
private:
213
0
    QFontPrivate &operator=(const QFontPrivate &) { return *this; }
214
};
215
216
217
class Q_GUI_EXPORT QFontCache : public QObject
218
{
219
public:
220
    // note: these static functions work on a per-thread basis
221
    static QFontCache *instance();
222
    static void cleanup();
223
224
    QFontCache();
225
    ~QFontCache();
226
227
0
    int id() const { return m_id; }
228
229
    void clear();
230
231
    struct Key {
232
0
        Key() : script(0), multi(0) { }
233
        Key(const QFontDef &d, uchar c, bool m = 0)
234
0
            : def(d), script(c), multi(m) { }
235
236
        QFontDef def;
237
        uchar script;
238
        uchar multi: 1;
239
240
        inline bool operator<(const Key &other) const
241
0
        {
242
0
            if (script != other.script) return script < other.script;
243
0
            if (multi != other.multi) return multi < other.multi;
244
0
            if (multi && def.fallBackFamilies.size() != other.def.fallBackFamilies.size())
245
0
                return def.fallBackFamilies.size() < other.def.fallBackFamilies.size();
246
0
            return def < other.def;
247
0
        }
248
        inline bool operator==(const Key &other) const
249
0
        {
250
0
            return script == other.script
251
0
                    && multi == other.multi
252
0
                    && (!multi || def.fallBackFamilies == other.def.fallBackFamilies)
253
0
                    && def == other.def;
254
0
        }
255
    };
256
257
    // QFontEngineData cache
258
    typedef QMap<QFontDef, QFontEngineData*> EngineDataCache;
259
    EngineDataCache engineDataCache;
260
261
    QFontEngineData *findEngineData(const QFontDef &def) const;
262
    void insertEngineData(const QFontDef &def, QFontEngineData *engineData);
263
264
    // QFontEngine cache
265
    struct Engine {
266
0
        Engine() : data(nullptr), timestamp(0), hits(0) { }
267
0
        Engine(QFontEngine *d) : data(d), timestamp(0), hits(0) { }
268
269
        QFontEngine *data;
270
        uint timestamp;
271
        uint hits;
272
    };
273
274
    typedef QMultiMap<Key,Engine> EngineCache;
275
    EngineCache engineCache;
276
    QHash<QFontEngine *, int> engineCacheCount;
277
278
    QFontEngine *findEngine(const Key &key);
279
280
    void updateHitCountAndTimeStamp(Engine &value);
281
    void insertEngine(const Key &key, QFontEngine *engine, bool insertMulti = false);
282
283
private:
284
    void increaseCost(uint cost);
285
    void decreaseCost(uint cost);
286
    void timerEvent(QTimerEvent *event) override;
287
    void decreaseCache();
288
289
    static const uint min_cost;
290
    uint total_cost, max_cost;
291
    uint current_timestamp;
292
    bool fast;
293
    int timer_id;
294
    const int m_id;
295
};
296
297
Q_GUI_EXPORT int qt_defaultDpiX();
298
Q_GUI_EXPORT int qt_defaultDpiY();
299
Q_GUI_EXPORT int qt_defaultDpi();
300
301
QT_END_NAMESPACE
302
303
#endif // QFONT_P_H