1// Copyright (C) 2016 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 QFONT_P_H
5#define QFONT_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 <QtGui/private/qtguiglobal_p.h>
19#include "QtGui/qfont.h"
20#include "QtCore/qmap.h"
21#include "QtCore/qhash.h"
22#include "QtCore/qobject.h"
23#include "QtCore/qstringlist.h"
24#include <QtGui/qfontdatabase.h>
25#include "private/qfixed_p.h"
26
27QT_BEGIN_NAMESPACE
28
29// forwards
30class QFontCache;
31class QFontEngine;
32
33#define QFONT_WEIGHT_MIN 1
34#define QFONT_WEIGHT_MAX 1000
35
36struct QFontDef
37{
38 inline QFontDef()
39 : pointSize(-1.0),
40 pixelSize(-1),
41 styleStrategy(QFont::PreferDefault),
42 stretch(QFont::AnyStretch),
43 style(QFont::StyleNormal),
44 hintingPreference(QFont::PreferDefaultHinting),
45 styleHint(QFont::AnyStyle),
46 weight(QFont::Normal),
47 fixedPitch(false),
48 ignorePitch(true),
49 fixedPitchComputed(0),
50 reserved(0)
51 {
52 }
53
54 QStringList families;
55 QString styleName;
56
57 QStringList fallBackFamilies;
58 QMap<QFont::Tag, float> variableAxisValues;
59
60 qreal pointSize;
61 qreal pixelSize;
62
63 // Note: Variable ordering matters to make sure no variable overlaps two 32-bit registers.
64 uint styleStrategy : 16;
65 uint stretch : 12; // 0-4000
66 uint style : 2;
67 uint hintingPreference : 2;
68
69 uint styleHint : 8;
70 uint weight : 10; // 1-1000
71 uint fixedPitch : 1;
72 uint ignorePitch : 1;
73 uint fixedPitchComputed : 1; // for Mac OS X only
74 uint reserved : 11; // for future extensions
75
76 bool exactMatch(const QFontDef &other) const;
77 bool operator==(const QFontDef &other) const
78 {
79 return pixelSize == other.pixelSize
80 && weight == other.weight
81 && style == other.style
82 && stretch == other.stretch
83 && styleHint == other.styleHint
84 && styleStrategy == other.styleStrategy
85 && ignorePitch == other.ignorePitch && fixedPitch == other.fixedPitch
86 && families == other.families
87 && styleName == other.styleName
88 && hintingPreference == other.hintingPreference
89 && variableAxisValues == other.variableAxisValues
90 ;
91 }
92 inline bool operator<(const QFontDef &other) const
93 {
94 if (pixelSize != other.pixelSize) return pixelSize < other.pixelSize;
95 if (weight != other.weight) return weight < other.weight;
96 if (style != other.style) return style < other.style;
97 if (stretch != other.stretch) return stretch < other.stretch;
98 if (styleHint != other.styleHint) return styleHint < other.styleHint;
99 if (styleStrategy != other.styleStrategy) return styleStrategy < other.styleStrategy;
100 if (families != other.families) return families < other.families;
101 if (styleName != other.styleName)
102 return styleName < other.styleName;
103 if (hintingPreference != other.hintingPreference) return hintingPreference < other.hintingPreference;
104
105
106 if (ignorePitch != other.ignorePitch) return ignorePitch < other.ignorePitch;
107 if (fixedPitch != other.fixedPitch) return fixedPitch < other.fixedPitch;
108 if (variableAxisValues != other.variableAxisValues) {
109 if (variableAxisValues.size() != other.variableAxisValues.size())
110 return variableAxisValues.size() < other.variableAxisValues.size();
111
112 {
113 auto it = variableAxisValues.constBegin();
114 auto jt = other.variableAxisValues.constBegin();
115 for (; it != variableAxisValues.constEnd(); ++it, ++jt) {
116 if (it.key() != jt.key())
117 return jt.key() < it.key();
118 if (it.value() != jt.value())
119 return jt.value() < it.value();
120 }
121 }
122 }
123
124 return false;
125 }
126};
127
128inline size_t qHash(const QFontDef &fd, size_t seed = 0) noexcept
129{
130 return qHashMulti(seed,
131 args: qRound64(d: fd.pixelSize*10000), // use only 4 fractional digits
132 args: fd.weight,
133 args: fd.style,
134 args: fd.stretch,
135 args: fd.styleHint,
136 args: fd.styleStrategy,
137 args: fd.ignorePitch,
138 args: fd.fixedPitch,
139 args: fd.families,
140 args: fd.styleName,
141 args: fd.hintingPreference,
142 args: fd.variableAxisValues.keys(),
143 args: fd.variableAxisValues.values());
144}
145
146class QFontEngineData
147{
148public:
149 QFontEngineData();
150 ~QFontEngineData();
151
152 QAtomicInt ref;
153 const int fontCacheId;
154
155 QFontEngine *engines[QChar::ScriptCount];
156
157private:
158 Q_DISABLE_COPY_MOVE(QFontEngineData)
159};
160
161
162class Q_GUI_EXPORT QFontPrivate
163{
164public:
165
166 QFontPrivate();
167 QFontPrivate(const QFontPrivate &other);
168 ~QFontPrivate();
169
170 QFontEngine *engineForScript(int script) const;
171 void alterCharForCapitalization(QChar &c) const;
172
173 QAtomicInt ref;
174 QFontDef request;
175 mutable QFontEngineData *engineData;
176 int dpi;
177
178 uint underline : 1;
179 uint overline : 1;
180 uint strikeOut : 1;
181 uint kerning : 1;
182 uint capital : 3;
183 bool letterSpacingIsAbsolute : 1;
184
185 QFixed letterSpacing;
186 QFixed wordSpacing;
187 QHash<QFont::Tag, quint32> features;
188
189 mutable QFontPrivate *scFont;
190 QFont smallCapsFont() const { return QFont(smallCapsFontPrivate()); }
191 QFontPrivate *smallCapsFontPrivate() const;
192
193 static QFontPrivate *get(const QFont &font)
194 {
195 return font.d.data();
196 }
197
198 void resolve(uint mask, const QFontPrivate *other);
199
200 static void detachButKeepEngineData(QFont *font);
201
202 void setFeature(QFont::Tag tag, quint32 value);
203 void unsetFeature(QFont::Tag tag);
204
205 void setVariableAxis(QFont::Tag tag, float value);
206 void unsetVariableAxis(QFont::Tag tag);
207 bool hasVariableAxis(QFont::Tag tag, float value) const;
208
209private:
210 QFontPrivate &operator=(const QFontPrivate &) { return *this; }
211};
212
213
214class Q_GUI_EXPORT QFontCache : public QObject
215{
216public:
217 // note: these static functions work on a per-thread basis
218 static QFontCache *instance();
219 static void cleanup();
220
221 QFontCache();
222 ~QFontCache();
223
224 int id() const { return m_id; }
225
226 void clear();
227
228 struct Key {
229 Key() : script(0), multi(0) { }
230 Key(const QFontDef &d, uchar c, bool m = 0)
231 : def(d), script(c), multi(m) { }
232
233 QFontDef def;
234 uchar script;
235 uchar multi: 1;
236
237 inline bool operator<(const Key &other) const
238 {
239 if (script != other.script) return script < other.script;
240 if (multi != other.multi) return multi < other.multi;
241 if (multi && def.fallBackFamilies.size() != other.def.fallBackFamilies.size())
242 return def.fallBackFamilies.size() < other.def.fallBackFamilies.size();
243 return def < other.def;
244 }
245 inline bool operator==(const Key &other) const
246 {
247 return script == other.script
248 && multi == other.multi
249 && (!multi || def.fallBackFamilies == other.def.fallBackFamilies)
250 && def == other.def;
251 }
252 };
253
254 // QFontEngineData cache
255 typedef QMap<QFontDef, QFontEngineData*> EngineDataCache;
256 EngineDataCache engineDataCache;
257
258 QFontEngineData *findEngineData(const QFontDef &def) const;
259 void insertEngineData(const QFontDef &def, QFontEngineData *engineData);
260
261 // QFontEngine cache
262 struct Engine {
263 Engine() : data(nullptr), timestamp(0), hits(0) { }
264 Engine(QFontEngine *d) : data(d), timestamp(0), hits(0) { }
265
266 QFontEngine *data;
267 uint timestamp;
268 uint hits;
269 };
270
271 typedef QMultiMap<Key,Engine> EngineCache;
272 EngineCache engineCache;
273 QHash<QFontEngine *, int> engineCacheCount;
274
275 QFontEngine *findEngine(const Key &key);
276
277 void updateHitCountAndTimeStamp(Engine &value);
278 void insertEngine(const Key &key, QFontEngine *engine, bool insertMulti = false);
279
280private:
281 void increaseCost(uint cost);
282 void decreaseCost(uint cost);
283 void timerEvent(QTimerEvent *event) override;
284 void decreaseCache();
285
286 static const uint min_cost;
287 uint total_cost, max_cost;
288 uint current_timestamp;
289 bool fast;
290 const bool autoClean;
291 int timer_id;
292 const int m_id;
293};
294
295Q_GUI_EXPORT int qt_defaultDpiX();
296Q_GUI_EXPORT int qt_defaultDpiY();
297Q_GUI_EXPORT int qt_defaultDpi();
298
299Q_GUI_EXPORT int qt_legacyToOpenTypeWeight(int weight);
300Q_GUI_EXPORT int qt_openTypeToLegacyWeight(int weight);
301
302QT_END_NAMESPACE
303
304#endif // QFONT_P_H
305

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/gui/text/qfont_p.h