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_H
5#define QFONT_H
6
7#include <QtCore/qcompare.h>
8#include <QtCore/qendian.h>
9#include <QtCore/qshareddata.h>
10#include <QtGui/qtguiglobal.h>
11#include <QtGui/qwindowdefs.h>
12#include <QtCore/qstring.h>
13
14
15QT_BEGIN_NAMESPACE
16
17
18class QFontPrivate; /* don't touch */
19class QVariant;
20
21class Q_GUI_EXPORT QFont
22{
23 Q_GADGET
24public:
25 enum StyleHint {
26 Helvetica, SansSerif = Helvetica,
27 Times, Serif = Times,
28 Courier, TypeWriter = Courier,
29 OldEnglish, Decorative = OldEnglish,
30 System,
31 AnyStyle,
32 Cursive,
33 Monospace,
34 Fantasy
35 };
36 Q_ENUM(StyleHint)
37
38 enum StyleStrategy {
39 PreferDefault = 0x0001,
40 PreferBitmap = 0x0002,
41 PreferDevice = 0x0004,
42 PreferOutline = 0x0008,
43 ForceOutline = 0x0010,
44 PreferMatch = 0x0020,
45 PreferQuality = 0x0040,
46 PreferAntialias = 0x0080,
47 NoAntialias = 0x0100,
48 NoSubpixelAntialias = 0x0800,
49 PreferNoShaping = 0x1000,
50 NoFontMerging = 0x8000
51 };
52 Q_ENUM(StyleStrategy)
53
54 enum HintingPreference {
55 PreferDefaultHinting = 0,
56 PreferNoHinting = 1,
57 PreferVerticalHinting = 2,
58 PreferFullHinting = 3
59 };
60 Q_ENUM(HintingPreference)
61
62 enum Weight {
63 Thin = 100,
64 ExtraLight = 200,
65 Light = 300,
66 Normal = 400,
67 Medium = 500,
68 DemiBold = 600,
69 Bold = 700,
70 ExtraBold = 800,
71 Black = 900
72 };
73 Q_ENUM(Weight)
74
75 enum Style {
76 StyleNormal,
77 StyleItalic,
78 StyleOblique
79 };
80 Q_ENUM(Style)
81
82 enum Stretch {
83 AnyStretch = 0,
84 UltraCondensed = 50,
85 ExtraCondensed = 62,
86 Condensed = 75,
87 SemiCondensed = 87,
88 Unstretched = 100,
89 SemiExpanded = 112,
90 Expanded = 125,
91 ExtraExpanded = 150,
92 UltraExpanded = 200
93 };
94 Q_ENUM(Stretch)
95
96 enum Capitalization {
97 MixedCase,
98 AllUppercase,
99 AllLowercase,
100 SmallCaps,
101 Capitalize
102 };
103 Q_ENUM(Capitalization)
104
105 enum SpacingType {
106 PercentageSpacing,
107 AbsoluteSpacing
108 };
109 Q_ENUM(SpacingType)
110
111 enum ResolveProperties {
112 NoPropertiesResolved = 0x0000,
113 FamilyResolved = 0x0001,
114 SizeResolved = 0x0002,
115 StyleHintResolved = 0x0004,
116 StyleStrategyResolved = 0x0008,
117 WeightResolved = 0x0010,
118 StyleResolved = 0x0020,
119 UnderlineResolved = 0x0040,
120 OverlineResolved = 0x0080,
121 StrikeOutResolved = 0x0100,
122 FixedPitchResolved = 0x0200,
123 StretchResolved = 0x0400,
124 KerningResolved = 0x0800,
125 CapitalizationResolved = 0x1000,
126 LetterSpacingResolved = 0x2000,
127 WordSpacingResolved = 0x4000,
128 HintingPreferenceResolved = 0x8000,
129 StyleNameResolved = 0x10000,
130 FamiliesResolved = 0x20000,
131 FeaturesResolved = 0x40000,
132 VariableAxesResolved = 0x80000,
133 AllPropertiesResolved = 0xfffff
134 };
135 Q_ENUM(ResolveProperties)
136
137 QFont();
138
139 QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false);
140 explicit QFont(const QStringList &families, int pointSize = -1, int weight = -1, bool italic = false);
141 QFont(const QFont &font, const QPaintDevice *pd);
142 QFont(const QFont &font);
143 ~QFont();
144
145 void swap(QFont &other) noexcept
146 { d.swap(other&: other.d); std::swap(a&: resolve_mask, b&: other.resolve_mask); }
147
148 QString family() const;
149 void setFamily(const QString &);
150
151 QStringList families() const;
152 void setFamilies(const QStringList &);
153
154 QString styleName() const;
155 void setStyleName(const QString &);
156
157 int pointSize() const;
158 void setPointSize(int);
159 qreal pointSizeF() const;
160 void setPointSizeF(qreal);
161
162 int pixelSize() const;
163 void setPixelSize(int);
164
165 Weight weight() const;
166 void setWeight(Weight weight);
167
168 inline bool bold() const;
169 inline void setBold(bool);
170
171 void setStyle(Style style);
172 Style style() const;
173
174 inline bool italic() const;
175 inline void setItalic(bool b);
176
177 bool underline() const;
178 void setUnderline(bool);
179
180 bool overline() const;
181 void setOverline(bool);
182
183 bool strikeOut() const;
184 void setStrikeOut(bool);
185
186 bool fixedPitch() const;
187 void setFixedPitch(bool);
188
189 bool kerning() const;
190 void setKerning(bool);
191
192 StyleHint styleHint() const;
193 StyleStrategy styleStrategy() const;
194 void setStyleHint(StyleHint, StyleStrategy = PreferDefault);
195 void setStyleStrategy(StyleStrategy s);
196
197 int stretch() const;
198 void setStretch(int);
199
200 qreal letterSpacing() const;
201 SpacingType letterSpacingType() const;
202 void setLetterSpacing(SpacingType type, qreal spacing);
203
204 qreal wordSpacing() const;
205 void setWordSpacing(qreal spacing);
206
207 void setCapitalization(Capitalization);
208 Capitalization capitalization() const;
209
210 void setHintingPreference(HintingPreference hintingPreference);
211 HintingPreference hintingPreference() const;
212
213 struct Tag
214 {
215 constexpr Tag() = default;
216
217 template <size_t N>
218 constexpr Q_IMPLICIT Tag(const char (&str)[N]) noexcept
219 : m_value((quint32(str[0]) << 24) | (quint32(str[1]) << 16)
220 | (quint32(str[2]) << 8) | quint32(str[3]))
221 {
222 static_assert(N == 5, "The tag name must be exactly 4 characters long!");
223 }
224
225 constexpr bool isValid() const noexcept { return m_value != 0; }
226 constexpr quint32 value() const noexcept { return m_value; }
227
228 QByteArray toString() const
229 {
230 const char data[] = {
231 char((m_value & 0xff000000) >> 24),
232 char((m_value & 0x00ff0000) >> 16),
233 char((m_value & 0x0000ff00) >> 8),
234 char((m_value & 0x000000ff)) };
235 return QByteArray(data, sizeof(data));
236 }
237
238 static constexpr std::optional<Tag> fromValue(quint32 value) noexcept
239 {
240 Tag maybeTag;
241 maybeTag.m_value = value;
242 return maybeTag.isValid() ? std::optional<Tag>(maybeTag) : std::nullopt;
243 }
244 Q_GUI_EXPORT static std::optional<Tag> fromString(QAnyStringView view) noexcept;
245
246#ifndef QT_NO_DATASTREAM
247 friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, Tag);
248 friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, Tag &);
249#endif
250
251#ifndef QT_NO_DEBUG_STREAM
252 friend Q_GUI_EXPORT QDebug operator<<(QDebug debug, Tag tag);
253#endif
254
255 friend constexpr size_t qHash(Tag key, size_t seed = 0) noexcept
256 { return qHash(key: key.value(), seed); }
257
258 private:
259 friend constexpr bool comparesEqual(const Tag &lhs, const Tag &rhs) noexcept
260 { return lhs.m_value == rhs.m_value; }
261 friend constexpr Qt::strong_ordering compareThreeWay(const Tag &lhs, const Tag &rhs) noexcept
262 { return Qt::compareThreeWay(lhs: lhs.m_value, rhs: rhs.m_value); }
263 Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QFont::Tag)
264
265 quint32 m_value = 0;
266 };
267
268 void setFeature(Tag tag, quint32 value);
269 void unsetFeature(Tag tag);
270 quint32 featureValue(Tag tag) const;
271 bool isFeatureSet(Tag tag) const;
272 QList<Tag> featureTags() const;
273 void clearFeatures();
274
275 void setVariableAxis(Tag tag, float value);
276 void unsetVariableAxis(Tag tag);
277 bool isVariableAxisSet(Tag tag) const;
278 float variableAxisValue(Tag tag) const;
279 void clearVariableAxes();
280 QList<Tag> variableAxisTags() const;
281
282 // dupicated from QFontInfo
283 bool exactMatch() const;
284
285 QFont &operator=(const QFont &);
286 bool operator==(const QFont &) const;
287 bool operator!=(const QFont &) const;
288 bool operator<(const QFont &) const;
289 operator QVariant() const;
290 bool isCopyOf(const QFont &) const;
291 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QFont)
292
293 QString key() const;
294
295 QString toString() const;
296 bool fromString(const QString &);
297
298 static QString substitute(const QString &);
299 static QStringList substitutes(const QString &);
300 static QStringList substitutions();
301 static void insertSubstitution(const QString&, const QString &);
302 static void insertSubstitutions(const QString&, const QStringList &);
303 static void removeSubstitutions(const QString &);
304 static void initialize();
305 static void cleanup();
306 static void cacheStatistics();
307
308 QString defaultFamily() const;
309
310 QFont resolve(const QFont &) const;
311 inline uint resolveMask() const { return resolve_mask; }
312 inline void setResolveMask(uint mask) { resolve_mask = mask; }
313
314#if QT_DEPRECATED_SINCE(6, 0)
315 QT_DEPRECATED_VERSION_X_6_0("Use setWeight() instead") void setLegacyWeight(int legacyWeight);
316 QT_DEPRECATED_VERSION_X_6_0("Use weight() instead") int legacyWeight() const;
317#endif
318
319private:
320 explicit QFont(QFontPrivate *);
321
322 void detach();
323
324
325 friend class QFontPrivate;
326 friend class QFontDialogPrivate;
327 friend class QFontMetrics;
328 friend class QFontMetricsF;
329 friend class QFontInfo;
330 friend class QPainter;
331 friend class QPainterPrivate;
332 friend class QApplication;
333 friend class QWidget;
334 friend class QWidgetPrivate;
335 friend class QTextLayout;
336 friend class QTextEngine;
337 friend class QStackTextEngine;
338 friend class QTextLine;
339 friend struct QScriptLine;
340 friend class QOpenGLContext;
341 friend class QWin32PaintEngine;
342 friend class QAlphaPaintEngine;
343 friend class QPainterPath;
344 friend class QTextItemInt;
345 friend class QPicturePaintEngine;
346 friend class QPainterReplayer;
347 friend class QPaintBufferEngine;
348 friend class QCommandLinkButtonPrivate;
349 friend class QFontEngine;
350
351#ifndef QT_NO_DATASTREAM
352 friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QFont &);
353 friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QFont &);
354#endif
355
356#ifndef QT_NO_DEBUG_STREAM
357 friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QFont &);
358#endif
359
360 QExplicitlySharedDataPointer<QFontPrivate> d;
361 uint resolve_mask;
362};
363
364Q_DECLARE_SHARED(QFont)
365
366Q_GUI_EXPORT size_t qHash(const QFont &font, size_t seed = 0) noexcept;
367
368inline bool QFont::bold() const
369{ return weight() > Medium; }
370
371
372inline void QFont::setBold(bool enable)
373{ setWeight(enable ? Bold : Normal); }
374
375inline bool QFont::italic() const
376{
377 return (style() != StyleNormal);
378}
379
380inline void QFont::setItalic(bool b) {
381 setStyle(b ? StyleItalic : StyleNormal);
382}
383
384
385/*****************************************************************************
386 QFont stream functions
387 *****************************************************************************/
388
389#ifndef QT_NO_DATASTREAM
390Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QFont &);
391Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QFont &);
392#endif
393
394#ifndef QT_NO_DEBUG_STREAM
395Q_GUI_EXPORT QDebug operator<<(QDebug, const QFont &);
396#endif
397
398QT_END_NAMESPACE
399
400#endif // QFONT_H
401