1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #include "qpaintdevice.h"
45 #include "qfontdatabase.h"
46 #include "qfontmetrics.h"
47 #include "qfontinfo.h"
50 #include "qdatastream.h"
51 #include "qguiapplication.h"
52 #include "qstringlist.h"
56 #include "qthreadstorage.h"
58 #include <private/qunicodetables_p.h>
60 #include <private/qfontengine_p.h>
61 #include <private/qpainter_p.h>
62 #include <private/qtextengine_p.h>
65 #include <qpa/qplatformscreen.h>
66 #include <QtGui/private/qguiapplication_p.h>
68 #include <QtCore/QMutexLocker>
69 #include <QtCore/QMutex>
71 // #define QFONTCACHE_DEBUG
72 #ifdef QFONTCACHE_DEBUG
73 # define FC_DEBUG qDebug
75 # define FC_DEBUG if (false) qDebug
82 bool QFontDef::exactMatch(const QFontDef &other) const
85 QFontDef comparison is more complicated than just simple
86 per-member comparisons.
88 When comparing point/pixel sizes, either point or pixelsize
89 could be -1. in This case we have to compare the non negative
92 This test will fail if the point-sizes differ by 1/2 point or
93 more or they do not round to the same value. We have to do this
94 since our API still uses 'int' point-sizes in the API, but store
95 deci-point-sizes internally.
97 To compare the family members, we need to parse the font names
98 and compare the family/foundry strings separately. This allows
99 us to compare e.g. "Helvetica" and "Helvetica [Adobe]" with
102 if (pixelSize != -1 && other.pixelSize != -1) {
103 if (pixelSize != other.pixelSize)
105 } else if (pointSize != -1 && other.pointSize != -1) {
106 if (pointSize != other.pointSize)
112 if (!ignorePitch && !other.ignorePitch && fixedPitch != other.fixedPitch)
115 if (stretch != 0 && other.stretch != 0 && stretch != other.stretch)
118 QString this_family, this_foundry, other_family, other_foundry;
119 QFontDatabase::parseFontName(family, this_foundry, this_family);
120 QFontDatabase::parseFontName(other.family, other_foundry, other_family);
122 this_family = QFontDatabase::resolveFontFamilyAlias(this_family);
123 other_family = QFontDatabase::resolveFontFamilyAlias(other_family);
125 return (styleHint == other.styleHint
126 && styleStrategy == other.styleStrategy
127 && weight == other.weight
128 && style == other.style
129 && this_family == other_family
130 && (styleName.isEmpty() || other.styleName.isEmpty() || styleName == other.styleName)
131 && (this_foundry.isEmpty()
132 || other_foundry.isEmpty()
133 || this_foundry == other_foundry)
137 extern bool qt_is_gui_used;
139 Q_GUI_EXPORT int qt_defaultDpiX()
141 if (qApp->testAttribute(Qt::AA_Use96Dpi))
147 if (const QScreen *screen = QGuiApplication::primaryScreen())
148 return qRound(screen->logicalDotsPerInchX());
150 //PI has not been initialised, or it is being initialised. Give a default dpi
154 Q_GUI_EXPORT int qt_defaultDpiY()
156 if (qApp->testAttribute(Qt::AA_Use96Dpi))
162 if (const QScreen *screen = QGuiApplication::primaryScreen())
163 return qRound(screen->logicalDotsPerInchY());
165 //PI has not been initialised, or it is being initialised. Give a default dpi
169 Q_GUI_EXPORT int qt_defaultDpi()
171 return qt_defaultDpiY();
174 QFontPrivate::QFontPrivate()
175 : engineData(0), dpi(qt_defaultDpi()), screen(0),
176 rawMode(false), underline(false), overline(false), strikeOut(false), kerning(true),
177 capital(0), letterSpacingIsAbsolute(false), scFont(0)
181 QFontPrivate::QFontPrivate(const QFontPrivate &other)
182 : request(other.request), engineData(0), dpi(other.dpi), screen(other.screen),
183 rawMode(other.rawMode), underline(other.underline), overline(other.overline),
184 strikeOut(other.strikeOut), kerning(other.kerning),
185 capital(other.capital), letterSpacingIsAbsolute(other.letterSpacingIsAbsolute),
186 letterSpacing(other.letterSpacing), wordSpacing(other.wordSpacing),
189 if (scFont && scFont != this)
193 QFontPrivate::~QFontPrivate()
196 engineData->ref.deref();
198 if (scFont && scFont != this)
203 extern QMutex *qt_fontdatabase_mutex();
205 #define QT_FONT_ENGINE_FROM_DATA(data, script) data->engines[script]
207 QFontEngine *QFontPrivate::engineForScript(int script) const
209 QMutexLocker locker(qt_fontdatabase_mutex());
210 if (script >= QUnicodeTables::Inherited)
211 script = QUnicodeTables::Common;
212 if (engineData && engineData->fontCache != QFontCache::instance()) {
213 // throw out engineData that came from a different thread
214 engineData->ref.deref();
217 if (!engineData || !QT_FONT_ENGINE_FROM_DATA(engineData, script))
218 QFontDatabase::load(this, script);
219 return QT_FONT_ENGINE_FROM_DATA(engineData, script);
222 void QFontPrivate::alterCharForCapitalization(QChar &c) const {
224 case QFont::AllUppercase:
225 case QFont::SmallCaps:
228 case QFont::AllLowercase:
231 case QFont::MixedCase:
236 QFontPrivate *QFontPrivate::smallCapsFontPrivate() const
240 QFont font(const_cast<QFontPrivate *>(this));
241 qreal pointSize = font.pointSizeF();
243 font.setPointSizeF(pointSize * .7);
245 font.setPixelSize((font.pixelSize() * 7 + 5) / 10);
246 scFont = font.d.data();
253 void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
255 Q_ASSERT(other != 0);
259 if ((mask & QFont::AllPropertiesResolved) == QFont::AllPropertiesResolved) return;
261 // assign the unset-bits with the set-bits of the other font def
262 if (! (mask & QFont::FamilyResolved))
263 request.family = other->request.family;
265 if (! (mask & QFont::StyleNameResolved))
266 request.styleName = other->request.styleName;
268 if (! (mask & QFont::SizeResolved)) {
269 request.pointSize = other->request.pointSize;
270 request.pixelSize = other->request.pixelSize;
273 if (! (mask & QFont::StyleHintResolved))
274 request.styleHint = other->request.styleHint;
276 if (! (mask & QFont::StyleStrategyResolved))
277 request.styleStrategy = other->request.styleStrategy;
279 if (! (mask & QFont::WeightResolved))
280 request.weight = other->request.weight;
282 if (! (mask & QFont::StyleResolved))
283 request.style = other->request.style;
285 if (! (mask & QFont::FixedPitchResolved))
286 request.fixedPitch = other->request.fixedPitch;
288 if (! (mask & QFont::StretchResolved))
289 request.stretch = other->request.stretch;
291 if (! (mask & QFont::HintingPreferenceResolved))
292 request.hintingPreference = other->request.hintingPreference;
294 if (! (mask & QFont::UnderlineResolved))
295 underline = other->underline;
297 if (! (mask & QFont::OverlineResolved))
298 overline = other->overline;
300 if (! (mask & QFont::StrikeOutResolved))
301 strikeOut = other->strikeOut;
303 if (! (mask & QFont::KerningResolved))
304 kerning = other->kerning;
306 if (! (mask & QFont::LetterSpacingResolved)) {
307 letterSpacing = other->letterSpacing;
308 letterSpacingIsAbsolute = other->letterSpacingIsAbsolute;
310 if (! (mask & QFont::WordSpacingResolved))
311 wordSpacing = other->wordSpacing;
312 if (! (mask & QFont::CapitalizationResolved))
313 capital = other->capital;
319 QFontEngineData::QFontEngineData()
320 : ref(1), fontCache(QFontCache::instance())
322 memset(engines, 0, QUnicodeTables::ScriptCount * sizeof(QFontEngine *));
325 QFontEngineData::~QFontEngineData()
327 for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
329 engines[i]->ref.deref();
341 \brief The QFont class specifies a font used for drawing text.
346 \ingroup richtext-processing
350 When you create a QFont object you specify various attributes that
351 you want the font to have. Qt will use the font with the specified
352 attributes, or if no matching font exists, Qt will use the closest
353 matching installed font. The attributes of the font that is
354 actually used are retrievable from a QFontInfo object. If the
355 window system provides an exact match exactMatch() returns true.
356 Use QFontMetrics to get measurements, e.g. the pixel length of a
357 string using QFontMetrics::width().
359 Note that a QGuiApplication instance must exist before a QFont can be
360 used. You can set the application's default font with
361 QGuiApplication::setFont().
363 If a chosen font does not include all the characters that
364 need to be displayed, QFont will try to find the characters in the
365 nearest equivalent fonts. When a QPainter draws a character from a
366 font the QFont will report whether or not it has the character; if
367 it does not, QPainter will draw an unfilled square.
369 Create QFonts like this:
371 \snippet code/src_gui_text_qfont.cpp 0
373 The attributes set in the constructor can also be set later, e.g.
374 setFamily(), setPointSize(), setPointSizeFloat(), setWeight() and
375 setItalic(). The remaining attributes must be set after
376 contstruction, e.g. setBold(), setUnderline(), setOverline(),
377 setStrikeOut() and setFixedPitch(). QFontInfo objects should be
378 created \e after the font's attributes have been set. A QFontInfo
379 object will not change, even if you change the font's
380 attributes. The corresponding "get" functions, e.g. family(),
381 pointSize(), etc., return the values that were set, even though
382 the values used may differ. The actual values are available from a
385 If the requested font family is unavailable you can influence the
386 \l{#fontmatching}{font matching algorithm} by choosing a
387 particular \l{QFont::StyleHint} and \l{QFont::StyleStrategy} with
388 setStyleHint(). The default family (corresponding to the current
389 style hint) is returned by defaultFamily().
391 The font-matching algorithm has a lastResortFamily() and
392 lastResortFont() in cases where a suitable match cannot be found.
393 You can provide substitutions for font family names using
394 insertSubstitution() and insertSubstitutions(). Substitutions can
395 be removed with removeSubstitutions(). Use substitute() to retrieve
396 a family's first substitute, or the family name itself if it has
397 no substitutes. Use substitutes() to retrieve a list of a family's
398 substitutes (which may be empty).
400 Every QFont has a key() which you can use, for example, as the key
401 in a cache or dictionary. If you want to store a user's font
402 preferences you could use QSettings, writing the font information
403 with toString() and reading it back with fromString(). The
404 operator<<() and operator>>() functions are also available, but
405 they work on a data stream.
407 It is possible to set the height of characters shown on the screen
408 to a specified number of pixels with setPixelSize(); however using
409 setPointSize() has a similar effect and provides device
412 In X11 you can set a font using its system
413 specific name with setRawName().
415 Loading fonts can be expensive, especially on X11. QFont contains
416 extensive optimizations to make the copying of QFont objects fast,
417 and to cache the results of the slow window system functions it
421 The font matching algorithm works as follows:
423 \li The specified font family is searched for.
424 \li If not found, the styleHint() is used to select a replacement
426 \li Each replacement font family is searched for.
427 \li If none of these are found or there was no styleHint(), "helvetica"
428 will be searched for.
429 \li If "helvetica" isn't found Qt will try the lastResortFamily().
430 \li If the lastResortFamily() isn't found Qt will try the
431 lastResortFont() which will always return a name of some kind.
434 Note that the actual font matching algorithm varies from platform to platform.
436 In Windows a request for the "Courier" font is automatically changed to
437 "Courier New", an improved version of Courier that allows for smooth scaling.
438 The older "Courier" bitmap font can be selected by setting the PreferBitmap
439 style strategy (see setStyleStrategy()).
441 Once a font is found, the remaining attributes are matched in order of
445 \li pointSize() (see below)
450 If you have a font which matches on family, even if none of the
451 other attributes match, this font will be chosen in preference to
452 a font which doesn't match on family but which does match on the
453 other attributes. This is because font family is the dominant
456 The point size is defined to match if it is within 20% of the
457 requested point size. When several fonts match and are only
458 distinguished by point size, the font with the closest point size
459 to the one requested will be chosen.
461 The actual family, font size, weight and other font attributes
462 used for drawing text will depend on what's available for the
463 chosen family under the window system. A QFontInfo object can be
464 used to determine the actual values used for drawing the text.
468 \snippet code/src_gui_text_qfont.cpp 1
469 If you had both an Adobe and a Cronyx Helvetica, you might get
472 \snippet code/src_gui_text_qfont.cpp 2
474 You can specify the foundry you want in the family name. The font f
475 in the above example will be set to "Helvetica
478 To determine the attributes of the font actually used in the window
479 system, use a QFontInfo object, e.g.
481 \snippet code/src_gui_text_qfont.cpp 3
483 To find out font metrics use a QFontMetrics object, e.g.
485 \snippet code/src_gui_text_qfont.cpp 4
487 For more general information on fonts, see the
488 \l{comp.fonts FAQ}{comp.fonts FAQ}.
489 Information on encodings can be found from
490 \l{Roman Czyborra's} page.
492 \sa QFontComboBox, QFontMetrics, QFontInfo, QFontDatabase, {Character Map Example}
497 \enum QFont::ResolveProperties
499 This enum describes the properties of a QFont that can be set on a font
500 individually and then considered resolved.
502 \value FamilyResolved
504 \value StyleHintResolved
505 \value StyleStrategyResolved
506 \value WeightResolved
508 \value UnderlineResolved
509 \value OverlineResolved
510 \value StrikeOutResolved
511 \value FixedPitchResolved
512 \value StretchResolved
513 \value KerningResolved
514 \value CapitalizationResolved
515 \value LetterSpacingResolved
516 \value WordSpacingResolved
517 \value CompletelyResolved
523 This enum describes the different styles of glyphs that are used to
526 \value StyleNormal Normal glyphs used in unstyled text.
527 \value StyleItalic Italic glyphs that are specifically designed for
528 the purpose of representing italicized text.
529 \value StyleOblique Glyphs with an italic appearance that are typically
530 based on the unstyled glyphs, but are not fine-tuned
531 for the purpose of representing italicized text.
537 \fn FT_Face QFont::freetypeFace() const
539 Returns the handle to the primary FreeType face of the font. If font merging is not disabled a
540 QFont can contain several physical fonts.
542 Returns 0 if the font does not contain a FreeType face.
544 \note This function is only available on platforms that provide the FreeType library;
545 i.e., X11 and some Embedded Linux platforms.
549 \fn QString QFont::rawName() const
551 Returns the name of the font within the underlying window system.
553 On X11, this function will return an empty string.
555 Using the return value of this function is usually \e not \e
562 \fn void QFont::setRawName(const QString &name)
564 Sets a font by its system specific name.
566 A font set with setRawName() is still a full-featured QFont. It can
567 be queried (for example with italic()) or modified (for example with
568 setItalic()) and is therefore also suitable for rendering rich text.
570 If Qt's internal font database cannot resolve the raw name, the
571 font becomes a raw font with \a name as its family.
573 \sa rawName(), setRawMode(), setFamily()
577 \fn QString QFont::lastResortFamily() const
579 Returns the "last resort" font family name.
581 The current implementation tries a wide variety of common fonts,
582 returning the first one it finds. Is is possible that no family is
583 found in which case an empty string is returned.
589 \fn QString QFont::defaultFamily() const
591 Returns the family name that corresponds to the current style
594 \sa StyleHint, styleHint(), setStyleHint()
598 \fn QString QFont::lastResortFont() const
600 Returns a "last resort" font name for the font matching algorithm.
601 This is used if the last resort family is not available. It will
602 always return a name, if necessary returning something like
605 The current implementation tries a wide variety of common fonts,
606 returning the first one it finds. The implementation may change
607 at any time, but this function will always return a string
608 containing something.
610 It is theoretically possible that there really isn't a
611 lastResortFont() in which case Qt will abort with an error
612 message. We have not been able to identify a case where this
613 happens. Please \l{bughowto.html}{report it as a bug} if
614 it does, preferably with a list of the fonts you have installed.
616 \sa lastResortFamily(), rawName()
620 Constructs a font from \a font for use on the paint device \a pd.
622 QFont::QFont(const QFont &font, QPaintDevice *pd)
623 : resolve_mask(font.resolve_mask)
626 int dpi = pd->logicalDpiY();
627 const int screen = 0;
628 if (font.d->dpi != dpi || font.d->screen != screen ) {
629 d = new QFontPrivate(*font.d);
640 QFont::QFont(QFontPrivate *data)
641 : d(data), resolve_mask(QFont::AllPropertiesResolved)
646 Detaches the font object from common font data.
650 if (d->ref.load() == 1) {
652 d->engineData->ref.deref();
654 if (d->scFont && d->scFont != d.data())
655 d->scFont->ref.deref();
664 Constructs a font object that uses the application's default font.
666 \sa QGuiApplication::setFont(), QGuiApplication::font()
669 : d(QGuiApplication::font().d.data()), resolve_mask(0)
674 Constructs a font object with the specified \a family, \a
675 pointSize, \a weight and \a italic settings.
677 If \a pointSize is zero or negative, the point size of the font
678 is set to a system-dependent default value. Generally, this is
681 The \a family name may optionally also include a foundry name,
682 e.g. "Helvetica [Cronyx]". If the \a family is
683 available from more than one foundry and the foundry isn't
684 specified, an arbitrary foundry is chosen. If the family isn't
685 available a family will be set using the \l{QFont}{font matching}
688 \sa Weight, setFamily(), setPointSize(), setWeight(), setItalic(),
689 setStyleHint(), QGuiApplication::font()
691 QFont::QFont(const QString &family, int pointSize, int weight, bool italic)
692 : d(new QFontPrivate()), resolve_mask(QFont::FamilyResolved)
694 if (pointSize <= 0) {
697 resolve_mask |= QFont::SizeResolved;
703 resolve_mask |= QFont::WeightResolved | QFont::StyleResolved;
707 resolve_mask |= QFont::StyleResolved;
709 d->request.family = family;
710 d->request.pointSize = qreal(pointSize);
711 d->request.pixelSize = -1;
712 d->request.weight = weight;
713 d->request.style = italic ? QFont::StyleItalic : QFont::StyleNormal;
717 Constructs a font that is a copy of \a font.
719 QFont::QFont(const QFont &font)
720 : d(font.d.data()), resolve_mask(font.resolve_mask)
725 Destroys the font object and frees all allocated resources.
732 Assigns \a font to this font and returns a reference to it.
734 QFont &QFont::operator=(const QFont &font)
737 resolve_mask = font.resolve_mask;
742 Returns the requested font family name, i.e. the name set in the
743 constructor or the last setFont() call.
745 \sa setFamily(), substitutes(), substitute()
747 QString QFont::family() const
749 return d->request.family;
753 Sets the family name of the font. The name is case insensitive and
754 may include a foundry name.
756 The \a family name may optionally also include a foundry name,
757 e.g. "Helvetica [Cronyx]". If the \a family is
758 available from more than one foundry and the foundry isn't
759 specified, an arbitrary foundry is chosen. If the family isn't
760 available a family will be set using the \l{QFont}{font matching}
763 \sa family(), setStyleHint(), QFontInfo
765 void QFont::setFamily(const QString &family)
769 d->request.family = family;
771 resolve_mask |= QFont::FamilyResolved;
777 Returns the requested font style name, it will be used to match the
778 font with irregular styles (that can't be normalized in other style
779 properties). It depends on system font support, thus only works for
780 Mac OS X and X11 so far. On Windows irregular styles will be added
781 as separate font families so there is no need for this.
783 \sa setFamily(), setStyle()
785 QString QFont::styleName() const
787 return d->request.styleName;
793 Sets the style name of the font. When set, other style properties
794 like \a style() and \a weight() will be ignored for font matching.
798 void QFont::setStyleName(const QString &styleName)
802 d->request.styleName = styleName;
803 resolve_mask |= QFont::StyleNameResolved;
807 Returns the point size of the font. Returns -1 if the font size
808 was specified in pixels.
810 \sa setPointSize(), pointSizeF()
812 int QFont::pointSize() const
814 return qRound(d->request.pointSize);
820 \enum QFont::HintingPreference
822 This enum describes the different levels of hinting that can be applied
823 to glyphs to improve legibility on displays where it might be warranted
824 by the density of pixels.
826 \value PreferDefaultHinting Use the default hinting level for the target platform.
827 \value PreferNoHinting If possible, render text without hinting the outlines
828 of the glyphs. The text layout will be typographically accurate and
829 scalable, using the same metrics as are used e.g. when printing.
830 \value PreferVerticalHinting If possible, render text with no horizontal hinting,
831 but align glyphs to the pixel grid in the vertical direction. The text will appear
832 crisper on displays where the density is too low to give an accurate rendering
833 of the glyphs. But since the horizontal metrics of the glyphs are unhinted, the text's
834 layout will be scalable to higher density devices (such as printers) without impacting
835 details such as line breaks.
836 \value PreferFullHinting If possible, render text with hinting in both horizontal and
837 vertical directions. The text will be altered to optimize legibility on the target
838 device, but since the metrics will depend on the target size of the text, the positions
839 of glyphs, line breaks, and other typographical detail will not scale, meaning that a
840 text layout may look different on devices with different pixel densities.
842 Please note that this enum only describes a preference, as the full range of hinting levels
843 are not supported on all of Qt's supported platforms. The following table details the effect
844 of a given hinting preference on a selected set of target platforms.
849 \li PreferDefaultHinting
851 \li PreferVerticalHinting
852 \li PreferFullHinting
854 \li Windows Vista (w/o Platform Update) and earlier
860 \li Windows 7 and Windows Vista (w/Platform Update) and DirectWrite enabled in Qt
867 \li Operating System setting
869 \li Vertical hinting (light)
872 \li Cocoa on Mac OS X
879 \note Please be aware that altering the hinting preference on Windows is available through
880 the DirectWrite font engine. This is available on Windows Vista after installing the platform
881 update, and on Windows 7. In order to use this extension, configure Qt using -directwrite.
882 The target application will then depend on the availability of DirectWrite on the target
890 Set the preference for the hinting level of the glyphs to \a hintingPreference. This is a hint
891 to the underlying font rendering system to use a certain level of hinting, and has varying
892 support across platforms. See the table in the documentation for QFont::HintingPreference for
895 The default hinting preference is QFont::PreferDefaultHinting.
897 void QFont::setHintingPreference(HintingPreference hintingPreference)
901 d->request.hintingPreference = hintingPreference;
903 resolve_mask |= QFont::HintingPreferenceResolved;
909 Returns the currently preferred hinting level for glyphs rendered with this font.
911 QFont::HintingPreference QFont::hintingPreference() const
913 return QFont::HintingPreference(d->request.hintingPreference);
917 Sets the point size to \a pointSize. The point size must be
920 \sa pointSize(), setPointSizeF()
922 void QFont::setPointSize(int pointSize)
924 if (pointSize <= 0) {
925 qWarning("QFont::setPointSize: Point size <= 0 (%d), must be greater than 0", pointSize);
931 d->request.pointSize = qreal(pointSize);
932 d->request.pixelSize = -1;
934 resolve_mask |= QFont::SizeResolved;
938 Sets the point size to \a pointSize. The point size must be
939 greater than zero. The requested precision may not be achieved on
942 \sa pointSizeF(), setPointSize(), setPixelSize()
944 void QFont::setPointSizeF(qreal pointSize)
946 if (pointSize <= 0) {
947 qWarning("QFont::setPointSizeF: Point size <= 0 (%f), must be greater than 0", pointSize);
953 d->request.pointSize = pointSize;
954 d->request.pixelSize = -1;
956 resolve_mask |= QFont::SizeResolved;
960 Returns the point size of the font. Returns -1 if the font size was
963 \sa pointSize(), setPointSizeF(), pixelSize(), QFontInfo::pointSize(), QFontInfo::pixelSize()
965 qreal QFont::pointSizeF() const
967 return d->request.pointSize;
971 Sets the font size to \a pixelSize pixels.
973 Using this function makes the font device dependent. Use
974 setPointSize() or setPointSizeF() to set the size of the font
975 in a device independent manner.
979 void QFont::setPixelSize(int pixelSize)
981 if (pixelSize <= 0) {
982 qWarning("QFont::setPixelSize: Pixel size <= 0 (%d)", pixelSize);
988 d->request.pixelSize = pixelSize;
989 d->request.pointSize = -1;
991 resolve_mask |= QFont::SizeResolved;
995 Returns the pixel size of the font if it was set with
996 setPixelSize(). Returns -1 if the size was set with setPointSize()
999 \sa setPixelSize(), pointSize(), QFontInfo::pointSize(), QFontInfo::pixelSize()
1001 int QFont::pixelSize() const
1003 return d->request.pixelSize;
1007 \fn bool QFont::italic() const
1009 Returns true if the style() of the font is not QFont::StyleNormal
1011 \sa setItalic(), style()
1015 \fn void QFont::setItalic(bool enable)
1017 Sets the style() of the font to QFont::StyleItalic if \a enable is true;
1018 otherwise the style is set to QFont::StyleNormal.
1020 \sa italic(), QFontInfo
1024 Returns the style of the font.
1028 QFont::Style QFont::style() const
1030 return (QFont::Style)d->request.style;
1035 Sets the style of the font to \a style.
1037 \sa italic(), QFontInfo
1039 void QFont::setStyle(Style style)
1043 d->request.style = style;
1044 resolve_mask |= QFont::StyleResolved;
1048 Returns the weight of the font which is one of the enumerated
1049 values from \l{QFont::Weight}.
1051 \sa setWeight(), Weight, QFontInfo
1053 int QFont::weight() const
1055 return d->request.weight;
1061 Qt uses a weighting scale from 0 to 99 similar to, but not the
1062 same as, the scales used in Windows or CSS. A weight of 0 is
1063 ultralight, whilst 99 will be an extremely black.
1065 This enum contains the predefined font weights:
1075 Sets the weight the font to \a weight, which should be a value
1076 from the \l QFont::Weight enumeration.
1078 \sa weight(), QFontInfo
1080 void QFont::setWeight(int weight)
1082 Q_ASSERT_X(weight >= 0 && weight <= 99, "QFont::setWeight", "Weight must be between 0 and 99");
1086 d->request.weight = weight;
1087 resolve_mask |= QFont::WeightResolved;
1091 \fn bool QFont::bold() const
1093 Returns true if weight() is a value greater than
1094 \l{Weight}{QFont::Normal}; otherwise returns false.
1096 \sa weight(), setBold(), QFontInfo::bold()
1100 \fn void QFont::setBold(bool enable)
1102 If \a enable is true sets the font's weight to
1103 \l{Weight}{QFont::Bold};
1104 otherwise sets the weight to \l{Weight}{QFont::Normal}.
1106 For finer boldness control use setWeight().
1108 \sa bold(), setWeight()
1112 Returns true if underline has been set; otherwise returns false.
1116 bool QFont::underline() const
1118 return d->underline;
1122 If \a enable is true, sets underline on; otherwise sets underline
1125 \sa underline(), QFontInfo
1127 void QFont::setUnderline(bool enable)
1131 d->underline = enable;
1132 resolve_mask |= QFont::UnderlineResolved;
1136 Returns true if overline has been set; otherwise returns false.
1140 bool QFont::overline() const
1146 If \a enable is true, sets overline on; otherwise sets overline off.
1148 \sa overline(), QFontInfo
1150 void QFont::setOverline(bool enable)
1154 d->overline = enable;
1155 resolve_mask |= QFont::OverlineResolved;
1159 Returns true if strikeout has been set; otherwise returns false.
1163 bool QFont::strikeOut() const
1165 return d->strikeOut;
1169 If \a enable is true, sets strikeout on; otherwise sets strikeout
1172 \sa strikeOut(), QFontInfo
1174 void QFont::setStrikeOut(bool enable)
1178 d->strikeOut = enable;
1179 resolve_mask |= QFont::StrikeOutResolved;
1183 Returns true if fixed pitch has been set; otherwise returns false.
1185 \sa setFixedPitch(), QFontInfo::fixedPitch()
1187 bool QFont::fixedPitch() const
1189 return d->request.fixedPitch;
1193 If \a enable is true, sets fixed pitch on; otherwise sets fixed
1196 \sa fixedPitch(), QFontInfo
1198 void QFont::setFixedPitch(bool enable)
1202 d->request.fixedPitch = enable;
1203 d->request.ignorePitch = false;
1204 resolve_mask |= QFont::FixedPitchResolved;
1208 Returns true if kerning should be used when drawing text with this font.
1212 bool QFont::kerning() const
1218 Enables kerning for this font if \a enable is true; otherwise
1219 disables it. By default, kerning is enabled.
1221 When kerning is enabled, glyph metrics do not add up anymore,
1222 even for Latin text. In other words, the assumption that
1223 width('a') + width('b') is equal to width("ab") is not
1226 \sa kerning(), QFontMetrics
1228 void QFont::setKerning(bool enable)
1231 d->kerning = enable;
1232 resolve_mask |= QFont::KerningResolved;
1236 Returns the StyleStrategy.
1238 The style strategy affects the \l{QFont}{font matching} algorithm.
1239 See \l QFont::StyleStrategy for the list of available strategies.
1241 \sa setStyleHint(), QFont::StyleHint
1243 QFont::StyleStrategy QFont::styleStrategy() const
1245 return (StyleStrategy) d->request.styleStrategy;
1249 Returns the StyleHint.
1251 The style hint affects the \l{QFont}{font matching} algorithm.
1252 See \l QFont::StyleHint for the list of available hints.
1254 \sa setStyleHint(), QFont::StyleStrategy, QFontInfo::styleHint()
1256 QFont::StyleHint QFont::styleHint() const
1258 return (StyleHint) d->request.styleHint;
1262 \enum QFont::StyleHint
1264 Style hints are used by the \l{QFont}{font matching} algorithm to
1265 find an appropriate default family if a selected font family is
1268 \value AnyStyle leaves the font matching algorithm to choose the
1269 family. This is the default.
1271 \value SansSerif the font matcher prefer sans serif fonts.
1272 \value Helvetica is a synonym for \c SansSerif.
1274 \value Serif the font matcher prefers serif fonts.
1275 \value Times is a synonym for \c Serif.
1277 \value TypeWriter the font matcher prefers fixed pitch fonts.
1278 \value Courier a synonym for \c TypeWriter.
1280 \value OldEnglish the font matcher prefers decorative fonts.
1281 \value Decorative is a synonym for \c OldEnglish.
1283 \value Monospace the font matcher prefers fonts that map to the
1284 CSS generic font-family 'monospace'.
1286 \value Fantasy the font matcher prefers fonts that map to the
1287 CSS generic font-family 'fantasy'.
1289 \value Cursive the font matcher prefers fonts that map to the
1290 CSS generic font-family 'cursive'.
1292 \value System the font matcher prefers system fonts.
1296 \enum QFont::StyleStrategy
1298 The style strategy tells the \l{QFont}{font matching} algorithm
1299 what type of fonts should be used to find an appropriate default
1302 The following strategies are available:
1304 \value PreferDefault the default style strategy. It does not prefer
1306 \value PreferBitmap prefers bitmap fonts (as opposed to outline
1308 \value PreferDevice prefers device fonts.
1309 \value PreferOutline prefers outline fonts (as opposed to bitmap fonts).
1310 \value ForceOutline forces the use of outline fonts.
1311 \value NoAntialias don't antialias the fonts.
1312 \value PreferAntialias antialias if possible.
1313 \value OpenGLCompatible forces the use of OpenGL compatible
1315 \value NoFontMerging If the font selected for a certain writing system
1316 does not contain a character requested to draw, then Qt automatically chooses a similar
1317 looking font that contains the character. The NoFontMerging flag disables this feature.
1318 Please note that enabling this flag will not prevent Qt from automatically picking a
1319 suitable font when the selected font does not support the writing system of the text.
1321 Any of these may be OR-ed with one of these flags:
1323 \value PreferMatch prefer an exact match. The font matcher will try to
1324 use the exact font size that has been specified.
1325 \value PreferQuality prefer the best quality font. The font matcher
1326 will use the nearest standard point size that the font
1328 \value ForceIntegerMetrics forces the use of integer values in font engines that support fractional
1333 Sets the style hint and strategy to \a hint and \a strategy,
1336 If these aren't set explicitly the style hint will default to
1337 \c AnyStyle and the style strategy to \c PreferDefault.
1339 Qt does not support style hints on X11 since this information
1340 is not provided by the window system.
1342 \sa StyleHint, styleHint(), StyleStrategy, styleStrategy(), QFontInfo
1344 void QFont::setStyleHint(StyleHint hint, StyleStrategy strategy)
1348 if ((resolve_mask & (QFont::StyleHintResolved | QFont::StyleStrategyResolved)) &&
1349 (StyleHint) d->request.styleHint == hint &&
1350 (StyleStrategy) d->request.styleStrategy == strategy)
1353 d->request.styleHint = hint;
1354 d->request.styleStrategy = strategy;
1355 resolve_mask |= QFont::StyleHintResolved;
1356 resolve_mask |= QFont::StyleStrategyResolved;
1361 Sets the style strategy for the font to \a s.
1363 \sa QFont::StyleStrategy
1365 void QFont::setStyleStrategy(StyleStrategy s)
1369 if ((resolve_mask & QFont::StyleStrategyResolved) &&
1370 s == (StyleStrategy)d->request.styleStrategy)
1373 d->request.styleStrategy = s;
1374 resolve_mask |= QFont::StyleStrategyResolved;
1379 \enum QFont::Stretch
1381 Predefined stretch values that follow the CSS naming convention. The higher
1382 the value, the more stretched the text is.
1384 \value UltraCondensed 50
1385 \value ExtraCondensed 62
1387 \value SemiCondensed 87
1388 \value Unstretched 100
1389 \value SemiExpanded 112
1391 \value ExtraExpanded 150
1392 \value UltraExpanded 200
1394 \sa setStretch(), stretch()
1398 Returns the stretch factor for the font.
1402 int QFont::stretch() const
1404 return d->request.stretch;
1408 Sets the stretch factor for the font.
1410 The stretch factor changes the width of all characters in the font
1411 by \a factor percent. For example, setting \a factor to 150
1412 results in all characters in the font being 1.5 times (ie. 150%)
1413 wider. The default stretch factor is 100. The minimum stretch
1414 factor is 1, and the maximum stretch factor is 4000.
1416 The stretch factor is only applied to outline fonts. The stretch
1417 factor is ignored for bitmap fonts.
1419 \sa stretch(), QFont::Stretch
1421 void QFont::setStretch(int factor)
1423 if (factor < 1 || factor > 4000) {
1424 qWarning("QFont::setStretch: Parameter '%d' out of range", factor);
1428 if ((resolve_mask & QFont::StretchResolved) &&
1429 d->request.stretch == (uint)factor)
1434 d->request.stretch = (uint)factor;
1435 resolve_mask |= QFont::StretchResolved;
1439 \enum QFont::SpacingType
1442 \value PercentageSpacing A value of 100 will keep the spacing unchanged; a value of 200 will enlarge the
1443 spacing after a character by the width of the character itself.
1444 \value AbsoluteSpacing A positive value increases the letter spacing by the corresponding pixels; a negative
1445 value decreases the spacing.
1450 Returns the letter spacing for the font.
1452 \sa setLetterSpacing(), letterSpacingType(), setWordSpacing()
1454 qreal QFont::letterSpacing() const
1456 return d->letterSpacing.toReal();
1461 Sets the letter spacing for the font to \a spacing and the type
1462 of spacing to \a type.
1464 Letter spacing changes the default spacing between individual
1465 letters in the font. The spacing between the letters can be
1466 made smaller as well as larger.
1468 \sa letterSpacing(), letterSpacingType(), setWordSpacing()
1470 void QFont::setLetterSpacing(SpacingType type, qreal spacing)
1472 const QFixed newSpacing = QFixed::fromReal(spacing);
1473 const bool absoluteSpacing = type == AbsoluteSpacing;
1474 if ((resolve_mask & QFont::LetterSpacingResolved) &&
1475 d->letterSpacingIsAbsolute == absoluteSpacing &&
1476 d->letterSpacing == newSpacing)
1481 d->letterSpacing = newSpacing;
1482 d->letterSpacingIsAbsolute = absoluteSpacing;
1483 resolve_mask |= QFont::LetterSpacingResolved;
1488 Returns the spacing type used for letter spacing.
1490 \sa letterSpacing(), setLetterSpacing(), setWordSpacing()
1492 QFont::SpacingType QFont::letterSpacingType() const
1494 return d->letterSpacingIsAbsolute ? AbsoluteSpacing : PercentageSpacing;
1499 Returns the word spacing for the font.
1501 \sa setWordSpacing(), setLetterSpacing()
1503 qreal QFont::wordSpacing() const
1505 return d->wordSpacing.toReal();
1510 Sets the word spacing for the font to \a spacing.
1512 Word spacing changes the default spacing between individual
1513 words. A positive value increases the word spacing
1514 by a corresponding amount of pixels, while a negative value
1515 decreases the inter-word spacing accordingly.
1517 Word spacing will not apply to writing systems, where indiviaul
1518 words are not separated by white space.
1520 \sa wordSpacing(), setLetterSpacing()
1522 void QFont::setWordSpacing(qreal spacing)
1524 const QFixed newSpacing = QFixed::fromReal(spacing);
1525 if ((resolve_mask & QFont::WordSpacingResolved) &&
1526 d->wordSpacing == newSpacing)
1531 d->wordSpacing = newSpacing;
1532 resolve_mask |= QFont::WordSpacingResolved;
1536 \enum QFont::Capitalization
1539 Rendering option for text this font applies to.
1542 \value MixedCase This is the normal text rendering option where no capitalization change is applied.
1543 \value AllUppercase This alters the text to be rendered in all uppercase type.
1544 \value AllLowercase This alters the text to be rendered in all lowercase type.
1545 \value SmallCaps This alters the text to be rendered in small-caps type.
1546 \value Capitalize This alters the text to be rendered with the first character of each word as an uppercase character.
1551 Sets the capitalization of the text in this font to \a caps.
1553 A font's capitalization makes the text appear in the selected capitalization mode.
1555 \sa capitalization()
1557 void QFont::setCapitalization(Capitalization caps)
1559 if ((resolve_mask & QFont::CapitalizationResolved) &&
1560 capitalization() == caps)
1566 resolve_mask |= QFont::CapitalizationResolved;
1571 Returns the current capitalization type of the font.
1573 \sa setCapitalization()
1575 QFont::Capitalization QFont::capitalization() const
1577 return static_cast<QFont::Capitalization> (d->capital);
1582 If \a enable is true, turns raw mode on; otherwise turns raw mode
1583 off. This function only has an effect under X11.
1585 If raw mode is enabled, Qt will search for an X font with a
1586 complete font name matching the family name, ignoring all other
1587 values set for the QFont. If the font name matches several fonts,
1588 Qt will use the first font returned by X. QFontInfo \e cannot be
1589 used to fetch information about a QFont using raw mode (it will
1590 return the values set in the QFont for all parameters, including
1593 \warning Do not use raw mode unless you really, really need it! In
1594 most (if not all) cases, setRawName() is a much better choice.
1596 \sa rawMode(), setRawName()
1598 void QFont::setRawMode(bool enable)
1602 if ((bool) d->rawMode == enable) return;
1604 d->rawMode = enable;
1608 Returns true if a window system font exactly matching the settings
1609 of this font is available.
1613 bool QFont::exactMatch() const
1615 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1616 Q_ASSERT(engine != 0);
1618 ? engine->type() != QFontEngine::Box
1619 : d->request.exactMatch(engine->fontDef));
1623 Returns true if this font is equal to \a f; otherwise returns
1626 Two QFonts are considered equal if their font attributes are
1627 equal. If rawMode() is enabled for both fonts, only the family
1628 fields are compared.
1630 \sa operator!=(), isCopyOf()
1632 bool QFont::operator==(const QFont &f) const
1635 || (f.d->request == d->request
1636 && f.d->request.pointSize == d->request.pointSize
1637 && f.d->underline == d->underline
1638 && f.d->overline == d->overline
1639 && f.d->strikeOut == d->strikeOut
1640 && f.d->kerning == d->kerning
1641 && f.d->capital == d->capital
1642 && f.d->letterSpacingIsAbsolute == d->letterSpacingIsAbsolute
1643 && f.d->letterSpacing == d->letterSpacing
1644 && f.d->wordSpacing == d->wordSpacing
1650 Provides an arbitrary comparison of this font and font \a f.
1651 All that is guaranteed is that the operator returns false if both
1652 fonts are equal and that (f1 \< f2) == !(f2 \< f1) if the fonts
1655 This function is useful in some circumstances, for example if you
1656 want to use QFont objects as keys in a QMap.
1658 \sa operator==(), operator!=(), isCopyOf()
1660 bool QFont::operator<(const QFont &f) const
1662 if (f.d == d) return false;
1663 // the < operator for fontdefs ignores point sizes.
1664 QFontDef &r1 = f.d->request;
1665 QFontDef &r2 = d->request;
1666 if (r1.pointSize != r2.pointSize) return r1.pointSize < r2.pointSize;
1667 if (r1.pixelSize != r2.pixelSize) return r1.pixelSize < r2.pixelSize;
1668 if (r1.weight != r2.weight) return r1.weight < r2.weight;
1669 if (r1.style != r2.style) return r1.style < r2.style;
1670 if (r1.stretch != r2.stretch) return r1.stretch < r2.stretch;
1671 if (r1.styleHint != r2.styleHint) return r1.styleHint < r2.styleHint;
1672 if (r1.styleStrategy != r2.styleStrategy) return r1.styleStrategy < r2.styleStrategy;
1673 if (r1.family != r2.family) return r1.family < r2.family;
1674 if (f.d->capital != d->capital) return f.d->capital < d->capital;
1676 if (f.d->letterSpacingIsAbsolute != d->letterSpacingIsAbsolute) return f.d->letterSpacingIsAbsolute < d->letterSpacingIsAbsolute;
1677 if (f.d->letterSpacing != d->letterSpacing) return f.d->letterSpacing < d->letterSpacing;
1678 if (f.d->wordSpacing != d->wordSpacing) return f.d->wordSpacing < d->wordSpacing;
1680 int f1attrs = (f.d->underline << 3) + (f.d->overline << 2) + (f.d->strikeOut<<1) + f.d->kerning;
1681 int f2attrs = (d->underline << 3) + (d->overline << 2) + (d->strikeOut<<1) + d->kerning;
1682 return f1attrs < f2attrs;
1687 Returns true if this font is different from \a f; otherwise
1690 Two QFonts are considered to be different if their font attributes
1691 are different. If rawMode() is enabled for both fonts, only the
1692 family fields are compared.
1696 bool QFont::operator!=(const QFont &f) const
1698 return !(operator==(f));
1702 Returns the font as a QVariant
1704 QFont::operator QVariant() const
1706 return QVariant(QVariant::Font, this);
1710 Returns true if this font and \a f are copies of each other, i.e.
1711 one of them was created as a copy of the other and neither has
1712 been modified since. This is much stricter than equality.
1714 \sa operator=(), operator==()
1716 bool QFont::isCopyOf(const QFont & f) const
1722 Returns true if raw mode is used for font name matching; otherwise
1725 \sa setRawMode(), rawName()
1727 bool QFont::rawMode() const
1733 Returns a new QFont that has attributes copied from \a other that
1734 have not been previously set on this font.
1736 QFont QFont::resolve(const QFont &other) const
1739 && (resolve_mask == other.resolve_mask || resolve_mask == 0)
1740 && d->dpi == other.d->dpi) {
1742 o.resolve_mask = resolve_mask;
1748 font.d->resolve(resolve_mask, other.d.data());
1754 \fn uint QFont::resolve() const
1759 \fn void QFont::resolve(uint mask)
1764 /*****************************************************************************
1765 QFont substitution management
1766 *****************************************************************************/
1768 typedef QHash<QString, QStringList> QFontSubst;
1769 Q_GLOBAL_STATIC(QFontSubst, globalFontSubst)
1772 Returns the first family name to be used whenever \a familyName is
1773 specified. The lookup is case insensitive.
1775 If there is no substitution for \a familyName, \a familyName is
1778 To obtain a list of substitutions use substitutes().
1780 \sa setFamily(), insertSubstitutions(), insertSubstitution(), removeSubstitutions()
1782 QString QFont::substitute(const QString &familyName)
1784 QFontSubst *fontSubst = globalFontSubst();
1785 Q_ASSERT(fontSubst != 0);
1786 QFontSubst::ConstIterator it = fontSubst->constFind(familyName.toLower());
1787 if (it != fontSubst->constEnd() && !(*it).isEmpty())
1788 return (*it).first();
1795 Returns a list of family names to be used whenever \a familyName
1796 is specified. The lookup is case insensitive.
1798 If there is no substitution for \a familyName, an empty list is
1801 \sa substitute(), insertSubstitutions(), insertSubstitution(), removeSubstitutions()
1803 QStringList QFont::substitutes(const QString &familyName)
1805 QFontSubst *fontSubst = globalFontSubst();
1806 Q_ASSERT(fontSubst != 0);
1807 return fontSubst->value(familyName.toLower(), QStringList());
1812 Inserts \a substituteName into the substitution
1813 table for the family \a familyName.
1815 \sa insertSubstitutions(), removeSubstitutions(), substitutions(), substitute(), substitutes()
1817 void QFont::insertSubstitution(const QString &familyName,
1818 const QString &substituteName)
1820 QFontSubst *fontSubst = globalFontSubst();
1821 Q_ASSERT(fontSubst != 0);
1822 QStringList &list = (*fontSubst)[familyName.toLower()];
1823 QString s = substituteName.toLower();
1824 if (!list.contains(s))
1830 Inserts the list of families \a substituteNames into the
1831 substitution list for \a familyName.
1833 \sa insertSubstitution(), removeSubstitutions(), substitutions(), substitute()
1835 void QFont::insertSubstitutions(const QString &familyName,
1836 const QStringList &substituteNames)
1838 QFontSubst *fontSubst = globalFontSubst();
1839 Q_ASSERT(fontSubst != 0);
1840 QStringList &list = (*fontSubst)[familyName.toLower()];
1841 foreach (const QString &substituteName, substituteNames) {
1842 const QString lowerSubstituteName = substituteName.toLower();
1843 if (!list.contains(lowerSubstituteName))
1844 list.append(lowerSubstituteName);
1848 /*! \fn void QFont::initialize()
1851 Internal function that initializes the font system. The font cache
1852 and font dict do not alloc the keys. The key is a QString which is
1853 shared between QFontPrivate and QXFontName.
1856 /*! \fn void QFont::cleanup()
1859 Internal function that cleans up the font system.
1863 Removes all the substitutions for \a familyName.
1865 \sa insertSubstitutions(), insertSubstitution(), substitutions(), substitute()
1868 void QFont::removeSubstitutions(const QString &familyName)
1870 QFontSubst *fontSubst = globalFontSubst();
1871 Q_ASSERT(fontSubst != 0);
1872 fontSubst->remove(familyName.toLower());
1876 \fn void QFont::removeSubstitution(const QString &familyName)
1880 This function is deprecated. Use removeSubstitutions() instead.
1884 Returns a sorted list of substituted family names.
1886 \sa insertSubstitution(), removeSubstitution(), substitute()
1888 QStringList QFont::substitutions()
1890 typedef QFontSubst::const_iterator QFontSubstConstIterator;
1892 QFontSubst *fontSubst = globalFontSubst();
1893 Q_ASSERT(fontSubst != 0);
1895 const QFontSubstConstIterator cend = fontSubst->constEnd();
1896 for (QFontSubstConstIterator it = fontSubst->constBegin(); it != cend; ++it)
1897 ret.append(it.key());
1905 Internal function. Converts boolean font settings to an unsigned
1906 8-bit number. Used for serialization etc.
1908 static quint8 get_font_bits(int version, const QFontPrivate *f)
1912 if (f->request.style)
1920 if (f->request.fixedPitch)
1922 // if (f.hintSetByUser)
1926 if (version >= QDataStream::Qt_4_0) {
1930 if (f->request.style == QFont::StyleOblique)
1935 static quint8 get_extended_font_bits(const QFontPrivate *f)
1939 if (f->request.ignorePitch)
1941 if (f->letterSpacingIsAbsolute)
1946 #ifndef QT_NO_DATASTREAM
1949 Internal function. Sets boolean font settings from an unsigned
1950 8-bit number. Used for serialization etc.
1952 static void set_font_bits(int version, quint8 bits, QFontPrivate *f)
1955 f->request.style = (bits & 0x01) != 0 ? QFont::StyleItalic : QFont::StyleNormal;
1956 f->underline = (bits & 0x02) != 0;
1957 f->overline = (bits & 0x40) != 0;
1958 f->strikeOut = (bits & 0x04) != 0;
1959 f->request.fixedPitch = (bits & 0x08) != 0;
1960 // f->hintSetByUser = (bits & 0x10) != 0;
1961 f->rawMode = (bits & 0x20) != 0;
1962 if (version >= QDataStream::Qt_4_0)
1963 f->kerning = (bits & 0x10) != 0;
1964 if ((bits & 0x80) != 0)
1965 f->request.style = QFont::StyleOblique;
1968 static void set_extended_font_bits(quint8 bits, QFontPrivate *f)
1971 f->request.ignorePitch = (bits & 0x01) != 0;
1972 f->letterSpacingIsAbsolute = (bits & 0x02) != 0;
1978 Returns the font's key, a textual representation of a font. It is
1979 typically used as the key for a cache or dictionary of fonts.
1983 QString QFont::key() const
1989 Returns a description of the font. The description is a
1990 comma-separated list of the attributes, perfectly suited for use
1995 QString QFont::toString() const
1997 const QChar comma(QLatin1Char(','));
1998 return family() + comma +
1999 QString::number( pointSizeF()) + comma +
2000 QString::number( pixelSize()) + comma +
2001 QString::number((int) styleHint()) + comma +
2002 QString::number( weight()) + comma +
2003 QString::number((int) style()) + comma +
2004 QString::number((int) underline()) + comma +
2005 QString::number((int) strikeOut()) + comma +
2006 QString::number((int)fixedPitch()) + comma +
2007 QString::number((int) rawMode());
2012 Sets this font to match the description \a descrip. The description
2013 is a comma-separated list of the font attributes, as returned by
2018 bool QFont::fromString(const QString &descrip)
2020 QStringList l(descrip.split(QLatin1Char(',')));
2022 int count = l.count();
2023 if (!count || (count > 2 && count < 9) || count > 11) {
2024 qWarning("QFont::fromString: Invalid description '%s'",
2025 descrip.isEmpty() ? "(empty)" : descrip.toLatin1().data());
2030 if (count > 1 && l[1].toDouble() > 0.0)
2031 setPointSizeF(l[1].toDouble());
2033 setStyleHint((StyleHint) l[2].toInt());
2034 setWeight(qMax(qMin(99, l[3].toInt()), 0));
2035 setItalic(l[4].toInt());
2036 setUnderline(l[5].toInt());
2037 setStrikeOut(l[6].toInt());
2038 setFixedPitch(l[7].toInt());
2039 setRawMode(l[8].toInt());
2040 } else if (count == 10) {
2041 if (l[2].toInt() > 0)
2042 setPixelSize(l[2].toInt());
2043 setStyleHint((StyleHint) l[3].toInt());
2044 setWeight(qMax(qMin(99, l[4].toInt()), 0));
2045 setStyle((QFont::Style)l[5].toInt());
2046 setUnderline(l[6].toInt());
2047 setStrikeOut(l[7].toInt());
2048 setFixedPitch(l[8].toInt());
2049 setRawMode(l[9].toInt());
2051 if (count >= 9 && !d->request.fixedPitch) // assume 'false' fixedPitch equals default
2052 d->request.ignorePitch = true;
2059 Internal function that dumps font cache statistics.
2061 void QFont::cacheStatistics()
2069 /*****************************************************************************
2070 QFont stream functions
2071 *****************************************************************************/
2072 #ifndef QT_NO_DATASTREAM
2077 Writes the font \a font to the data stream \a s. (toString()
2078 writes to a text stream.)
2080 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2082 QDataStream &operator<<(QDataStream &s, const QFont &font)
2084 if (s.version() == 1) {
2085 s << font.d->request.family.toLatin1();
2087 s << font.d->request.family;
2090 if (s.version() >= QDataStream::Qt_4_0) {
2092 double pointSize = font.d->request.pointSize;
2093 qint32 pixelSize = font.d->request.pixelSize;
2096 } else if (s.version() <= 3) {
2097 qint16 pointSize = (qint16) (font.d->request.pointSize * 10);
2098 if (pointSize < 0) {
2099 pointSize = (qint16)QFontInfo(font).pointSize() * 10;
2103 s << (qint16) (font.d->request.pointSize * 10);
2104 s << (qint16) font.d->request.pixelSize;
2107 s << (quint8) font.d->request.styleHint;
2108 if (s.version() >= QDataStream::Qt_3_1)
2109 s << (quint8) font.d->request.styleStrategy;
2111 << (quint8) font.d->request.weight
2112 << get_font_bits(s.version(), font.d.data());
2113 if (s.version() >= QDataStream::Qt_4_3)
2114 s << (quint16)font.d->request.stretch;
2115 if (s.version() >= QDataStream::Qt_4_4)
2116 s << get_extended_font_bits(font.d.data());
2117 if (s.version() >= QDataStream::Qt_4_5) {
2118 s << font.d->letterSpacing.value();
2119 s << font.d->wordSpacing.value();
2128 Reads the font \a font from the data stream \a s. (fromString()
2129 reads from a text stream.)
2131 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2133 QDataStream &operator>>(QDataStream &s, QFont &font)
2135 font.d = new QFontPrivate;
2136 font.resolve_mask = QFont::AllPropertiesResolved;
2138 quint8 styleHint, styleStrategy = QFont::PreferDefault, charSet, weight, bits;
2140 if (s.version() == 1) {
2143 font.d->request.family = QString::fromLatin1(fam);
2145 s >> font.d->request.family;
2148 if (s.version() >= QDataStream::Qt_4_0) {
2154 font.d->request.pointSize = qreal(pointSize);
2155 font.d->request.pixelSize = pixelSize;
2157 qint16 pointSize, pixelSize = -1;
2159 if (s.version() >= 4)
2161 font.d->request.pointSize = qreal(pointSize / 10.);
2162 font.d->request.pixelSize = pixelSize;
2165 if (s.version() >= QDataStream::Qt_3_1)
2172 font.d->request.styleHint = styleHint;
2173 font.d->request.styleStrategy = styleStrategy;
2174 font.d->request.weight = weight;
2176 set_font_bits(s.version(), bits, font.d.data());
2178 if (s.version() >= QDataStream::Qt_4_3) {
2181 font.d->request.stretch = stretch;
2184 if (s.version() >= QDataStream::Qt_4_4) {
2185 quint8 extendedBits;
2187 set_extended_font_bits(extendedBits, font.d.data());
2189 if (s.version() >= QDataStream::Qt_4_5) {
2192 font.d->letterSpacing.setValue(value);
2194 font.d->wordSpacing.setValue(value);
2200 #endif // QT_NO_DATASTREAM
2203 /*****************************************************************************
2204 QFontInfo member functions
2205 *****************************************************************************/
2211 \brief The QFontInfo class provides general information about fonts.
2217 The QFontInfo class provides the same access functions as QFont,
2218 e.g. family(), pointSize(), italic(), weight(), fixedPitch(),
2219 styleHint() etc. But whilst the QFont access functions return the
2220 values that were set, a QFontInfo object returns the values that
2221 apply to the font that will actually be used to draw the text.
2223 For example, when the program asks for a 25pt Courier font on a
2224 machine that has a non-scalable 24pt Courier font, QFont will
2225 (normally) use the 24pt Courier for rendering. In this case,
2226 QFont::pointSize() returns 25 and QFontInfo::pointSize() returns
2229 There are three ways to create a QFontInfo object.
2231 \li Calling the QFontInfo constructor with a QFont creates a font
2232 info object for a screen-compatible font, i.e. the font cannot be
2233 a printer font. If the font is changed later, the font
2234 info object is \e not updated.
2236 (Note: If you use a printer font the values returned may be
2237 inaccurate. Printer fonts are not always accessible so the nearest
2238 screen font is used if a printer font is supplied.)
2240 \li QWidget::fontInfo() returns the font info for a widget's font.
2241 This is equivalent to calling QFontInfo(widget->font()). If the
2242 widget's font is changed later, the font info object is \e not
2245 \li QPainter::fontInfo() returns the font info for a painter's
2246 current font. If the painter's font is changed later, the font
2247 info object is \e not updated.
2250 \sa QFont, QFontMetrics, QFontDatabase
2254 Constructs a font info object for \a font.
2256 The font must be screen-compatible, i.e. a font you use when
2257 drawing text in \l{QWidget}{widgets} or \l{QPixmap}{pixmaps}, not QPicture or QPrinter.
2259 The font info object holds the information for the font that is
2260 passed in the constructor at the time it is created, and is not
2261 updated if the font's attributes are changed later.
2263 Use QPainter::fontInfo() to get the font info when painting.
2264 This will give correct results also when painting on paint device
2265 that is not screen-compatible.
2267 QFontInfo::QFontInfo(const QFont &font)
2273 Constructs a copy of \a fi.
2275 QFontInfo::QFontInfo(const QFontInfo &fi)
2281 Destroys the font info object.
2283 QFontInfo::~QFontInfo()
2288 Assigns the font info in \a fi.
2290 QFontInfo &QFontInfo::operator=(const QFontInfo &fi)
2297 Returns the family name of the matched window system font.
2301 QString QFontInfo::family() const
2303 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2304 Q_ASSERT(engine != 0);
2305 return engine->fontDef.family;
2311 Returns the style name of the matched window system font on
2312 system that supports it.
2314 \sa QFont::styleName()
2316 QString QFontInfo::styleName() const
2318 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2319 Q_ASSERT(engine != 0);
2320 return engine->fontDef.styleName;
2324 Returns the point size of the matched window system font.
2326 \sa pointSizeF(), QFont::pointSize()
2328 int QFontInfo::pointSize() const
2330 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2331 Q_ASSERT(engine != 0);
2332 return qRound(engine->fontDef.pointSize);
2336 Returns the point size of the matched window system font.
2338 \sa QFont::pointSizeF()
2340 qreal QFontInfo::pointSizeF() const
2342 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2343 Q_ASSERT(engine != 0);
2344 return engine->fontDef.pointSize;
2348 Returns the pixel size of the matched window system font.
2350 \sa QFont::pointSize()
2352 int QFontInfo::pixelSize() const
2354 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2355 Q_ASSERT(engine != 0);
2356 return engine->fontDef.pixelSize;
2360 Returns the italic value of the matched window system font.
2364 bool QFontInfo::italic() const
2366 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2367 Q_ASSERT(engine != 0);
2368 return engine->fontDef.style != QFont::StyleNormal;
2372 Returns the style value of the matched window system font.
2376 QFont::Style QFontInfo::style() const
2378 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2379 Q_ASSERT(engine != 0);
2380 return (QFont::Style)engine->fontDef.style;
2384 Returns the weight of the matched window system font.
2386 \sa QFont::weight(), bold()
2388 int QFontInfo::weight() const
2390 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2391 Q_ASSERT(engine != 0);
2392 return engine->fontDef.weight;
2397 \fn bool QFontInfo::bold() const
2399 Returns true if weight() would return a value greater than
2400 QFont::Normal; otherwise returns false.
2402 \sa weight(), QFont::bold()
2406 Returns the underline value of the matched window system font.
2408 \sa QFont::underline()
2412 Here we read the underline flag directly from the QFont.
2413 This is OK for X11 and for Windows because we always get what we want.
2415 bool QFontInfo::underline() const
2417 return d->underline;
2421 Returns the overline value of the matched window system font.
2423 \sa QFont::overline()
2427 Here we read the overline flag directly from the QFont.
2428 This is OK for X11 and for Windows because we always get what we want.
2430 bool QFontInfo::overline() const
2436 Returns the strikeout value of the matched window system font.
2438 \sa QFont::strikeOut()
2440 \internal Here we read the strikeOut flag directly from the QFont.
2441 This is OK for X11 and for Windows because we always get what we want.
2443 bool QFontInfo::strikeOut() const
2445 return d->strikeOut;
2449 Returns the fixed pitch value of the matched window system font.
2451 \sa QFont::fixedPitch()
2453 bool QFontInfo::fixedPitch() const
2455 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2456 Q_ASSERT(engine != 0);
2458 if (!engine->fontDef.fixedPitchComputed) {
2459 QChar ch[2] = { QLatin1Char('i'), QLatin1Char('m') };
2460 QGlyphLayoutArray<2> g;
2462 engine->stringToCMap(ch, 2, &g, &l, 0);
2463 engine->fontDef.fixedPitch = g.advances_x[0] == g.advances_x[1];
2464 engine->fontDef.fixedPitchComputed = true;
2467 return engine->fontDef.fixedPitch;
2471 Returns the style of the matched window system font.
2473 Currently only returns the style hint set in QFont.
2475 \sa QFont::styleHint(), QFont::StyleHint
2477 QFont::StyleHint QFontInfo::styleHint() const
2479 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2480 Q_ASSERT(engine != 0);
2481 return (QFont::StyleHint) engine->fontDef.styleHint;
2485 Returns true if the font is a raw mode font; otherwise returns
2488 If it is a raw mode font, all other functions in QFontInfo will
2489 return the same values set in the QFont, regardless of the font
2492 \sa QFont::rawMode()
2494 bool QFontInfo::rawMode() const
2500 Returns true if the matched window system font is exactly the same
2501 as the one specified by the font; otherwise returns false.
2503 \sa QFont::exactMatch()
2505 bool QFontInfo::exactMatch() const
2507 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2508 Q_ASSERT(engine != 0);
2510 ? engine->type() != QFontEngine::Box
2511 : d->request.exactMatch(engine->fontDef));
2517 // **********************************************************************
2519 // **********************************************************************
2521 #ifdef QFONTCACHE_DEBUG
2522 // fast timeouts for debugging
2523 static const int fast_timeout = 1000; // 1s
2524 static const int slow_timeout = 5000; // 5s
2526 static const int fast_timeout = 10000; // 10s
2527 static const int slow_timeout = 300000; // 5m
2528 #endif // QFONTCACHE_DEBUG
2530 const uint QFontCache::min_cost = 4*1024; // 4mb
2533 Q_GLOBAL_STATIC(QFontCache, theFontCache)
2535 QFontCache *QFontCache::instance()
2537 return theFontCache();
2540 void QFontCache::cleanup()
2544 Q_GLOBAL_STATIC(QThreadStorage<QFontCache *>, theFontCache)
2546 QFontCache *QFontCache::instance()
2548 QFontCache *&fontCache = theFontCache()->localData();
2550 fontCache = new QFontCache;
2554 void QFontCache::cleanup()
2556 QThreadStorage<QFontCache *> *cache = 0;
2558 cache = theFontCache();
2559 } QT_CATCH (const std::bad_alloc &) {
2560 // no cache - just ignore
2562 if (cache && cache->hasLocalData())
2563 cache->setLocalData(0);
2565 #endif // QT_NO_THREAD
2567 QFontCache::QFontCache()
2568 : QObject(), total_cost(0), max_cost(min_cost),
2569 current_timestamp(0), fast(false), timer_id(-1)
2573 QFontCache::~QFontCache()
2577 EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
2578 end = engineDataCache.constEnd();
2580 if (it.value()->ref.load() == 0)
2583 FC_DEBUG("QFontCache::~QFontCache: engineData %p still has refcount %d",
2584 it.value(), it.value()->ref.load());
2588 EngineCache::ConstIterator it = engineCache.constBegin(),
2589 end = engineCache.constEnd();
2591 if (--it.value().data->cache_count == 0) {
2592 if (it.value().data->ref.load() == 0) {
2593 FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %g %d %d %d)",
2594 it.value().data, it.key().script, it.key().def.pointSize,
2595 it.key().def.pixelSize, it.key().def.weight, it.key().def.style,
2596 it.key().def.fixedPitch);
2598 delete it.value().data;
2600 FC_DEBUG("QFontCache::~QFontCache: engine = %p still has refcount %d",
2601 it.value().data, it.value().data->ref.load());
2608 void QFontCache::clear()
2611 EngineDataCache::Iterator it = engineDataCache.begin(),
2612 end = engineDataCache.end();
2614 QFontEngineData *data = it.value();
2615 for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
2616 if (data->engines[i]) {
2617 data->engines[i]->ref.deref();
2618 data->engines[i] = 0;
2625 for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
2627 if (it->data->ref.load() == 0) {
2633 for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
2635 if (it->data && it->data->ref.load() == 0) {
2641 engineCache.clear();
2645 QFontEngineData *QFontCache::findEngineData(const QFontDef &def) const
2647 EngineDataCache::ConstIterator it = engineDataCache.find(def),
2648 end = engineDataCache.end();
2649 if (it == end) return 0;
2655 void QFontCache::insertEngineData(const QFontDef &def, QFontEngineData *engineData)
2657 FC_DEBUG("QFontCache: inserting new engine data %p", engineData);
2659 engineDataCache.insert(def, engineData);
2660 increaseCost(sizeof(QFontEngineData));
2663 QFontEngine *QFontCache::findEngine(const Key &key)
2665 EngineCache::Iterator it = engineCache.find(key),
2666 end = engineCache.end();
2667 if (it == end) return 0;
2668 // found... update the hitcount and timestamp
2669 updateHitCountAndTimeStamp(it.value());
2671 return it.value().data;
2674 void QFontCache::updateHitCountAndTimeStamp(Engine &value)
2677 value.timestamp = ++current_timestamp;
2679 FC_DEBUG("QFontCache: found font engine\n"
2680 " %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'",
2681 value.data, value.timestamp, value.hits,
2682 value.data->ref.load(), value.data->cache_count,
2683 value.data->name());
2686 void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti)
2688 FC_DEBUG("QFontCache: inserting new engine %p", engine);
2690 Engine data(engine);
2691 data.timestamp = ++current_timestamp;
2694 engineCache.insertMulti(key, data);
2696 engineCache.insert(key, data);
2698 // only increase the cost if this is the first time we insert the engine
2699 if (engine->cache_count == 0)
2700 increaseCost(engine->cache_cost);
2702 ++engine->cache_count;
2705 void QFontCache::increaseCost(uint cost)
2707 cost = (cost + 512) / 1024; // store cost in kb
2708 cost = cost > 0 ? cost : 1;
2711 FC_DEBUG(" COST: increased %u kb, total_cost %u kb, max_cost %u kb",
2712 cost, total_cost, max_cost);
2714 if (total_cost > max_cost) {
2715 max_cost = total_cost;
2717 if (timer_id == -1 || ! fast) {
2718 FC_DEBUG(" TIMER: starting fast timer (%d ms)", fast_timeout);
2720 if (timer_id != -1) killTimer(timer_id);
2721 timer_id = startTimer(fast_timeout);
2727 void QFontCache::decreaseCost(uint cost)
2729 cost = (cost + 512) / 1024; // cost is stored in kb
2730 cost = cost > 0 ? cost : 1;
2731 Q_ASSERT(cost <= total_cost);
2734 FC_DEBUG(" COST: decreased %u kb, total_cost %u kb, max_cost %u kb",
2735 cost, total_cost, max_cost);
2738 void QFontCache::timerEvent(QTimerEvent *)
2740 FC_DEBUG("QFontCache::timerEvent: performing cache maintenance (timestamp %u)",
2743 if (total_cost <= max_cost && max_cost <= min_cost) {
2744 FC_DEBUG(" cache redused sufficiently, stopping timer");
2746 killTimer(timer_id);
2753 // go through the cache and count up everything in use
2754 uint in_use_cost = 0;
2757 FC_DEBUG(" SWEEP engine data:");
2759 // make sure the cost of each engine data is at least 1kb
2760 const uint engine_data_cost =
2761 sizeof(QFontEngineData) > 1024 ? sizeof(QFontEngineData) : 1024;
2763 EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
2764 end = engineDataCache.constEnd();
2765 for (; it != end; ++it) {
2766 #ifdef QFONTCACHE_DEBUG
2767 FC_DEBUG(" %p: ref %2d", it.value(), int(it.value()->ref));
2769 #endif // QFONTCACHE_DEBUG
2771 if (it.value()->ref.load() != 0)
2772 in_use_cost += engine_data_cost;
2777 FC_DEBUG(" SWEEP engine:");
2779 EngineCache::ConstIterator it = engineCache.constBegin(),
2780 end = engineCache.constEnd();
2781 for (; it != end; ++it) {
2782 FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, cost %u bytes",
2783 it.value().data, it.value().timestamp, it.value().hits,
2784 it.value().data->ref.load(), it.value().data->cache_count,
2785 it.value().data->cache_cost);
2787 if (it.value().data->ref.load() != 0)
2788 in_use_cost += it.value().data->cache_cost / it.value().data->cache_count;
2791 // attempt to make up for rounding errors
2792 in_use_cost += engineCache.size();
2795 in_use_cost = (in_use_cost + 512) / 1024; // cost is stored in kb
2798 calculate the new maximum cost for the cache
2800 NOTE: in_use_cost is *not* correct due to rounding errors in the
2801 above algorithm. instead of worrying about getting the
2802 calculation correct, we are more interested in speed, and use
2803 in_use_cost as a floor for new_max_cost
2805 uint new_max_cost = qMax(qMax(max_cost / 2, in_use_cost), min_cost);
2807 FC_DEBUG(" after sweep, in use %u kb, total %u kb, max %u kb, new max %u kb",
2808 in_use_cost, total_cost, max_cost, new_max_cost);
2810 if (new_max_cost == max_cost) {
2812 FC_DEBUG(" cannot shrink cache, slowing timer");
2814 killTimer(timer_id);
2815 timer_id = startTimer(slow_timeout);
2820 } else if (! fast) {
2821 FC_DEBUG(" dropping into passing gear");
2823 killTimer(timer_id);
2824 timer_id = startTimer(fast_timeout);
2828 max_cost = new_max_cost;
2831 FC_DEBUG(" CLEAN engine data:");
2833 // clean out all unused engine data
2834 EngineDataCache::Iterator it = engineDataCache.begin(),
2835 end = engineDataCache.end();
2837 if (it.value()->ref.load() != 0) {
2842 EngineDataCache::Iterator rem = it++;
2844 decreaseCost(sizeof(QFontEngineData));
2846 FC_DEBUG(" %p", rem.value());
2849 engineDataCache.erase(rem);
2853 // clean out the engine cache just enough to get below our new max cost
2856 current_cost = total_cost;
2858 EngineCache::Iterator it = engineCache.begin(),
2859 end = engineCache.end();
2860 // determine the oldest and least popular of the unused engines
2862 uint least_popular = ~0u;
2864 for (; it != end; ++it) {
2865 if (it.value().data->ref.load() != 0)
2868 if (it.value().timestamp < oldest &&
2869 it.value().hits <= least_popular) {
2870 oldest = it.value().timestamp;
2871 least_popular = it.value().hits;
2875 FC_DEBUG(" oldest %u least popular %u", oldest, least_popular);
2877 for (it = engineCache.begin(); it != end; ++it) {
2878 if (it.value().data->ref.load() == 0 &&
2879 it.value().timestamp == oldest &&
2880 it.value().hits == least_popular)
2885 FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'",
2886 it.value().data, it.value().timestamp, it.value().hits,
2887 it.value().data->ref.load(), it.value().data->cache_count,
2888 it.value().data->name());
2890 if (--it.value().data->cache_count == 0) {
2891 FC_DEBUG(" DELETE: last occurrence in cache");
2893 decreaseCost(it.value().data->cache_cost);
2894 delete it.value().data;
2897 this particular font engine is in the cache multiple
2898 times... set current_cost to zero, so that we can
2899 keep looping to get rid of all occurrences
2904 engineCache.erase(it);
2906 } while (current_cost != total_cost && total_cost > max_cost);
2910 #ifndef QT_NO_DEBUG_STREAM
2911 QDebug operator<<(QDebug stream, const QFont &font)
2913 return stream << "QFont(" << font.toString() << ')';