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
20#include <QtGui/qfontdatabase.h>
21#include <QtCore/private/qglobal_p.h>
22
23QT_BEGIN_NAMESPACE
24
25struct QtFontDesc;
26
27struct QtFontFallbacksCacheKey
28{
29 QString family;
30 QFont::Style style;
31 QFont::StyleHint styleHint;
32 QChar::Script script;
33};
34
35inline bool operator==(const QtFontFallbacksCacheKey &lhs, const QtFontFallbacksCacheKey &rhs) noexcept
36{
37 return lhs.script == rhs.script &&
38 lhs.styleHint == rhs.styleHint &&
39 lhs.style == rhs.style &&
40 lhs.family == rhs.family;
41}
42
43inline bool operator!=(const QtFontFallbacksCacheKey &lhs, const QtFontFallbacksCacheKey &rhs) noexcept
44{
45 return !operator==(lhs, rhs);
46}
47
48inline size_t qHash(const QtFontFallbacksCacheKey &key, size_t seed = 0) noexcept
49{
50 QtPrivate::QHashCombine hash;
51 seed = hash(seed, key.family);
52 seed = hash(seed, int(key.style));
53 seed = hash(seed, int(key.styleHint));
54 seed = hash(seed, int(key.script));
55 return seed;
56}
57
58struct Q_GUI_EXPORT QtFontSize
59{
60 void *handle;
61 unsigned short pixelSize : 16;
62};
63
64struct Q_GUI_EXPORT QtFontStyle
65{
66 struct Key
67 {
68 Key(const QString &styleString);
69
70 Key()
71 : style(QFont::StyleNormal)
72 , weight(QFont::Normal)
73 , stretch(0)
74 {}
75
76 Key(const Key &o)
77 : style(o.style)
78 , weight(o.weight)
79 , stretch(o.stretch)
80 {}
81
82 uint style : 2;
83 uint weight : 10;
84 signed int stretch : 12;
85
86 bool operator==(const Key &other) const noexcept
87 {
88 return (style == other.style && weight == other.weight &&
89 (stretch == 0 || other.stretch == 0 || stretch == other.stretch));
90 }
91
92 bool operator!=(const Key &other) const noexcept
93 {
94 return !operator==(other);
95 }
96 };
97
98 QtFontStyle(const Key &k)
99 : key(k)
100 , bitmapScalable(false)
101 , smoothScalable(false)
102 , count(0)
103 , pixelSizes(nullptr)
104 {
105 }
106
107 ~QtFontStyle();
108
109 QtFontSize *pixelSize(unsigned short size, bool = false);
110
111 Key key;
112 bool bitmapScalable : 1;
113 bool smoothScalable : 1;
114 signed int count : 30;
115 QtFontSize *pixelSizes;
116 QString styleName;
117 bool antialiased;
118};
119
120struct Q_GUI_EXPORT QtFontFoundry
121{
122 QtFontFoundry(const QString &n)
123 : name(n)
124 , count(0)
125 , styles(nullptr)
126 {}
127
128 ~QtFontFoundry()
129 {
130 while (count--)
131 delete styles[count];
132 free(ptr: styles);
133 }
134
135 QString name;
136 int count;
137 QtFontStyle **styles;
138 QtFontStyle *style(const QtFontStyle::Key &, const QString & = QString(), bool = false);
139};
140
141struct Q_GUI_EXPORT QtFontFamily
142{
143 enum WritingSystemStatus {
144 Unknown = 0,
145 Supported = 1,
146 UnsupportedFT = 2,
147 Unsupported = UnsupportedFT
148 };
149
150 QtFontFamily(const QString &n)
151 :
152 populated(false),
153 fixedPitch(false),
154 name(n), count(0), foundries(nullptr)
155 {
156 memset(s: writingSystems, c: 0, n: sizeof(writingSystems));
157 }
158 ~QtFontFamily() {
159 while (count--)
160 delete foundries[count];
161 free(ptr: foundries);
162 }
163
164 bool populated : 1;
165 bool fixedPitch : 1;
166
167 QString name;
168 QStringList aliases;
169 int count;
170 QtFontFoundry **foundries;
171
172 unsigned char writingSystems[QFontDatabase::WritingSystemsCount];
173
174 bool matchesFamilyName(const QString &familyName) const;
175 QtFontFoundry *foundry(const QString &f, bool = false);
176
177 bool ensurePopulated();
178};
179
180class Q_GUI_EXPORT QFontDatabasePrivate
181{
182public:
183 QFontDatabasePrivate()
184 : count(0)
185 , families(nullptr)
186 , fallbacksCache(64)
187 { }
188
189 ~QFontDatabasePrivate() {
190 clearFamilies();
191 }
192
193 void clearFamilies();
194
195 enum FamilyRequestFlags {
196 RequestFamily = 0,
197 EnsureCreated,
198 EnsurePopulated
199 };
200
201 QtFontFamily *family(const QString &f, FamilyRequestFlags flags = EnsurePopulated);
202
203 int count;
204 QtFontFamily **families;
205 bool populated = false;
206
207 QCache<QtFontFallbacksCacheKey, QStringList> fallbacksCache;
208 struct ApplicationFont {
209 QString fileName;
210
211 // Note: The data may be implicitly shared throughout the
212 // font database and platform font database, so be careful
213 // to never detach when accessing this member!
214 QByteArray data;
215
216 bool isNull() const { return fileName.isEmpty(); }
217 bool isPopulated() const { return !properties.isEmpty(); }
218
219 struct Properties {
220 QString familyName;
221 QString styleName;
222 int weight = 0;
223 QFont::Style style = QFont::StyleNormal;
224 int stretch = QFont::Unstretched;
225 };
226
227 QList<Properties> properties;
228 };
229 QList<ApplicationFont> applicationFonts;
230 int addAppFont(const QByteArray &fontData, const QString &fileName);
231 bool isApplicationFont(const QString &fileName);
232
233 static QFontDatabasePrivate *instance();
234
235 static void parseFontName(const QString &name, QString &foundry, QString &family);
236 static QString resolveFontFamilyAlias(const QString &family);
237 static QFontEngine *findFont(const QFontDef &request,
238 int script /* QChar::Script */,
239 bool preferScriptOverFamily = false);
240 static void load(const QFontPrivate *d, int script /* QChar::Script */);
241 static QFontDatabasePrivate *ensureFontDatabase();
242
243 void invalidate();
244
245private:
246 static int match(int script, const QFontDef &request, const QString &family_name,
247 const QString &foundry_name, QtFontDesc *desc, const QList<int> &blacklistedFamilies,
248 unsigned int *resultingScore = nullptr);
249
250 static unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
251 const QtFontFamily *family, const QString &foundry_name,
252 QtFontStyle::Key styleKey, int pixelSize, char pitch,
253 QtFontDesc *desc, const QString &styleName = QString());
254
255 static QFontEngine *loadSingleEngine(int script, const QFontDef &request,
256 QtFontFamily *family, QtFontFoundry *foundry,
257 QtFontStyle *style, QtFontSize *size);
258
259 static QFontEngine *loadEngine(int script, const QFontDef &request,
260 QtFontFamily *family, QtFontFoundry *foundry,
261 QtFontStyle *style, QtFontSize *size);
262
263};
264Q_DECLARE_TYPEINFO(QFontDatabasePrivate::ApplicationFont, Q_RELOCATABLE_TYPE);
265
266QT_END_NAMESPACE
267
268#endif // QFONTDATABASE_P_H
269

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