Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qfont.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 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#include "qfont.h"
5#include "qdebug.h"
6#include "qpaintdevice.h"
7#include "qfontdatabase.h"
8#include "qfontmetrics.h"
9#include "qfontinfo.h"
10#include "qpainter.h"
11#include "qhash.h"
12#include "qdatastream.h"
13#include "qguiapplication.h"
14#include "qstringlist.h"
15#include "qscreen.h"
16
17#include "qthread.h"
18#include "qthreadstorage.h"
19
20#include "qfont_p.h"
21#include <private/qfontengine_p.h>
22#include <private/qpainter_p.h>
23#include <private/qtextengine_p.h>
24#include <limits.h>
25
26#include <qpa/qplatformscreen.h>
27#include <qpa/qplatformintegration.h>
28#include <qpa/qplatformfontdatabase.h>
29#include <QtGui/private/qguiapplication_p.h>
30
31#include <QtCore/QMutexLocker>
32#include <QtCore/QMutex>
33
34#include <array>
35
36// #define QFONTCACHE_DEBUG
37#ifdef QFONTCACHE_DEBUG
38# define FC_DEBUG qDebug
39#else
40# define FC_DEBUG if (false) qDebug
41#endif
42
44
45#ifndef QFONTCACHE_DECREASE_TRIGGER_LIMIT
46# define QFONTCACHE_DECREASE_TRIGGER_LIMIT 256
47#endif
48
50{
51 /*
52 QFontDef comparison is more complicated than just simple
53 per-member comparisons.
54
55 When comparing point/pixel sizes, either point or pixelsize
56 could be -1. in This case we have to compare the non negative
57 size value.
58
59 This test will fail if the point-sizes differ by 1/2 point or
60 more or they do not round to the same value. We have to do this
61 since our API still uses 'int' point-sizes in the API, but store
62 deci-point-sizes internally.
63
64 To compare the family members, we need to parse the font names
65 and compare the family/foundry strings separately. This allows
66 us to compare e.g. "Helvetica" and "Helvetica [Adobe]" with
67 positive results.
68 */
69 if (pixelSize != -1 && other.pixelSize != -1) {
70 if (pixelSize != other.pixelSize)
71 return false;
72 } else if (pointSize != -1 && other.pointSize != -1) {
73 if (pointSize != other.pointSize)
74 return false;
75 } else {
76 return false;
77 }
78
79 if (!ignorePitch && !other.ignorePitch && fixedPitch != other.fixedPitch)
80 return false;
81
82 if (stretch != 0 && other.stretch != 0 && stretch != other.stretch)
83 return false;
84
85 QString this_family, this_foundry, other_family, other_foundry;
86 for (int i = 0; i < families.size(); ++i) {
87 QFontDatabasePrivate::parseFontName(families.at(i), this_foundry, this_family);
88 QFontDatabasePrivate::parseFontName(other.families.at(i), other_foundry, other_family);
89 if (this_family != other_family || this_foundry != other_foundry)
90 return false;
91 }
92
93 return (styleHint == other.styleHint
94 && styleStrategy == other.styleStrategy
95 && weight == other.weight
96 && style == other.style
97 && this_family == other_family
98 && (styleName.isEmpty() || other.styleName.isEmpty() || styleName == other.styleName)
99 && (this_foundry.isEmpty()
100 || other_foundry.isEmpty()
101 || this_foundry == other_foundry)
102 );
103}
104
105extern bool qt_is_tty_app;
106
107Q_GUI_EXPORT int qt_defaultDpiX()
108{
109 if (QCoreApplication::instance()->testAttribute(Qt::AA_Use96Dpi))
110 return 96;
111
112 if (qt_is_tty_app)
113 return 75;
114
117
118 //PI has not been initialised, or it is being initialised. Give a default dpi
119 return 100;
120}
121
122Q_GUI_EXPORT int qt_defaultDpiY()
123{
124 if (QCoreApplication::instance()->testAttribute(Qt::AA_Use96Dpi))
125 return 96;
126
127 if (qt_is_tty_app)
128 return 75;
129
132
133 //PI has not been initialised, or it is being initialised. Give a default dpi
134 return 100;
135}
136
137Q_GUI_EXPORT int qt_defaultDpi()
138{
139 return qt_defaultDpiY();
140}
141
142/* Helper function to convert between legacy Qt and OpenType font weights. */
143static int convertWeights(int weight, bool inverted)
144{
145 static constexpr std::array<int, 2> legacyToOpenTypeMap[] = {
146 { 0, QFont::Thin }, { 12, QFont::ExtraLight }, { 25, QFont::Light },
147 { 50, QFont::Normal }, { 57, QFont::Medium }, { 63, QFont::DemiBold },
148 { 75, QFont::Bold }, { 81, QFont::ExtraBold }, { 87, QFont::Black },
149 };
150
151 int closestDist = INT_MAX;
152 int result = -1;
153
154 // Go through and find the closest mapped value
155 for (auto mapping : legacyToOpenTypeMap) {
156 const int weightOld = mapping[ inverted];
157 const int weightNew = mapping[!inverted];
158 const int dist = qAbs(weightOld - weight);
159 if (dist < closestDist) {
160 result = weightNew;
161 closestDist = dist;
162 } else {
163 // Break early since following values will be further away
164 break;
165 }
166 }
167
168 return result;
169}
170
171// Splits the family string on a comma and returns the list based on that
173{
175 if (family.isEmpty())
176 return familyList;
177 const auto list = QStringView{family}.split(u',');
178 const int numFamilies = list.size();
179 familyList.reserve(numFamilies);
180 for (int i = 0; i < numFamilies; ++i) {
181 auto str = list.at(i).trimmed();
182 if ((str.startsWith(u'"') && str.endsWith(u'"'))
183 || (str.startsWith(u'\'') && str.endsWith(u'\''))) {
184 str = str.mid(1, str.size() - 2);
185 }
186 familyList << str.toString();
187 }
188 return familyList;
189}
190
191/* Converts from legacy Qt font weight (Qt < 6.0) to OpenType font weight (Qt >= 6.0) */
193{
194 return convertWeights(weight, false);
195}
196
197/* Converts from OpenType font weight (Qt >= 6.0) to legacy Qt font weight (Qt < 6.0) */
199{
200 return convertWeights(weight, true);
201}
202
204 : engineData(nullptr), dpi(qt_defaultDpi()),
205 underline(false), overline(false), strikeOut(false), kerning(true),
206 capital(0), letterSpacingIsAbsolute(false), scFont(nullptr)
207{
208}
209
211 : request(other.request), engineData(nullptr), dpi(other.dpi),
212 underline(other.underline), overline(other.overline),
213 strikeOut(other.strikeOut), kerning(other.kerning),
214 capital(other.capital), letterSpacingIsAbsolute(other.letterSpacingIsAbsolute),
215 letterSpacing(other.letterSpacing), wordSpacing(other.wordSpacing),
216 features(other.features), scFont(other.scFont)
217{
218 if (scFont && scFont != this)
219 scFont->ref.ref();
220}
221
223{
224 if (engineData && !engineData->ref.deref())
225 delete engineData;
226 engineData = nullptr;
227 if (scFont && scFont != this) {
228 if (!scFont->ref.deref())
229 delete scFont;
230 }
231 scFont = nullptr;
232}
233
235
236#define QT_FONT_ENGINE_FROM_DATA(data, script) data->engines[script]
237
239{
241 if (script <= QChar::Script_Latin)
242 script = QChar::Script_Common;
244 // throw out engineData that came from a different thread
245 if (!engineData->ref.deref())
246 delete engineData;
247 engineData = nullptr;
248 }
250 QFontDatabasePrivate::load(this, script);
251 return QT_FONT_ENGINE_FROM_DATA(engineData, script);
252}
253
255 switch (capital) {
257 case QFont::SmallCaps:
258 c = c.toUpper();
259 break;
261 c = c.toLower();
262 break;
263 case QFont::MixedCase:
264 break;
265 }
266}
267
269{
270 if (scFont)
271 return scFont;
272 QFont font(const_cast<QFontPrivate *>(this));
273 qreal pointSize = font.pointSizeF();
274 if (pointSize > 0)
275 font.setPointSizeF(pointSize * .7);
276 else
277 font.setPixelSize((font.pixelSize() * 7 + 5) / 10);
278 scFont = font.d.data();
279 if (scFont != this)
280 scFont->ref.ref();
281 return scFont;
282}
283
284
286{
287 Q_ASSERT(other != nullptr);
288
289 dpi = other->dpi;
290
292
293 // assign the unset-bits with the set-bits of the other font def
295 request.families = other->request.families;
296
298 request.styleName = other->request.styleName;
299
300 if (! (mask & QFont::SizeResolved)) {
301 request.pointSize = other->request.pointSize;
302 request.pixelSize = other->request.pixelSize;
303 }
304
306 request.styleHint = other->request.styleHint;
307
309 request.styleStrategy = other->request.styleStrategy;
310
311 if (! (mask & QFont::WeightResolved))
312 request.weight = other->request.weight;
313
314 if (! (mask & QFont::StyleResolved))
315 request.style = other->request.style;
316
318 request.fixedPitch = other->request.fixedPitch;
319
321 request.stretch = other->request.stretch;
322
324 request.hintingPreference = other->request.hintingPreference;
325
327 underline = other->underline;
328
330 overline = other->overline;
331
333 strikeOut = other->strikeOut;
334
336 kerning = other->kerning;
337
339 letterSpacing = other->letterSpacing;
340 letterSpacingIsAbsolute = other->letterSpacingIsAbsolute;
341 }
343 wordSpacing = other->wordSpacing;
345 capital = other->capital;
346
348 features = other->features;
349}
350
352{
354}
355
357{
359}
360
361
363 : ref(0), fontCacheId(QFontCache::instance()->id())
364{
365 memset(engines, 0, QChar::ScriptCount * sizeof(QFontEngine *));
366}
367
369{
370 Q_ASSERT(ref.loadRelaxed() == 0);
371 for (int i = 0; i < QChar::ScriptCount; ++i) {
372 if (engines[i]) {
373 if (!engines[i]->ref.deref())
374 delete engines[i];
375 engines[i] = nullptr;
376 }
377 }
378}
379
380
381
382
601 : resolve_mask(font.resolve_mask)
602{
603 Q_ASSERT(pd);
604 const int dpi = pd->logicalDpiY();
605 if (font.d->dpi != dpi) {
606 d = new QFontPrivate(*font.d);
607 d->dpi = dpi;
608 } else {
609 d = font.d;
610 }
611}
612
617 : d(data), resolve_mask(QFont::AllPropertiesResolved)
618{
619}
620
624void QFont::detach()
625{
626 if (d->ref.loadRelaxed() == 1) {
627 if (d->engineData && !d->engineData->ref.deref())
628 delete d->engineData;
629 d->engineData = nullptr;
630 if (d->scFont && d->scFont != d.data()) {
631 if (!d->scFont->ref.deref())
632 delete d->scFont;
633 }
634 d->scFont = nullptr;
635 return;
636 }
637
638 d.detach();
639}
640
648{
649 if (font->d->ref.loadRelaxed() == 1)
650 return;
651
653 if (engineData)
654 engineData->ref.ref();
655 font->d.detach();
657}
658
665 : d(QGuiApplicationPrivate::instance() ? QGuiApplication::font().d.data() : new QFontPrivate()), resolve_mask(0)
666{
667}
668
691QFont::QFont(const QString &family, int pointSize, int weight, bool italic)
692 : d(new QFontPrivate()), resolve_mask(QFont::FamiliesResolved)
693{
694 if (pointSize <= 0) {
695 pointSize = 12;
696 } else {
697 resolve_mask |= QFont::SizeResolved;
698 }
699
700 if (weight < 0) {
701 weight = Normal;
702 } else {
704 }
705
706 if (italic)
707 resolve_mask |= QFont::StyleResolved;
708
711 d->request.pixelSize = -1;
712 d->request.weight = weight;
714}
715
734QFont::QFont(const QStringList &families, int pointSize, int weight, bool italic)
735 : d(new QFontPrivate()), resolve_mask(QFont::FamiliesResolved)
736{
737 if (pointSize <= 0)
738 pointSize = 12;
739 else
740 resolve_mask |= QFont::SizeResolved;
741
742 if (weight < 0)
743 weight = Normal;
744 else
746
747 if (italic)
748 resolve_mask |= QFont::StyleResolved;
749
752 d->request.pixelSize = -1;
753 d->request.weight = weight;
755}
756
761 : d(font.d), resolve_mask(font.resolve_mask)
762{
763}
764
769{
770}
771
776{
777 d = font.d;
778 resolve_mask = font.resolve_mask;
779 return *this;
780}
781
797{
798 return d->request.families.isEmpty() ? QString() : d->request.families.constFirst();
799}
800
814void QFont::setFamily(const QString &family)
815{
817}
818
829{
830 return d->request.styleName;
831}
832
846void QFont::setStyleName(const QString &styleName)
847{
848 if ((resolve_mask & QFont::StyleNameResolved) && d->request.styleName == styleName)
849 return;
850
851 detach();
852
854 resolve_mask |= QFont::StyleNameResolved;
855}
856
864{
865 return qRound(d->request.pointSize);
866}
867
943{
945 return;
946
947 detach();
948
950
951 resolve_mask |= QFont::HintingPreferenceResolved;
952}
953
960{
962}
963
970void QFont::setPointSize(int pointSize)
971{
972 if (pointSize <= 0) {
973 qWarning("QFont::setPointSize: Point size <= 0 (%d), must be greater than 0", pointSize);
974 return;
975 }
976
977 if ((resolve_mask & QFont::SizeResolved) && d->request.pointSize == qreal(pointSize))
978 return;
979
980 detach();
981
983 d->request.pixelSize = -1;
984
985 resolve_mask |= QFont::SizeResolved;
986}
987
996{
997 if (pointSize <= 0) {
998 qWarning("QFont::setPointSizeF: Point size <= 0 (%f), must be greater than 0", pointSize);
999 return;
1000 }
1001
1002 if ((resolve_mask & QFont::SizeResolved) && d->request.pointSize == pointSize)
1003 return;
1004
1005 detach();
1006
1008 d->request.pixelSize = -1;
1009
1010 resolve_mask |= QFont::SizeResolved;
1011}
1012
1020{
1021 return d->request.pointSize;
1022}
1023
1034void QFont::setPixelSize(int pixelSize)
1035{
1036 if (pixelSize <= 0) {
1037 qWarning("QFont::setPixelSize: Pixel size <= 0 (%d)", pixelSize);
1038 return;
1039 }
1040
1041 if ((resolve_mask & QFont::SizeResolved) && d->request.pixelSize == qreal(pixelSize))
1042 return;
1043
1044 detach();
1045
1047 d->request.pointSize = -1;
1048
1049 resolve_mask |= QFont::SizeResolved;
1050}
1051
1060{
1061 return d->request.pixelSize;
1062}
1063
1091{
1092 return (QFont::Style)d->request.style;
1093}
1094
1095
1102{
1103 if ((resolve_mask & QFont::StyleResolved) && d->request.style == style)
1104 return;
1105
1106 detach();
1107
1108 d->request.style = style;
1109 resolve_mask |= QFont::StyleResolved;
1110}
1111
1119{
1120 return static_cast<Weight>(d->request.weight);
1121}
1122
1142#if QT_DEPRECATED_SINCE(6, 0)
1158void QFont::setLegacyWeight(int legacyWeight)
1159{
1161}
1162
1176int QFont::legacyWeight() const
1177{
1179}
1180#endif // QT_DEPRECATED_SINCE(6, 0)
1181
1191{
1192 const int weightValue = qBound(QFONT_WEIGHT_MIN, static_cast<int>(weight), QFONT_WEIGHT_MAX);
1193 if (weightValue != static_cast<int>(weight)) {
1194 qWarning() << "QFont::setWeight: Weight must be between 1 and 1000, attempted to set "
1195 << static_cast<int>(weight);
1196 }
1197
1198 if ((resolve_mask & QFont::WeightResolved) && d->request.weight == weightValue)
1199 return;
1200
1201 detach();
1202
1203 d->request.weight = weightValue;
1204 resolve_mask |= QFont::WeightResolved;
1205}
1206
1237{
1238 return d->underline;
1239}
1240
1248{
1249 if ((resolve_mask & QFont::UnderlineResolved) && d->underline == enable)
1250 return;
1251
1253
1254 d->underline = enable;
1255 resolve_mask |= QFont::UnderlineResolved;
1256}
1257
1264{
1265 return d->overline;
1266}
1267
1274{
1275 if ((resolve_mask & QFont::OverlineResolved) && d->overline == enable)
1276 return;
1277
1279
1280 d->overline = enable;
1281 resolve_mask |= QFont::OverlineResolved;
1282}
1283
1290{
1291 return d->strikeOut;
1292}
1293
1301{
1302 if ((resolve_mask & QFont::StrikeOutResolved) && d->strikeOut == enable)
1303 return;
1304
1306
1307 d->strikeOut = enable;
1308 resolve_mask |= QFont::StrikeOutResolved;
1309}
1310
1317{
1318 return d->request.fixedPitch;
1319}
1320
1328{
1329 if ((resolve_mask & QFont::FixedPitchResolved) && d->request.fixedPitch == enable)
1330 return;
1331
1332 detach();
1333
1335 d->request.ignorePitch = false;
1336 resolve_mask |= QFont::FixedPitchResolved;
1337}
1338
1344bool QFont::kerning() const
1345{
1346 return d->kerning;
1347}
1348
1361{
1362 if ((resolve_mask & QFont::KerningResolved) && d->kerning == enable)
1363 return;
1364
1366
1367 d->kerning = enable;
1368 resolve_mask |= QFont::KerningResolved;
1369}
1370
1380{
1382}
1383
1393{
1394 return (StyleHint) d->request.styleHint;
1395}
1396
1483{
1484 if ((resolve_mask & (QFont::StyleHintResolved | QFont::StyleStrategyResolved)) &&
1485 (StyleHint) d->request.styleHint == hint &&
1486 (StyleStrategy) d->request.styleStrategy == strategy)
1487 return;
1488
1489 detach();
1490
1491 d->request.styleHint = hint;
1492 d->request.styleStrategy = strategy;
1493 resolve_mask |= QFont::StyleHintResolved;
1494 resolve_mask |= QFont::StyleStrategyResolved;
1495
1496}
1497
1504{
1505 if ((resolve_mask & QFont::StyleStrategyResolved) &&
1507 return;
1508
1509 detach();
1510
1511 d->request.styleStrategy = s;
1512 resolve_mask |= QFont::StyleStrategyResolved;
1513}
1514
1515
1542{
1543 return d->request.stretch;
1544}
1545
1565void QFont::setStretch(int factor)
1566{
1567 if (factor < 0 || factor > 4000) {
1568 qWarning("QFont::setStretch: Parameter '%d' out of range", factor);
1569 return;
1570 }
1571
1572 if ((resolve_mask & QFont::StretchResolved) &&
1573 d->request.stretch == (uint)factor)
1574 return;
1575
1576 detach();
1577
1578 d->request.stretch = (uint)factor;
1579 resolve_mask |= QFont::StretchResolved;
1580}
1581
1599{
1600 return d->letterSpacing.toReal();
1601}
1602
1616{
1617 const QFixed newSpacing = QFixed::fromReal(spacing);
1618 const bool absoluteSpacing = type == AbsoluteSpacing;
1619 if ((resolve_mask & QFont::LetterSpacingResolved) &&
1620 d->letterSpacingIsAbsolute == absoluteSpacing &&
1621 d->letterSpacing == newSpacing)
1622 return;
1623
1625
1626 d->letterSpacing = newSpacing;
1627 d->letterSpacingIsAbsolute = absoluteSpacing;
1628 resolve_mask |= QFont::LetterSpacingResolved;
1629}
1630
1638{
1640}
1641
1649{
1650 return d->wordSpacing.toReal();
1651}
1652
1668{
1669 const QFixed newSpacing = QFixed::fromReal(spacing);
1670 if ((resolve_mask & QFont::WordSpacingResolved) &&
1671 d->wordSpacing == newSpacing)
1672 return;
1673
1675
1676 d->wordSpacing = newSpacing;
1677 resolve_mask |= QFont::WordSpacingResolved;
1678}
1679
1703{
1704 if ((resolve_mask & QFont::CapitalizationResolved) &&
1705 capitalization() == caps)
1706 return;
1707
1709
1710 d->capital = caps;
1711 resolve_mask |= QFont::CapitalizationResolved;
1712}
1713
1721{
1722 return static_cast<QFont::Capitalization> (d->capital);
1723}
1724
1732{
1734 Q_ASSERT(engine != nullptr);
1735 return d->request.exactMatch(engine->fontDef);
1736}
1737
1747bool QFont::operator==(const QFont &f) const
1748{
1749 return (f.d == d
1750 || (f.d->request == d->request
1751 && f.d->request.pointSize == d->request.pointSize
1752 && f.d->underline == d->underline
1753 && f.d->overline == d->overline
1754 && f.d->strikeOut == d->strikeOut
1755 && f.d->kerning == d->kerning
1756 && f.d->capital == d->capital
1757 && f.d->letterSpacingIsAbsolute == d->letterSpacingIsAbsolute
1758 && f.d->letterSpacing == d->letterSpacing
1759 && f.d->wordSpacing == d->wordSpacing
1760 && f.d->features == d->features
1761 ));
1762}
1763
1764
1776bool QFont::operator<(const QFont &f) const
1777{
1778 if (f.d == d) return false;
1779 // the < operator for fontdefs ignores point sizes.
1780 const QFontDef &r1 = f.d->request;
1781 const QFontDef &r2 = d->request;
1782 if (r1.pointSize != r2.pointSize) return r1.pointSize < r2.pointSize;
1783 if (r1.pixelSize != r2.pixelSize) return r1.pixelSize < r2.pixelSize;
1784 if (r1.weight != r2.weight) return r1.weight < r2.weight;
1785 if (r1.style != r2.style) return r1.style < r2.style;
1786 if (r1.stretch != r2.stretch) return r1.stretch < r2.stretch;
1787 if (r1.styleHint != r2.styleHint) return r1.styleHint < r2.styleHint;
1788 if (r1.styleStrategy != r2.styleStrategy) return r1.styleStrategy < r2.styleStrategy;
1789 if (r1.families != r2.families) return r1.families < r2.families;
1790 if (f.d->capital != d->capital) return f.d->capital < d->capital;
1791
1792 if (f.d->letterSpacingIsAbsolute != d->letterSpacingIsAbsolute) return f.d->letterSpacingIsAbsolute < d->letterSpacingIsAbsolute;
1793 if (f.d->letterSpacing != d->letterSpacing) return f.d->letterSpacing < d->letterSpacing;
1794 if (f.d->wordSpacing != d->wordSpacing) return f.d->wordSpacing < d->wordSpacing;
1795
1796 int f1attrs = (f.d->underline << 3) + (f.d->overline << 2) + (f.d->strikeOut<<1) + f.d->kerning;
1797 int f2attrs = (d->underline << 3) + (d->overline << 2) + (d->strikeOut<<1) + d->kerning;
1798 if (f1attrs != f2attrs) return f1attrs < f2attrs;
1799
1800 if (d->features.size() != f.d->features.size())
1801 return f.d->features.size() < d->features.size();
1802
1803 auto it = d->features.constBegin();
1804 auto jt = f.d->features.constBegin();
1805 for (; it != d->features.constEnd(); ++it, ++jt) {
1806 if (it.key() != jt.key())
1807 return jt.key() < it.key();
1808 if (it.value() != jt.value())
1809 return jt.value() < it.value();
1810 }
1811
1812 return false;
1813}
1814
1815
1825bool QFont::operator!=(const QFont &f) const
1826{
1827 return !(operator==(f));
1828}
1829
1833QFont::operator QVariant() const
1834{
1835 return QVariant::fromValue(*this);
1836}
1837
1845bool QFont::isCopyOf(const QFont & f) const
1846{
1847 return d == f.d;
1848}
1849
1855{
1856 if (resolve_mask == 0 || (resolve_mask == other.resolve_mask && *this == other)) {
1857 QFont o(other);
1858 o.resolve_mask = resolve_mask;
1859 return o;
1860 }
1861
1862 QFont font(*this);
1863 font.detach();
1864 font.d->resolve(resolve_mask, other.d.data());
1865
1866 return font;
1867}
1868
1880/*****************************************************************************
1881 QFont substitution management
1882 *****************************************************************************/
1883
1885Q_GLOBAL_STATIC(QFontSubst, globalFontSubst)
1886
1887
1898QString QFont::substitute(const QString &familyName)
1899{
1900 QFontSubst *fontSubst = globalFontSubst();
1901 Q_ASSERT(fontSubst != nullptr);
1902 QFontSubst::ConstIterator it = fontSubst->constFind(familyName.toLower());
1903 if (it != fontSubst->constEnd() && !(*it).isEmpty())
1904 return (*it).first();
1905
1906 return familyName;
1907}
1908
1909
1920{
1921 QFontSubst *fontSubst = globalFontSubst();
1922 Q_ASSERT(fontSubst != nullptr);
1923 return fontSubst->value(familyName.toLower(), QStringList());
1924}
1925
1926
1936void QFont::insertSubstitution(const QString &familyName,
1937 const QString &substituteName)
1938{
1939 QFontSubst *fontSubst = globalFontSubst();
1940 Q_ASSERT(fontSubst != nullptr);
1941 QStringList &list = (*fontSubst)[familyName.toLower()];
1942 QString s = substituteName.toLower();
1943 if (!list.contains(s))
1944 list.append(s);
1945}
1946
1947
1959 const QStringList &substituteNames)
1960{
1961 QFontSubst *fontSubst = globalFontSubst();
1962 Q_ASSERT(fontSubst != nullptr);
1963 QStringList &list = (*fontSubst)[familyName.toLower()];
1964 for (const QString &substituteName : substituteNames) {
1965 const QString lowerSubstituteName = substituteName.toLower();
1966 if (!list.contains(lowerSubstituteName))
1967 list.append(lowerSubstituteName);
1968 }
1969}
1970
1978{
1979 QFontSubst *fontSubst = globalFontSubst();
1980 Q_ASSERT(fontSubst != nullptr);
1981 fontSubst->remove(familyName.toLower());
1982}
1983
1990{
1991 QFontSubst *fontSubst = globalFontSubst();
1992 Q_ASSERT(fontSubst != nullptr);
1993 QStringList ret = fontSubst->keys();
1994
1995 ret.sort();
1996 return ret;
1997}
1998
1999#ifndef QT_NO_DATASTREAM
2000/* \internal
2001 Internal function. Converts boolean font settings to an unsigned
2002 8-bit number. Used for serialization etc.
2003*/
2004static quint8 get_font_bits(int version, const QFontPrivate *f)
2005{
2006 Q_ASSERT(f != nullptr);
2007 quint8 bits = 0;
2008 if (f->request.style)
2009 bits |= 0x01;
2010 if (f->underline)
2011 bits |= 0x02;
2012 if (f->overline)
2013 bits |= 0x40;
2014 if (f->strikeOut)
2015 bits |= 0x04;
2016 if (f->request.fixedPitch)
2017 bits |= 0x08;
2018 // if (f.hintSetByUser)
2019 // bits |= 0x10;
2020 if (version >= QDataStream::Qt_4_0) {
2021 if (f->kerning)
2022 bits |= 0x10;
2023 }
2024 if (f->request.style == QFont::StyleOblique)
2025 bits |= 0x80;
2026 return bits;
2027}
2028
2030{
2031 Q_ASSERT(f != nullptr);
2032 quint8 bits = 0;
2033 if (f->request.ignorePitch)
2034 bits |= 0x01;
2035 if (f->letterSpacingIsAbsolute)
2036 bits |= 0x02;
2037 return bits;
2038}
2039
2040/* \internal
2041 Internal function. Sets boolean font settings from an unsigned
2042 8-bit number. Used for serialization etc.
2043*/
2044static void set_font_bits(int version, quint8 bits, QFontPrivate *f)
2045{
2046 Q_ASSERT(f != nullptr);
2047 f->request.style = (bits & 0x01) != 0 ? QFont::StyleItalic : QFont::StyleNormal;
2048 f->underline = (bits & 0x02) != 0;
2049 f->overline = (bits & 0x40) != 0;
2050 f->strikeOut = (bits & 0x04) != 0;
2051 f->request.fixedPitch = (bits & 0x08) != 0;
2052 // f->hintSetByUser = (bits & 0x10) != 0;
2053 if (version >= QDataStream::Qt_4_0)
2054 f->kerning = (bits & 0x10) != 0;
2055 if ((bits & 0x80) != 0)
2056 f->request.style = QFont::StyleOblique;
2057}
2058
2060{
2061 Q_ASSERT(f != nullptr);
2062 f->request.ignorePitch = (bits & 0x01) != 0;
2063 f->letterSpacingIsAbsolute = (bits & 0x02) != 0;
2064}
2065#endif
2066
2074{
2075 return toString();
2076}
2077
2105{
2106 const QChar comma(u',');
2107 QString fontDescription = family() + comma +
2108 QString::number( pointSizeF()) + comma +
2109 QString::number( pixelSize()) + comma +
2110 QString::number((int) styleHint()) + comma +
2111 QString::number( weight()) + comma +
2112 QString::number((int) style()) + comma +
2113 QString::number((int) underline()) + comma +
2114 QString::number((int) strikeOut()) + comma +
2115 QString::number((int)fixedPitch()) + comma +
2116 QString::number((int) false) + comma +
2117 QString::number((int)capitalization()) + comma +
2118 QString::number((int)letterSpacingType()) + comma +
2119 QString::number(letterSpacing()) + comma +
2120 QString::number(wordSpacing()) + comma +
2121 QString::number(stretch()) + comma +
2123
2125 if (!fontStyle.isEmpty())
2126 fontDescription += comma + fontStyle;
2127
2128 return fontDescription;
2129}
2130
2138size_t qHash(const QFont &font, size_t seed) noexcept
2139{
2141}
2142
2143
2151bool QFont::fromString(const QString &descrip)
2152{
2153 const auto sr = QStringView(descrip).trimmed();
2154 const auto l = sr.split(u',');
2155 const int count = l.size();
2156 if (!count || (count > 2 && count < 9) || count == 9 || count > 17 ||
2157 l.first().isEmpty()) {
2158 qWarning("QFont::fromString: Invalid description '%s'",
2159 descrip.isEmpty() ? "(empty)" : descrip.toLatin1().data());
2160 return false;
2161 }
2162
2163 setFamily(l[0].toString());
2164 if (count > 1 && l[1].toDouble() > 0.0)
2165 setPointSizeF(l[1].toDouble());
2166 if (count == 9) {
2167 setStyleHint((StyleHint) l[2].toInt());
2168 setWeight(QFont::Weight(l[3].toInt()));
2169 setItalic(l[4].toInt());
2170 setUnderline(l[5].toInt());
2171 setStrikeOut(l[6].toInt());
2172 setFixedPitch(l[7].toInt());
2173 } else if (count >= 10) {
2174 if (l[2].toInt() > 0)
2175 setPixelSize(l[2].toInt());
2176 setStyleHint((StyleHint) l[3].toInt());
2177 if (count >= 16)
2178 setWeight(QFont::Weight(l[4].toInt()));
2179 else
2181 setStyle((QFont::Style)l[5].toInt());
2182 setUnderline(l[6].toInt());
2183 setStrikeOut(l[7].toInt());
2184 setFixedPitch(l[8].toInt());
2185 if (count >= 16) {
2187 setLetterSpacing((SpacingType)l[11].toInt(), l[12].toDouble());
2188 setWordSpacing(l[13].toDouble());
2189 setStretch(l[14].toInt());
2191 }
2192 if (count == 11 || count == 17)
2193 d->request.styleName = l[count - 1].toString();
2194 else
2195 d->request.styleName.clear();
2196 }
2197
2198 if (count >= 9 && !d->request.fixedPitch) // assume 'false' fixedPitch equals default
2199 d->request.ignorePitch = true;
2200
2201 return true;
2202}
2203
2212{
2213}
2214
2221{
2223}
2224
2230{
2231}
2232
2270{
2271 if (tag != 0) {
2272 d->detachButKeepEngineData(this);
2273 d->setFeature(tag, value);
2274 resolve_mask |= QFont::FeaturesResolved;
2275 }
2276}
2277
2291void QFont::setFeature(const char *feature, quint32 value)
2292{
2293 setFeature(stringToTag(feature), value);
2294}
2295
2312{
2313 if (tag != 0) {
2314 d->detachButKeepEngineData(this);
2315 d->unsetFeature(tag);
2316 resolve_mask |= QFont::FeaturesResolved;
2317 }
2318}
2319
2337void QFont::unsetFeature(const char *feature)
2338{
2339 unsetFeature(stringToTag(feature));
2340}
2341
2352{
2353 return d->features.keys();
2354}
2355
2367{
2368 return d->features.value(tag);
2369}
2370
2382{
2383 return d->features.contains(tag);
2384}
2385
2396{
2397 d->features.clear();
2398}
2399
2410{
2411 char str[4] =
2412 { char((tag & 0xff000000) >> 24),
2413 char((tag & 0x00ff0000) >> 16),
2414 char((tag & 0x0000ff00) >> 8),
2415 char((tag & 0x000000ff)) };
2416 return QByteArray(str, 4);
2417}
2418
2432{
2433 if (qstrlen(name) != 4)
2434 return 0;
2435
2436 return MAKE_TAG(name[0], name[1], name[2], name[3]);
2437}
2438
2439extern QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style,
2440 QFont::StyleHint styleHint, QChar::Script script);
2441
2451{
2454 if (!fallbacks.isEmpty())
2455 return fallbacks.first();
2456 return QString();
2457}
2458
2470{
2471 return d->request.families;
2472}
2473
2491void QFont::setFamilies(const QStringList &families)
2492{
2493 if ((resolve_mask & QFont::FamiliesResolved) && d->request.families == families)
2494 return;
2495 detach();
2497 resolve_mask |= QFont::FamiliesResolved;
2498}
2499
2500
2501/*****************************************************************************
2502 QFont stream functions
2503 *****************************************************************************/
2504#ifndef QT_NO_DATASTREAM
2505
2515{
2516 if (s.version() == 1) {
2517 s << font.d->request.families.first().toLatin1();
2518 } else {
2519 s << font.d->request.families.first();
2520 if (s.version() >= QDataStream::Qt_5_4)
2521 s << font.d->request.styleName;
2522 }
2523
2524 if (s.version() >= QDataStream::Qt_4_0) {
2525 // 4.0
2526 double pointSize = font.d->request.pointSize;
2527 qint32 pixelSize = font.d->request.pixelSize;
2528 s << pointSize;
2529 s << pixelSize;
2530 } else if (s.version() <= 3) {
2531 qint16 pointSize = (qint16) (font.d->request.pointSize * 10);
2532 if (pointSize < 0) {
2533 pointSize = (qint16)QFontInfo(font).pointSize() * 10;
2534 }
2535 s << pointSize;
2536 } else {
2537 s << (qint16) (font.d->request.pointSize * 10);
2538 s << (qint16) font.d->request.pixelSize;
2539 }
2540
2541 s << (quint8) font.d->request.styleHint;
2542 if (s.version() >= QDataStream::Qt_3_1) {
2543 // Continue writing 8 bits for versions < 5.4 so that we don't write too much,
2544 // even though we need 16 to store styleStrategy, so there is some data loss.
2545 if (s.version() >= QDataStream::Qt_5_4)
2547 else
2549 }
2550
2551 if (s.version() < QDataStream::Qt_6_0)
2553 else
2554 s << quint16(font.d->request.weight);
2555
2556 s << get_font_bits(s.version(), font.d.data());
2557 if (s.version() >= QDataStream::Qt_4_3)
2558 s << (quint16)font.d->request.stretch;
2559 if (s.version() >= QDataStream::Qt_4_4)
2561 if (s.version() >= QDataStream::Qt_4_5) {
2562 s << font.d->letterSpacing.value();
2563 s << font.d->wordSpacing.value();
2564 }
2565 if (s.version() >= QDataStream::Qt_5_4)
2567 if (s.version() >= QDataStream::Qt_5_6)
2568 s << (quint8)font.d->capital;
2569 if (s.version() >= QDataStream::Qt_5_13) {
2570 if (s.version() < QDataStream::Qt_6_0)
2571 s << font.d->request.families.mid(1);
2572 else
2573 s << font.d->request.families;
2574 }
2575 if (s.version() >= QDataStream::Qt_6_6)
2576 s << font.d->features;
2577 return s;
2578}
2579
2580
2590{
2591 font.d = new QFontPrivate;
2592 font.resolve_mask = QFont::AllPropertiesResolved;
2593
2594 quint8 styleHint, bits;
2595 quint16 styleStrategy = QFont::PreferDefault;
2596
2597 if (s.version() == 1) {
2598 QByteArray fam;
2599 s >> fam;
2601 } else {
2602 QString fam;
2603 s >> fam;
2604 font.d->request.families = QStringList(fam);
2605 if (s.version() >= QDataStream::Qt_5_4)
2606 s >> font.d->request.styleName;
2607 }
2608
2609 if (s.version() >= QDataStream::Qt_4_0) {
2610 // 4.0
2611 double pointSize;
2612 qint32 pixelSize;
2613 s >> pointSize;
2614 s >> pixelSize;
2615 font.d->request.pointSize = qreal(pointSize);
2616 font.d->request.pixelSize = pixelSize;
2617 } else {
2618 qint16 pointSize, pixelSize = -1;
2619 s >> pointSize;
2620 if (s.version() >= 4)
2621 s >> pixelSize;
2622 font.d->request.pointSize = qreal(pointSize / 10.);
2623 font.d->request.pixelSize = pixelSize;
2624 }
2625 s >> styleHint;
2626 if (s.version() >= QDataStream::Qt_3_1) {
2627 if (s.version() >= QDataStream::Qt_5_4) {
2628 s >> styleStrategy;
2629 } else {
2630 quint8 tempStyleStrategy;
2631 s >> tempStyleStrategy;
2632 styleStrategy = tempStyleStrategy;
2633 }
2634 }
2635
2636 if (s.version() < QDataStream::Qt_6_0) {
2637 quint8 charSet;
2638 quint8 weight;
2639 s >> charSet;
2640 s >> weight;
2642 } else {
2644 s >> weight;
2646 }
2647
2648 s >> bits;
2649
2650 font.d->request.styleHint = styleHint;
2651 font.d->request.styleStrategy = styleStrategy;
2652
2653 set_font_bits(s.version(), bits, font.d.data());
2654
2655 if (s.version() >= QDataStream::Qt_4_3) {
2656 quint16 stretch;
2657 s >> stretch;
2658 font.d->request.stretch = stretch;
2659 }
2660
2661 if (s.version() >= QDataStream::Qt_4_4) {
2662 quint8 extendedBits;
2663 s >> extendedBits;
2664 set_extended_font_bits(extendedBits, font.d.data());
2665 }
2666 if (s.version() >= QDataStream::Qt_4_5) {
2667 int value;
2668 s >> value;
2670 s >> value;
2672 }
2673 if (s.version() >= QDataStream::Qt_5_4) {
2674 quint8 value;
2675 s >> value;
2677 }
2678 if (s.version() >= QDataStream::Qt_5_6) {
2679 quint8 value;
2680 s >> value;
2682 }
2683 if (s.version() >= QDataStream::Qt_5_13) {
2685 s >> value;
2686 if (s.version() < QDataStream::Qt_6_0)
2687 font.d->request.families.append(value);
2688 else
2690 }
2691 if (s.version() >= QDataStream::Qt_6_6) {
2692 font.d->features.clear();
2693 s >> font.d->features;
2694 }
2695
2696 return s;
2697}
2698
2699#endif // QT_NO_DATASTREAM
2700
2701
2702/*****************************************************************************
2703 QFontInfo member functions
2704 *****************************************************************************/
2705
2767 : d(font.d)
2768{
2769}
2770
2775 : d(fi.d)
2776{
2777}
2778
2783{
2784}
2785
2790{
2791 d = fi.d;
2792 return *this;
2793}
2794
2809{
2811 Q_ASSERT(engine != nullptr);
2812 return engine->fontDef.families.isEmpty() ? QString() : engine->fontDef.families.first();
2813}
2814
2824{
2826 Q_ASSERT(engine != nullptr);
2827 return engine->fontDef.styleName;
2828}
2829
2836{
2838 Q_ASSERT(engine != nullptr);
2839 return qRound(engine->fontDef.pointSize);
2840}
2841
2848{
2850 Q_ASSERT(engine != nullptr);
2851 return engine->fontDef.pointSize;
2852}
2853
2860{
2862 Q_ASSERT(engine != nullptr);
2863 return engine->fontDef.pixelSize;
2864}
2865
2872{
2874 Q_ASSERT(engine != nullptr);
2875 return engine->fontDef.style != QFont::StyleNormal;
2876}
2877
2884{
2886 Q_ASSERT(engine != nullptr);
2887 return (QFont::Style)engine->fontDef.style;
2888}
2889
2890
2891#if QT_DEPRECATED_SINCE(6, 0)
2905int QFontInfo::legacyWeight() const
2906{
2908}
2909#endif // QT_DEPRECATED_SINCE(6, 0)
2910
2911
2918{
2920 Q_ASSERT(engine != nullptr);
2921 return engine->fontDef.weight;
2922
2923}
2924
2945{
2946 return d->underline;
2947}
2948
2960{
2961 return d->overline;
2962}
2963
2973{
2974 return d->strikeOut;
2975}
2976
2983{
2985 Q_ASSERT(engine != nullptr);
2986#ifdef Q_OS_MAC
2987 if (!engine->fontDef.fixedPitchComputed) {
2988 QChar ch[2] = { u'i', u'm' };
2990 int l = 2;
2991 if (!engine->stringToCMap(ch, 2, &g, &l, {}))
2992 Q_UNREACHABLE();
2993 Q_ASSERT(l == 2);
2994 engine->fontDef.fixedPitch = g.advances[0] == g.advances[1];
2995 engine->fontDef.fixedPitchComputed = true;
2996 }
2997#endif
2998 return engine->fontDef.fixedPitch;
2999}
3000
3009{
3011 Q_ASSERT(engine != nullptr);
3012 return (QFont::StyleHint) engine->fontDef.styleHint;
3013}
3014
3022{
3024 Q_ASSERT(engine != nullptr);
3025 return d->request.exactMatch(engine->fontDef);
3026}
3027
3028
3029
3030
3031// **********************************************************************
3032// QFontCache
3033// **********************************************************************
3034
3035using namespace std::chrono_literals;
3036
3037#ifdef QFONTCACHE_DEBUG
3038// fast timeouts for debugging
3039static constexpr auto fast_timeout = 1s;
3040static constexpr auto slow_timeout = 5s;
3041#else
3042static constexpr auto fast_timeout = 10s;
3043static constexpr auto slow_timeout = 5min;
3044#endif // QFONTCACHE_DEBUG
3045
3046#ifndef QFONTCACHE_MIN_COST
3047# define QFONTCACHE_MIN_COST 4*1024 // 4mb
3048#endif
3049const uint QFontCache::min_cost = QFONTCACHE_MIN_COST;
3051
3053{
3054 QFontCache *&fontCache = theFontCache()->localData();
3055 if (!fontCache)
3056 fontCache = new QFontCache;
3057 return fontCache;
3058}
3059
3061{
3063 QT_TRY {
3064 cache = theFontCache();
3065 } QT_CATCH (const std::bad_alloc &) {
3066 // no cache - just ignore
3067 }
3068 if (cache && cache->hasLocalData())
3069 cache->setLocalData(nullptr);
3070}
3071
3073
3075 : QObject(), total_cost(0), max_cost(min_cost),
3076 current_timestamp(0), fast(false),
3077 autoClean(QGuiApplication::instance()
3078 && (QGuiApplication::instance()->thread() == QThread::currentThread())),
3079 timer_id(-1),
3080 m_id(font_cache_id.fetchAndAddRelaxed(1) + 1)
3081{
3082}
3083
3085{
3086 clear();
3087}
3088
3090{
3091 {
3094 while (it != end) {
3095 QFontEngineData *data = it.value();
3096 for (int i = 0; i < QChar::ScriptCount; ++i) {
3097 if (data->engines[i]) {
3098 if (!data->engines[i]->ref.deref()) {
3099 Q_ASSERT(engineCacheCount.value(data->engines[i]) == 0);
3100 delete data->engines[i];
3101 }
3102 data->engines[i] = nullptr;
3103 }
3104 }
3105 if (!data->ref.deref()) {
3106 delete data;
3107 } else {
3108 FC_DEBUG("QFontCache::clear: engineData %p still has refcount %d",
3109 data, data->ref.loadRelaxed());
3110 }
3111 ++it;
3112 }
3113 }
3114
3116
3117
3118 bool mightHaveEnginesLeftForCleanup;
3119 do {
3120 mightHaveEnginesLeftForCleanup = false;
3122 it != end; ++it) {
3123 QFontEngine *engine = it.value().data;
3124 if (engine) {
3125 const int cacheCount = --engineCacheCount[engine];
3126 Q_ASSERT(cacheCount >= 0);
3127 if (!engine->ref.deref()) {
3128 Q_ASSERT(cacheCount == 0);
3129 mightHaveEnginesLeftForCleanup = engine->type() == QFontEngine::Multi;
3130 delete engine;
3131 } else if (cacheCount == 0) {
3132 FC_DEBUG("QFontCache::clear: engine %p still has refcount %d",
3133 engine, engine->ref.loadRelaxed());
3134 }
3135 it.value().data = nullptr;
3136 }
3137 }
3138 } while (mightHaveEnginesLeftForCleanup);
3139
3142
3143
3144 total_cost = 0;
3145 max_cost = min_cost;
3146}
3147
3148
3150{
3152 if (it == engineDataCache.constEnd())
3153 return nullptr;
3154
3155 // found
3156 return it.value();
3157}
3158
3160{
3161#ifdef QFONTCACHE_DEBUG
3162 FC_DEBUG("QFontCache: inserting new engine data %p", engineData);
3163 if (engineDataCache.contains(def)) {
3164 FC_DEBUG(" QFontCache already contains engine data %p for key=(%g %g %d %d %d)",
3166 def.pixelSize, def.weight, def.style, def.fixedPitch);
3167 }
3168#endif
3170
3171 engineData->ref.ref();
3172 // Decrease now rather than waiting
3173 if (total_cost > min_cost * 2 && engineDataCache.size() >= QFONTCACHE_DECREASE_TRIGGER_LIMIT)
3174 decreaseCache();
3175
3176 engineDataCache.insert(def, engineData);
3177 increaseCost(sizeof(QFontEngineData));
3178}
3179
3181{
3183 end = engineCache.end();
3184 if (it == end) return nullptr;
3185
3186 Q_ASSERT(it.value().data != nullptr);
3187 Q_ASSERT(key.multi == (it.value().data->type() == QFontEngine::Multi));
3188
3189 // found... update the hitcount and timestamp
3191
3192 return it.value().data;
3193}
3194
3196{
3197 value.hits++;
3198 value.timestamp = ++current_timestamp;
3199
3200 FC_DEBUG("QFontCache: found font engine\n"
3201 " %p: timestamp %4u hits %3u ref %2d/%2d, type %d",
3202 value.data, value.timestamp, value.hits,
3203 value.data->ref.loadRelaxed(), engineCacheCount.value(value.data),
3204 value.data->type());
3205}
3206
3207void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti)
3208{
3209 Q_ASSERT(engine != nullptr);
3210 Q_ASSERT(key.multi == (engine->type() == QFontEngine::Multi));
3211
3212#ifdef QFONTCACHE_DEBUG
3213 FC_DEBUG("QFontCache: inserting new engine %p, refcount %d", engine, engine->ref.loadRelaxed());
3214 if (!insertMulti && engineCache.contains(key)) {
3215 FC_DEBUG(" QFontCache already contains engine %p for key=(%g %g %d %d %d)",
3216 engineCache.value(key).data, key.def.pointSize,
3217 key.def.pixelSize, key.def.weight, key.def.style, key.def.fixedPitch);
3218 }
3219#endif
3220 engine->ref.ref();
3221 // Decrease now rather than waiting
3222 if (total_cost > min_cost * 2 && engineCache.size() >= QFONTCACHE_DECREASE_TRIGGER_LIMIT)
3223 decreaseCache();
3224
3226 data.timestamp = ++current_timestamp;
3227
3228 if (insertMulti)
3230 else
3232 // only increase the cost if this is the first time we insert the engine
3233 if (++engineCacheCount[engine] == 1)
3234 increaseCost(engine->cache_cost);
3235}
3236
3237void QFontCache::increaseCost(uint cost)
3238{
3239 cost = (cost + 512) / 1024; // store cost in kb
3240 cost = cost > 0 ? cost : 1;
3241 total_cost += cost;
3242
3243 FC_DEBUG(" COST: increased %u kb, total_cost %u kb, max_cost %u kb",
3244 cost, total_cost, max_cost);
3245
3246 if (total_cost > max_cost) {
3247 max_cost = total_cost;
3248
3249 if (!autoClean)
3250 return;
3251
3252 if (timer_id == -1 || ! fast) {
3253 FC_DEBUG(" TIMER: starting fast timer (%d s)", static_cast<int>(fast_timeout.count()));
3254
3255 if (timer_id != -1)
3256 killTimer(timer_id);
3257 timer_id = startTimer(fast_timeout);
3258 fast = true;
3259 }
3260 }
3261}
3262
3263void QFontCache::decreaseCost(uint cost)
3264{
3265 cost = (cost + 512) / 1024; // cost is stored in kb
3266 cost = cost > 0 ? cost : 1;
3267 Q_ASSERT(cost <= total_cost);
3268 total_cost -= cost;
3269
3270 FC_DEBUG(" COST: decreased %u kb, total_cost %u kb, max_cost %u kb",
3271 cost, total_cost, max_cost);
3272}
3273
3275{
3276 FC_DEBUG("QFontCache::timerEvent: performing cache maintenance (timestamp %u)",
3277 current_timestamp);
3278
3279 if (total_cost <= max_cost && max_cost <= min_cost) {
3280 FC_DEBUG(" cache redused sufficiently, stopping timer");
3281
3282 killTimer(timer_id);
3283 timer_id = -1;
3284 fast = false;
3285
3286 return;
3287 }
3288 decreaseCache();
3289}
3290
3291void QFontCache::decreaseCache()
3292{
3293 // go through the cache and count up everything in use
3294 uint in_use_cost = 0;
3295
3296 {
3297 FC_DEBUG(" SWEEP engine data:");
3298
3299 // make sure the cost of each engine data is at least 1kb
3300 const uint engine_data_cost =
3301 sizeof(QFontEngineData) > 1024 ? sizeof(QFontEngineData) : 1024;
3302
3305 for (; it != end; ++it) {
3306 FC_DEBUG(" %p: ref %2d", it.value(), int(it.value()->ref.loadRelaxed()));
3307
3308 if (it.value()->ref.loadRelaxed() != 1)
3309 in_use_cost += engine_data_cost;
3310 }
3311 }
3312
3313 {
3314 FC_DEBUG(" SWEEP engine:");
3315
3318 for (; it != end; ++it) {
3319 FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, cost %u bytes",
3320 it.value().data, it.value().timestamp, it.value().hits,
3321 it.value().data->ref.loadRelaxed(), engineCacheCount.value(it.value().data),
3322 it.value().data->cache_cost);
3323
3324 if (it.value().data->ref.loadRelaxed() > engineCacheCount.value(it.value().data))
3325 in_use_cost += it.value().data->cache_cost / engineCacheCount.value(it.value().data);
3326 }
3327
3328 // attempt to make up for rounding errors
3329 in_use_cost += engineCache.size();
3330 }
3331
3332 in_use_cost = (in_use_cost + 512) / 1024; // cost is stored in kb
3333
3334 /*
3335 calculate the new maximum cost for the cache
3336
3337 NOTE: in_use_cost is *not* correct due to rounding errors in the
3338 above algorithm. instead of worrying about getting the
3339 calculation correct, we are more interested in speed, and use
3340 in_use_cost as a floor for new_max_cost
3341 */
3342 uint new_max_cost = qMax(qMax(max_cost / 2, in_use_cost), min_cost);
3343
3344 FC_DEBUG(" after sweep, in use %u kb, total %u kb, max %u kb, new max %u kb",
3345 in_use_cost, total_cost, max_cost, new_max_cost);
3346
3347 if (autoClean) {
3348 if (new_max_cost == max_cost) {
3349 if (fast) {
3350 FC_DEBUG(" cannot shrink cache, slowing timer");
3351
3352 if (timer_id != -1) {
3353 killTimer(timer_id);
3354 timer_id = startTimer(slow_timeout);
3355 fast = false;
3356 }
3357
3358 return;
3359 } else if (! fast) {
3360 FC_DEBUG(" dropping into passing gear");
3361
3362 if (timer_id != -1)
3363 killTimer(timer_id);
3364 timer_id = startTimer(fast_timeout);
3365 fast = true; }
3366 }
3367 }
3368
3369 max_cost = new_max_cost;
3370
3371 {
3372 FC_DEBUG(" CLEAN engine data:");
3373
3374 // clean out all unused engine data
3376 while (it != engineDataCache.end()) {
3377 if (it.value()->ref.loadRelaxed() == 1) {
3378 FC_DEBUG(" %p", it.value());
3379 decreaseCost(sizeof(QFontEngineData));
3380 it.value()->ref.deref();
3381 delete it.value();
3383 } else {
3384 ++it;
3385 }
3386 }
3387 }
3388
3389 FC_DEBUG(" CLEAN engine:");
3390
3391 // clean out the engine cache just enough to get below our new max cost
3392 bool cost_decreased;
3393 do {
3394 cost_decreased = false;
3395
3397 end = engineCache.end();
3398 // determine the oldest and least popular of the unused engines
3399 uint oldest = ~0u;
3400 uint least_popular = ~0u;
3401
3403
3404 for ( ; it != end; ++it) {
3405 if (it.value().data->ref.loadRelaxed() != engineCacheCount.value(it.value().data))
3406 continue;
3407
3408 if (it.value().timestamp < oldest && it.value().hits <= least_popular) {
3409 oldest = it.value().timestamp;
3410 least_popular = it.value().hits;
3411 jt = it;
3412 }
3413 }
3414
3415 it = jt;
3416 if (it != end) {
3417 FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, type %d",
3418 it.value().data, it.value().timestamp, it.value().hits,
3419 it.value().data->ref.loadRelaxed(), engineCacheCount.value(it.value().data),
3420 it.value().data->type());
3421
3422 QFontEngine *fontEngine = it.value().data;
3423 // get rid of all occurrences
3424 it = engineCache.begin();
3425 while (it != engineCache.end()) {
3426 if (it.value().data == fontEngine) {
3427 fontEngine->ref.deref();
3429 } else {
3430 ++it;
3431 }
3432 }
3433 // and delete the last occurrence
3434 Q_ASSERT(fontEngine->ref.loadRelaxed() == 0);
3435 decreaseCost(fontEngine->cache_cost);
3436 delete fontEngine;
3437 engineCacheCount.remove(fontEngine);
3438
3439 cost_decreased = true;
3440 }
3441 } while (cost_decreased && total_cost > max_cost);
3442}
3443
3444
3445#ifndef QT_NO_DEBUG_STREAM
3447{
3448 QDebugStateSaver saver(stream);
3449 stream.nospace().noquote();
3450 stream << "QFont(";
3451
3452 if (stream.verbosity() == QDebug::DefaultVerbosity) {
3453 stream << font.toString() << ")";
3454 return stream;
3455 }
3456
3457 QString fontDescription;
3458 QDebug debug(&fontDescription);
3459 debug.nospace();
3460
3461 const QFont defaultFont(new QFontPrivate);
3462
3463 for (int property = QFont::SizeResolved; property < QFont::AllPropertiesResolved; property <<= 1) {
3464 const bool resolved = (font.resolve_mask & property) != 0;
3465 if (!resolved && stream.verbosity() == QDebug::MinimumVerbosity)
3466 continue;
3467
3468 #define QFONT_DEBUG_SKIP_DEFAULT(prop) \
3469 if ((font.prop() == defaultFont.prop()) && stream.verbosity() == 1) \
3470 continue;
3471
3472 QDebugStateSaver saver(debug);
3473
3474 switch (property) {
3476 if (font.pointSizeF() >= 0)
3477 debug << font.pointSizeF() << "pt";
3478 else if (font.pixelSize() >= 0)
3479 debug << font.pixelSize() << "px";
3480 else
3481 Q_UNREACHABLE();
3482 break;
3484 QFONT_DEBUG_SKIP_DEFAULT(styleHint);
3485 debug.verbosity(1) << font.styleHint(); break;
3487 QFONT_DEBUG_SKIP_DEFAULT(styleStrategy);
3488 debug.verbosity(1) << font.styleStrategy(); break;
3490 debug.verbosity(1) << QFont::Weight(font.weight()); break;
3493 debug.verbosity(0) << font.style(); break;
3495 QFONT_DEBUG_SKIP_DEFAULT(underline);
3496 debug << "underline=" << font.underline(); break;
3498 QFONT_DEBUG_SKIP_DEFAULT(overline);
3499 debug << "overline=" << font.overline(); break;
3501 QFONT_DEBUG_SKIP_DEFAULT(strikeOut);
3502 debug << "strikeOut=" << font.strikeOut(); break;
3504 QFONT_DEBUG_SKIP_DEFAULT(fixedPitch);
3505 debug << "fixedPitch=" << font.fixedPitch(); break;
3507 QFONT_DEBUG_SKIP_DEFAULT(stretch);
3508 debug.verbosity(0) << QFont::Stretch(font.stretch()); break;
3511 debug << "kerning=" << font.kerning(); break;
3513 QFONT_DEBUG_SKIP_DEFAULT(capitalization);
3514 debug.verbosity(0) << font.capitalization(); break;
3516 QFONT_DEBUG_SKIP_DEFAULT(letterSpacing);
3517 debug << "letterSpacing=" << font.letterSpacing();
3518 debug.verbosity(0) << " (" << font.letterSpacingType() << ")";
3519 break;
3521 QFONT_DEBUG_SKIP_DEFAULT(hintingPreference);
3522 debug.verbosity(0) << font.hintingPreference(); break;
3524 QFONT_DEBUG_SKIP_DEFAULT(styleName);
3525 debug << "styleName=" << font.styleName(); break;
3526 default:
3527 continue;
3528 };
3529
3530 #undef QFONT_DEBUG_SKIP_DEFAULT
3531
3532 debug << ", ";
3533 }
3534
3535 if (stream.verbosity() > QDebug::MinimumVerbosity)
3536 debug.verbosity(0) << "resolveMask=" << QFlags<QFont::ResolveProperties>(font.resolve_mask);
3537 else
3538 fontDescription.chop(2); // Last ', '
3539
3540 stream << fontDescription << ')';
3541
3542 return stream;
3543}
3544#endif
3545
3547
3548#include "moc_qfont.cpp"
bool ref() noexcept
bool deref() noexcept
T loadRelaxed() const noexcept
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:534
\inmodule QtCore
Definition qchar.h:48
Script
Definition qchar.h:144
@ ScriptCount
Definition qchar.h:341
@ Script_Common
Definition qchar.h:147
@ Script_Latin
Definition qchar.h:149
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
\inmodule QtCore\reentrant
Definition qdatastream.h:30
\inmodule QtCore
\inmodule QtCore
void detach()
If the shared data object's reference count is greater than 1, this function creates a deep copy of t...
T * data() const noexcept
Returns a pointer to the shared data object.
static void cleanup()
Definition qfont.cpp:3060
void insertEngineData(const QFontDef &def, QFontEngineData *engineData)
Definition qfont.cpp:3159
EngineDataCache engineDataCache
Definition qfont_p.h:232
void clear()
Definition qfont.cpp:3089
QFontEngine * findEngine(const Key &key)
Definition qfont.cpp:3180
QFontEngineData * findEngineData(const QFontDef &def) const
Definition qfont.cpp:3149
EngineCache engineCache
Definition qfont_p.h:248
void timerEvent(QTimerEvent *event) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
Definition qfont.cpp:3274
static QFontCache * instance()
Definition qfont.cpp:3052
void updateHitCountAndTimeStamp(Engine &value)
Definition qfont.cpp:3195
int id() const
Definition qfont_p.h:200
void insertEngine(const Key &key, QFontEngine *engine, bool insertMulti=false)
Definition qfont.cpp:3207
QHash< QFontEngine *, int > engineCacheCount
Definition qfont_p.h:249
static void parseFontName(const QString &name, QString &foundry, QString &family)
static void load(const QFontPrivate *d, int script)
QAtomicInt ref
Definition qfont_p.h:132
QFontEngine * engines[QChar::ScriptCount]
Definition qfont_p.h:135
const int fontCacheId
Definition qfont_p.h:133
QAtomicInt ref
\reentrant
Definition qfontinfo.h:14
qreal pointSizeF() const
Returns the point size of the matched window system font.
Definition qfont.cpp:2847
int pointSize() const
Returns the point size of the matched window system font.
Definition qfont.cpp:2835
int pixelSize() const
Returns the pixel size of the matched window system font.
Definition qfont.cpp:2859
QString family() const
Returns the family name of the matched window system font.
Definition qfont.cpp:2808
bool italic() const
Returns the italic value of the matched window system font.
Definition qfont.cpp:2871
QFontInfo & operator=(const QFontInfo &)
Assigns the font info in fi.
Definition qfont.cpp:2789
QString styleName() const
Definition qfont.cpp:2823
bool fixedPitch() const
Returns the fixed pitch value of the matched window system font.
Definition qfont.cpp:2982
QFontInfo(const QFont &)
Constructs a font info object for font.
Definition qfont.cpp:2766
QFont::StyleHint styleHint() const
Returns the style of the matched window system font.
Definition qfont.cpp:3008
bool strikeOut() const
Returns the strikeout value of the matched window system font.
Definition qfont.cpp:2972
bool overline() const
Returns the overline value of the matched window system font.
Definition qfont.cpp:2959
QFont::Style style() const
Returns the style value of the matched window system font.
Definition qfont.cpp:2883
int weight() const
Returns the weight of the matched window system font.
Definition qfont.cpp:2917
~QFontInfo()
Destroys the font info object.
Definition qfont.cpp:2782
bool exactMatch() const
Returns true if the matched window system font is exactly the same as the one specified by the font; ...
Definition qfont.cpp:3021
bool underline() const
Returns the underline value of the matched window system font.
Definition qfont.cpp:2944
bool letterSpacingIsAbsolute
Definition qfont_p.h:163
uint overline
Definition qfont_p.h:159
uint strikeOut
Definition qfont_p.h:160
QAtomicInt ref
Definition qfont_p.h:153
QFontDef request
Definition qfont_p.h:154
static QFontPrivate * get(const QFont &font)
Definition qfont_p.h:173
QHash< quint32, quint32 > features
Definition qfont_p.h:167
QFontPrivate * smallCapsFontPrivate() const
Definition qfont.cpp:268
void setFeature(quint32 tag, quint32 value)
Definition qfont.cpp:351
uint underline
Definition qfont_p.h:158
QFontEngine * engineForScript(int script) const
Definition qfont.cpp:238
QFixed wordSpacing
Definition qfont_p.h:166
uint kerning
Definition qfont_p.h:161
QFixed letterSpacing
Definition qfont_p.h:165
void resolve(uint mask, const QFontPrivate *other)
Definition qfont.cpp:285
void unsetFeature(quint32 tag)
Definition qfont.cpp:356
QFontEngineData * engineData
Definition qfont_p.h:155
uint capital
Definition qfont_p.h:162
QFontPrivate * scFont
Definition qfont_p.h:169
void alterCharForCapitalization(QChar &c) const
Definition qfont.cpp:254
static void detachButKeepEngineData(QFont *font)
Definition qfont.cpp:647
\reentrant
Definition qfont.h:20
static QStringList substitutes(const QString &)
Returns a list of family names to be used whenever familyName is specified.
Definition qfont.cpp:1919
static QByteArray tagToString(quint32 tag)
Definition qfont.cpp:2409
StyleHint
Style hints are used by the \l{QFont}{font matching} algorithm to find an appropriate default family ...
Definition qfont.h:23
void setStyle(Style style)
Sets the style of the font to style.
Definition qfont.cpp:1101
QString family() const
Returns the requested font family name.
Definition qfont.cpp:796
static void initialize()
Definition qfont.cpp:2211
StyleStrategy styleStrategy() const
Returns the StyleStrategy.
Definition qfont.cpp:1379
void setPointSize(int)
Sets the point size to pointSize.
Definition qfont.cpp:970
static void cacheStatistics()
Definition qfont.cpp:2229
void setOverline(bool)
If enable is true, sets overline on; otherwise sets overline off.
Definition qfont.cpp:1273
QString styleName() const
Definition qfont.cpp:828
void setStrikeOut(bool)
If enable is true, sets strikeout on; otherwise sets strikeout off.
Definition qfont.cpp:1300
void clearFeatures()
Definition qfont.cpp:2395
static void cleanup()
Definition qfont.cpp:2220
QList< quint32 > featureTags() const
Definition qfont.cpp:2351
bool isCopyOf(const QFont &) const
Returns true if this font and f are copies of each other, i.e.
Definition qfont.cpp:1845
int pixelSize() const
Returns the pixel size of the font if it was set with setPixelSize().
Definition qfont.cpp:1059
bool italic() const
Returns true if the style() of the font is not QFont::StyleNormal.
Definition qfont.h:315
QFont()
Constructs a font object that uses the application's default font.
Definition qfont.cpp:664
friend class QFontPrivate
Definition qfont.h:265
StyleHint styleHint() const
Returns the StyleHint.
Definition qfont.cpp:1392
bool fromString(const QString &)
Sets this font to match the description descrip.
Definition qfont.cpp:2151
bool strikeOut() const
Returns true if strikeout has been set; otherwise returns false.
Definition qfont.cpp:1289
size_t qHash(const QFont &font, size_t seed) noexcept
Returns the hash value for font.
Definition qfont.cpp:2138
bool underline() const
Returns true if underline has been set; otherwise returns false.
Definition qfont.cpp:1236
Capitalization
Definition qfont.h:94
@ AllLowercase
Definition qfont.h:97
@ AllUppercase
Definition qfont.h:96
@ MixedCase
Definition qfont.h:95
@ SmallCaps
Definition qfont.h:98
void setFamilies(const QStringList &)
Definition qfont.cpp:2491
bool operator!=(const QFont &) const
Returns true if this font is different from f; otherwise returns false.
Definition qfont.cpp:1825
void setCapitalization(Capitalization)
Definition qfont.cpp:1702
QString toString() const
Returns a description of the font.
Definition qfont.cpp:2104
qreal letterSpacing() const
Definition qfont.cpp:1598
bool isFeatureSet(quint32 tag) const
Definition qfont.cpp:2381
void setWordSpacing(qreal spacing)
Definition qfont.cpp:1667
void setFixedPitch(bool)
If enable is true, sets fixed pitch on; otherwise sets fixed pitch off.
Definition qfont.cpp:1327
void setFamily(const QString &)
Sets the family name of the font.
Definition qfont.cpp:814
void setStyleStrategy(StyleStrategy s)
Sets the style strategy for the font to s.
Definition qfont.cpp:1503
bool exactMatch() const
Returns true if a window system font exactly matching the settings of this font is available.
Definition qfont.cpp:1731
QFont resolve(const QFont &) const
Returns a new QFont that has attributes copied from other that have not been previously set on this f...
Definition qfont.cpp:1854
static void insertSubstitution(const QString &, const QString &)
Inserts substituteName into the substitution table for the family familyName.
Definition qfont.cpp:1936
HintingPreference hintingPreference() const
Definition qfont.cpp:959
SpacingType
Definition qfont.h:103
@ AbsoluteSpacing
Definition qfont.h:105
@ PercentageSpacing
Definition qfont.h:104
bool operator<(const QFont &) const
Provides an arbitrary comparison of this font and font f.
Definition qfont.cpp:1776
Capitalization capitalization() const
Definition qfont.cpp:1720
static void removeSubstitutions(const QString &)
Removes all the substitutions for familyName.
Definition qfont.cpp:1977
QStringList families() const
Definition qfont.cpp:2469
Weight weight() const
Returns the weight of the font, using the same scale as the \l{QFont::Weight} enumeration.
Definition qfont.cpp:1118
@ StretchResolved
Definition qfont.h:121
@ LetterSpacingResolved
Definition qfont.h:124
@ SizeResolved
Definition qfont.h:112
@ OverlineResolved
Definition qfont.h:118
@ UnderlineResolved
Definition qfont.h:117
@ StyleHintResolved
Definition qfont.h:113
@ StyleNameResolved
Definition qfont.h:127
@ AllPropertiesResolved
Definition qfont.h:130
@ StrikeOutResolved
Definition qfont.h:119
@ KerningResolved
Definition qfont.h:122
@ FeaturesResolved
Definition qfont.h:129
@ WeightResolved
Definition qfont.h:115
@ CapitalizationResolved
Definition qfont.h:123
@ HintingPreferenceResolved
Definition qfont.h:126
@ FixedPitchResolved
Definition qfont.h:120
@ WordSpacingResolved
Definition qfont.h:125
@ StyleStrategyResolved
Definition qfont.h:114
@ StyleResolved
Definition qfont.h:116
@ FamiliesResolved
Definition qfont.h:128
void setLetterSpacing(SpacingType type, qreal spacing)
Definition qfont.cpp:1615
qreal wordSpacing() const
Definition qfont.cpp:1648
int pointSize() const
Returns the point size of the font.
Definition qfont.cpp:863
void setKerning(bool)
Enables kerning for this font if enable is true; otherwise disables it.
Definition qfont.cpp:1360
int stretch() const
Returns the stretch factor for the font.
Definition qfont.cpp:1541
static QStringList substitutions()
Returns a sorted list of substituted family names.
Definition qfont.cpp:1989
bool kerning() const
Returns true if kerning should be used when drawing text with this font.
Definition qfont.cpp:1344
QString defaultFamily() const
Returns the family name that corresponds to the current style hint.
Definition qfont.cpp:2450
QString key() const
Returns the font's key, a textual representation of a font.
Definition qfont.cpp:2073
void setPixelSize(int)
Sets the font size to pixelSize pixels, with a maxiumum size of an unsigned 16-bit integer.
Definition qfont.cpp:1034
bool operator==(const QFont &) const
Returns true if this font is equal to f; otherwise returns false.
Definition qfont.cpp:1747
void setHintingPreference(HintingPreference hintingPreference)
Definition qfont.cpp:942
void setItalic(bool b)
Sets the style() of the font to QFont::StyleItalic if enable is true; otherwise the style is set to Q...
Definition qfont.h:320
bool fixedPitch() const
Returns true if fixed pitch has been set; otherwise returns false.
Definition qfont.cpp:1316
void setUnderline(bool)
If enable is true, sets underline on; otherwise sets underline off.
Definition qfont.cpp:1247
void setStyleHint(StyleHint, StyleStrategy=PreferDefault)
Sets the style hint and strategy to hint and strategy, respectively.
Definition qfont.cpp:1482
HintingPreference
Definition qfont.h:52
QFont & operator=(const QFont &)
Move-assigns other to this QFont instance.
Definition qfont.cpp:775
qreal pointSizeF() const
Returns the point size of the font.
Definition qfont.cpp:1019
void setStyleName(const QString &)
Definition qfont.cpp:846
void setStretch(int)
Sets the stretch factor for the font.
Definition qfont.cpp:1565
SpacingType letterSpacingType() const
Definition qfont.cpp:1637
quint32 featureValue(quint32 tag) const
Definition qfont.cpp:2366
Stretch
Predefined stretch values that follow the CSS naming convention.
Definition qfont.h:80
Style style() const
Returns the style of the font.
Definition qfont.cpp:1090
void setFeature(const char *feature, quint32 value)
Definition qfont.cpp:2291
StyleStrategy
The style strategy tells the \l{QFont}{font matching} algorithm what type of fonts should be used to ...
Definition qfont.h:36
@ PreferDefault
Definition qfont.h:37
void setPointSizeF(qreal)
Sets the point size to pointSize.
Definition qfont.cpp:995
static quint32 stringToTag(const char *tagString)
Definition qfont.cpp:2431
Weight
Qt uses a weighting scale from 1 to 1000 compatible with OpenType.
Definition qfont.h:60
@ DemiBold
Definition qfont.h:66
@ Thin
Definition qfont.h:61
@ ExtraBold
Definition qfont.h:68
@ Black
Definition qfont.h:69
@ Bold
Definition qfont.h:67
@ ExtraLight
Definition qfont.h:62
@ Normal
Definition qfont.h:64
@ Light
Definition qfont.h:63
@ Medium
Definition qfont.h:65
void unsetFeature(quint32 tag)
Definition qfont.cpp:2311
void setWeight(Weight weight)
Sets the weight of the font to weight, using the scale defined by \l QFont::Weight enumeration.
Definition qfont.cpp:1190
bool overline() const
Returns true if overline has been set; otherwise returns false.
Definition qfont.cpp:1263
~QFont()
Destroys the font object and frees all allocated resources.
Definition qfont.cpp:768
Style
This enum describes the different styles of glyphs that are used to display text.
Definition qfont.h:73
@ StyleItalic
Definition qfont.h:75
@ StyleNormal
Definition qfont.h:74
@ StyleOblique
Definition qfont.h:76
static void insertSubstitutions(const QString &, const QStringList &)
Inserts the list of families substituteNames into the substitution list for familyName.
Definition qfont.cpp:1958
\macro qGuiApp
QScreen * primaryScreen
the primary (or default) screen of the application.
\inmodule QtCore
Definition qhash.h:818
bool remove(const Key &key)
Removes the item that has the key from the hash.
Definition qhash.h:956
qsizetype size() const noexcept
Returns the number of items in the hash.
Definition qhash.h:925
const_iterator constFind(const Key &key) const noexcept
Definition qhash.h:1279
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
Definition qhash.h:1209
const_iterator constBegin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
Definition qhash.h:1205
QList< Key > keys() const
Returns a list containing all the keys in the hash, in an arbitrary order.
Definition qhash.h:1076
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
Definition qhash.h:991
T value(const Key &key) const noexcept
Definition qhash.h:1044
const_iterator ConstIterator
Qt-style synonym for QHash::const_iterator.
Definition qhash.h:1256
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
Definition qhash.h:949
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1283
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void append(parameter_type t)
Definition qlist.h:441
iterator insert(const Key &key, const T &value)
Definition qmap.h:687
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:356
iterator erase(const_iterator it)
Definition qmap.h:618
bool contains(const Key &key) const
Definition qmap.h:340
const_iterator constFind(const Key &key) const
Definition qmap.h:654
void clear()
Definition qmap.h:288
iterator begin()
Definition qmap.h:597
iterator end()
Definition qmap.h:601
const_iterator constBegin() const
Definition qmap.h:599
size_type size() const
Definition qmap.h:266
const_iterator constEnd() const
Definition qmap.h:603
iterator replace(const Key &key, const T &value)
Definition qmap.h:1474
const_iterator constEnd() const
Definition qmap.h:1302
bool contains(const Key &key) const
Definition qmap.h:1018
iterator end()
Definition qmap.h:1300
const_iterator ConstIterator
Definition qmap.h:1337
iterator find(const Key &key)
Definition qmap.h:1344
iterator insert(const Key &key, const T &value)
Definition qmap.h:1425
iterator erase(const_iterator it)
Definition qmap.h:1317
size_type size() const
Definition qmap.h:911
const_iterator constBegin() const
Definition qmap.h:1298
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:1039
void clear()
Definition qmap.h:933
iterator begin()
Definition qmap.h:1296
\inmodule QtCore
Definition qmutex.h:317
\inmodule QtCore
Definition qobject.h:90
int startTimer(int interval, Qt::TimerType timerType=Qt::CoarseTimer)
This is an overloaded function that will start a timer of type timerType and a timeout of interval mi...
Definition qobject.cpp:1792
void killTimer(int id)
Kills the timer with timer identifier, id.
Definition qobject.cpp:1872
int logicalDpiY() const
\inmodule QtCore
Definition qmutex.h:313
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
qreal logicalDotsPerInchY
the number of logical dots or pixels per inch in the vertical direction
Definition qscreen.h:57
qreal logicalDotsPerInchX
the number of logical dots or pixels per inch in the horizontal direction
Definition qscreen.h:56
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:76
Q_CORE_EXPORT QList< QStringView > split(QStringView sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the view into substring views wherever sep occurs, and returns the list of those string views.
Definition qstring.cpp:7987
QStringView trimmed() const noexcept
Strips leading and trailing whitespace and returns the result.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QByteArray toLatin1() const &
Definition qstring.h:559
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5299
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6180
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
Definition qstring.cpp:7956
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1107
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
Definition qstring.cpp:5204
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition qstring.cpp:5350
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString toLower() const &
Definition qstring.h:368
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:7822
\inmodule QtCore
\inmodule QtCore
Definition qcoreevent.h:359
\inmodule QtCore
Definition qvariant.h:64
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:531
QString str
[2]
qreal spacing
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
@ AA_Use96Dpi
Definition qnamespace.h:432
#define Q_BASIC_ATOMIC_INITIALIZER(a)
size_t qstrlen(const char *str)
AudioChannelLayoutTag tag
EGLStreamKHR stream
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define QT_CATCH(A)
#define QT_TRY
size_t qHash(const QFileSystemWatcherPathKey &key, size_t seed=0)
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:281
Q_GUI_EXPORT int qt_openTypeToLegacyWeight(int weight)
Definition qfont.cpp:198
static void set_font_bits(int version, quint8 bits, QFontPrivate *f)
Definition qfont.cpp:2044
QRecursiveMutex * qt_fontdatabase_mutex()
static int convertWeights(int weight, bool inverted)
Definition qfont.cpp:143
Q_GUI_EXPORT int qt_defaultDpiX()
Definition qfont.cpp:107
static QStringList splitIntoFamilies(const QString &family)
Definition qfont.cpp:172
#define FC_DEBUG
Definition qfont.cpp:40
Q_GUI_EXPORT int qt_legacyToOpenTypeWeight(int weight)
Definition qfont.cpp:192
Q_GUI_EXPORT int qt_defaultDpi()
Definition qfont.cpp:137
static constexpr auto slow_timeout
Definition qfont.cpp:3043
QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script)
static constexpr auto fast_timeout
Definition qfont.cpp:3042
#define QFONT_DEBUG_SKIP_DEFAULT(prop)
#define QFONTCACHE_MIN_COST
Definition qfont.cpp:3047
#define QT_FONT_ENGINE_FROM_DATA(data, script)
Definition qfont.cpp:236
Q_GUI_EXPORT int qt_defaultDpiY()
Definition qfont.cpp:122
bool qt_is_tty_app
static quint8 get_extended_font_bits(const QFontPrivate *f)
Definition qfont.cpp:2029
QDebug operator<<(QDebug stream, const QFont &font)
Definition qfont.cpp:3446
static Q_CONSTINIT QBasicAtomicInt font_cache_id
Definition qfont.cpp:3072
#define QFONTCACHE_DECREASE_TRIGGER_LIMIT
Definition qfont.cpp:46
QHash< QString, QStringList > QFontSubst
Definition qfont.cpp:1884
static quint8 get_font_bits(int version, const QFontPrivate *f)
Definition qfont.cpp:2004
static void set_extended_font_bits(quint8 bits, QFontPrivate *f)
Definition qfont.cpp:2059
#define QFONT_WEIGHT_MIN
Definition qfont_p.h:33
#define QFONT_WEIGHT_MAX
Definition qfont_p.h:34
static QStringList familyList(const QFontDef &req)
static QFixed kerning(int left, int right, const QFontEngine::KernPair *pairs, int numPairs)
#define MAKE_TAG(ch1, ch2, ch3, ch4)
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:162
return ret
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLuint64 key
GLuint GLuint end
GLenum GLuint id
[7]
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLuint GLuint GLfloat weight
GLenum type
GLboolean enable
GLenum const void GLbitfield fontStyle
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLboolean GLboolean g
GLint ref
GLuint name
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
const GLubyte * c
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
GLenum GLenum GLenum GLenum mapping
static qsizetype cost(const QPixmap &pixmap)
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
QScreen * screen
[1]
Definition main.cpp:29
unsigned int quint32
Definition qtypes.h:45
short qint16
Definition qtypes.h:42
unsigned short quint16
Definition qtypes.h:43
int qint32
Definition qtypes.h:44
unsigned int uint
Definition qtypes.h:29
double qreal
Definition qtypes.h:92
unsigned char quint8
Definition qtypes.h:41
static int toInt(const QChar &qc, int R)
static double toDouble(Value v)
const char property[13]
Definition qwizard.cpp:101
QList< int > list
[14]
std::uniform_real_distribution dist(1, 2.5)
[2]
QFileInfo fi("c:/temp/foo")
[newstuff]
QDataStream & operator>>(QDataStream &in, MyClass &myObj)
QObject::connect nullptr
QRect r1(100, 200, 11, 16)
[0]
QRect r2(QPoint(100, 200), QSize(11, 16))
QSharedPointer< T > other(t)
[5]
QNetworkRequest request(url)
QJSEngine engine
[0]
static constexpr QFixed fromReal(qreal r)
Definition qfixed_p.h:35
constexpr int value() const
Definition qfixed_p.h:38
void setValue(int value)
Definition qfixed_p.h:39
constexpr qreal toReal() const
Definition qfixed_p.h:42
QFontEngine * data
Definition qfont_p.h:242
uint hintingPreference
Definition qfont_p.h:66
uint stretch
Definition qfont_p.h:64
uint style
Definition qfont_p.h:65
uint styleStrategy
Definition qfont_p.h:63
uint fixedPitch
Definition qfont_p.h:70
qreal pixelSize
Definition qfont_p.h:60
uint ignorePitch
Definition qfont_p.h:71
uint weight
Definition qfont_p.h:69
QStringList families
Definition qfont_p.h:54
QString styleName
Definition qfont_p.h:55
bool exactMatch(const QFontDef &other) const
Definition qfont.cpp:49
uint styleHint
Definition qfont_p.h:68
qreal pointSize
Definition qfont_p.h:59
bool contains(const AT &t) const noexcept
Definition qlist.h:44