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
349 When you create a QFont object you specify various attributes that
350 you want the font to have. Qt will use the font with the specified
351 attributes, or if no matching font exists, Qt will use the closest
352 matching installed font. The attributes of the font that is
353 actually used are retrievable from a QFontInfo object. If the
354 window system provides an exact match exactMatch() returns true.
355 Use QFontMetrics to get measurements, e.g. the pixel length of a
356 string using QFontMetrics::width().
358 Note that a QGuiApplication instance must exist before a QFont can be
359 used. You can set the application's default font with
360 QGuiApplication::setFont().
362 If a chosen font does not include all the characters that
363 need to be displayed, QFont will try to find the characters in the
364 nearest equivalent fonts. When a QPainter draws a character from a
365 font the QFont will report whether or not it has the character; if
366 it does not, QPainter will draw an unfilled square.
368 Create QFonts like this:
370 \snippet code/src_gui_text_qfont.cpp 0
372 The attributes set in the constructor can also be set later, e.g.
373 setFamily(), setPointSize(), setPointSizeFloat(), setWeight() and
374 setItalic(). The remaining attributes must be set after
375 contstruction, e.g. setBold(), setUnderline(), setOverline(),
376 setStrikeOut() and setFixedPitch(). QFontInfo objects should be
377 created \e after the font's attributes have been set. A QFontInfo
378 object will not change, even if you change the font's
379 attributes. The corresponding "get" functions, e.g. family(),
380 pointSize(), etc., return the values that were set, even though
381 the values used may differ. The actual values are available from a
384 If the requested font family is unavailable you can influence the
385 \l{#fontmatching}{font matching algorithm} by choosing a
386 particular \l{QFont::StyleHint} and \l{QFont::StyleStrategy} with
387 setStyleHint(). The default family (corresponding to the current
388 style hint) is returned by defaultFamily().
390 The font-matching algorithm has a lastResortFamily() and
391 lastResortFont() in cases where a suitable match cannot be found.
392 You can provide substitutions for font family names using
393 insertSubstitution() and insertSubstitutions(). Substitutions can
394 be removed with removeSubstitutions(). Use substitute() to retrieve
395 a family's first substitute, or the family name itself if it has
396 no substitutes. Use substitutes() to retrieve a list of a family's
397 substitutes (which may be empty).
399 Every QFont has a key() which you can use, for example, as the key
400 in a cache or dictionary. If you want to store a user's font
401 preferences you could use QSettings, writing the font information
402 with toString() and reading it back with fromString(). The
403 operator<<() and operator>>() functions are also available, but
404 they work on a data stream.
406 It is possible to set the height of characters shown on the screen
407 to a specified number of pixels with setPixelSize(); however using
408 setPointSize() has a similar effect and provides device
411 In X11 you can set a font using its system
412 specific name with setRawName().
414 Loading fonts can be expensive, especially on X11. QFont contains
415 extensive optimizations to make the copying of QFont objects fast,
416 and to cache the results of the slow window system functions it
420 The font matching algorithm works as follows:
422 \li The specified font family is searched for.
423 \li If not found, the styleHint() is used to select a replacement
425 \li Each replacement font family is searched for.
426 \li If none of these are found or there was no styleHint(), "helvetica"
427 will be searched for.
428 \li If "helvetica" isn't found Qt will try the lastResortFamily().
429 \li If the lastResortFamily() isn't found Qt will try the
430 lastResortFont() which will always return a name of some kind.
433 Note that the actual font matching algorithm varies from platform to platform.
435 In Windows a request for the "Courier" font is automatically changed to
436 "Courier New", an improved version of Courier that allows for smooth scaling.
437 The older "Courier" bitmap font can be selected by setting the PreferBitmap
438 style strategy (see setStyleStrategy()).
440 Once a font is found, the remaining attributes are matched in order of
444 \li pointSize() (see below)
449 If you have a font which matches on family, even if none of the
450 other attributes match, this font will be chosen in preference to
451 a font which doesn't match on family but which does match on the
452 other attributes. This is because font family is the dominant
455 The point size is defined to match if it is within 20% of the
456 requested point size. When several fonts match and are only
457 distinguished by point size, the font with the closest point size
458 to the one requested will be chosen.
460 The actual family, font size, weight and other font attributes
461 used for drawing text will depend on what's available for the
462 chosen family under the window system. A QFontInfo object can be
463 used to determine the actual values used for drawing the text.
467 \snippet code/src_gui_text_qfont.cpp 1
468 If you had both an Adobe and a Cronyx Helvetica, you might get
471 \snippet code/src_gui_text_qfont.cpp 2
473 You can specify the foundry you want in the family name. The font f
474 in the above example will be set to "Helvetica
477 To determine the attributes of the font actually used in the window
478 system, use a QFontInfo object, e.g.
480 \snippet code/src_gui_text_qfont.cpp 3
482 To find out font metrics use a QFontMetrics object, e.g.
484 \snippet code/src_gui_text_qfont.cpp 4
486 For more general information on fonts, see the
487 \l{comp.fonts FAQ}{comp.fonts FAQ}.
488 Information on encodings can be found from
489 \l{Roman Czyborra's} page.
491 \sa QFontComboBox, QFontMetrics, QFontInfo, QFontDatabase, {Character Map Example}
496 \enum QFont::ResolveProperties
498 This enum describes the properties of a QFont that can be set on a font
499 individually and then considered resolved.
501 \value FamilyResolved
503 \value StyleHintResolved
504 \value StyleStrategyResolved
505 \value WeightResolved
507 \value UnderlineResolved
508 \value OverlineResolved
509 \value StrikeOutResolved
510 \value FixedPitchResolved
511 \value StretchResolved
512 \value KerningResolved
513 \value CapitalizationResolved
514 \value LetterSpacingResolved
515 \value WordSpacingResolved
516 \value CompletelyResolved
522 This enum describes the different styles of glyphs that are used to
525 \value StyleNormal Normal glyphs used in unstyled text.
526 \value StyleItalic Italic glyphs that are specifically designed for
527 the purpose of representing italicized text.
528 \value StyleOblique Glyphs with an italic appearance that are typically
529 based on the unstyled glyphs, but are not fine-tuned
530 for the purpose of representing italicized text.
536 \fn Qt::HANDLE QFont::handle() const
538 Returns the window system handle to the font, for low-level
539 access. Using this function is \e not portable.
543 \fn FT_Face QFont::freetypeFace() const
545 Returns the handle to the primary FreeType face of the font. If font merging is not disabled a
546 QFont can contain several physical fonts.
548 Returns 0 if the font does not contain a FreeType face.
550 \note This function is only available on platforms that provide the FreeType library;
551 i.e., X11 and some Embedded Linux platforms.
555 \fn QString QFont::rawName() const
557 Returns the name of the font within the underlying window system.
559 On X11, this function will return an empty string if Qt is built with
560 FontConfig support; otherwise the XLFD (X Logical Font Description) is
563 Using the return value of this function is usually \e not \e
570 \fn void QFont::setRawName(const QString &name)
572 Sets a font by its system specific name. The function is
573 particularly useful under X, where system font settings (for
574 example X resources) are usually available in XLFD (X Logical Font
575 Description) form only. You can pass an XLFD as \a name to this
578 A font set with setRawName() is still a full-featured QFont. It can
579 be queried (for example with italic()) or modified (for example with
580 setItalic()) and is therefore also suitable for rendering rich text.
582 If Qt's internal font database cannot resolve the raw name, the
583 font becomes a raw font with \a name as its family.
585 Note that the present implementation does not handle wildcards in
586 XLFDs well, and that font aliases (file \c fonts.alias in the font
587 directory on X11) are not supported.
589 \sa rawName(), setRawMode(), setFamily()
593 \fn QString QFont::lastResortFamily() const
595 Returns the "last resort" font family name.
597 The current implementation tries a wide variety of common fonts,
598 returning the first one it finds. Is is possible that no family is
599 found in which case an empty string is returned.
605 \fn QString QFont::defaultFamily() const
607 Returns the family name that corresponds to the current style
610 \sa StyleHint, styleHint(), setStyleHint()
614 \fn QString QFont::lastResortFont() const
616 Returns a "last resort" font name for the font matching algorithm.
617 This is used if the last resort family is not available. It will
618 always return a name, if necessary returning something like
621 The current implementation tries a wide variety of common fonts,
622 returning the first one it finds. The implementation may change
623 at any time, but this function will always return a string
624 containing something.
626 It is theoretically possible that there really isn't a
627 lastResortFont() in which case Qt will abort with an error
628 message. We have not been able to identify a case where this
629 happens. Please \l{bughowto.html}{report it as a bug} if
630 it does, preferably with a list of the fonts you have installed.
632 \sa lastResortFamily(), rawName()
636 Constructs a font from \a font for use on the paint device \a pd.
638 QFont::QFont(const QFont &font, QPaintDevice *pd)
639 : resolve_mask(font.resolve_mask)
642 int dpi = pd->logicalDpiY();
643 const int screen = 0;
644 if (font.d->dpi != dpi || font.d->screen != screen ) {
645 d = new QFontPrivate(*font.d);
656 QFont::QFont(QFontPrivate *data)
657 : d(data), resolve_mask(QFont::AllPropertiesResolved)
662 Detaches the font object from common font data.
666 if (d->ref.load() == 1) {
668 d->engineData->ref.deref();
670 if (d->scFont && d->scFont != d.data())
671 d->scFont->ref.deref();
680 Constructs a font object that uses the application's default font.
682 \sa QGuiApplication::setFont(), QGuiApplication::font()
685 : d(QGuiApplication::font().d.data()), resolve_mask(0)
690 Constructs a font object with the specified \a family, \a
691 pointSize, \a weight and \a italic settings.
693 If \a pointSize is zero or negative, the point size of the font
694 is set to a system-dependent default value. Generally, this is
697 The \a family name may optionally also include a foundry name,
698 e.g. "Helvetica [Cronyx]". If the \a family is
699 available from more than one foundry and the foundry isn't
700 specified, an arbitrary foundry is chosen. If the family isn't
701 available a family will be set using the \l{QFont}{font matching}
704 \sa Weight, setFamily(), setPointSize(), setWeight(), setItalic(),
705 setStyleHint(), QGuiApplication::font()
707 QFont::QFont(const QString &family, int pointSize, int weight, bool italic)
708 : d(new QFontPrivate()), resolve_mask(QFont::FamilyResolved)
710 if (pointSize <= 0) {
713 resolve_mask |= QFont::SizeResolved;
719 resolve_mask |= QFont::WeightResolved | QFont::StyleResolved;
723 resolve_mask |= QFont::StyleResolved;
725 d->request.family = family;
726 d->request.pointSize = qreal(pointSize);
727 d->request.pixelSize = -1;
728 d->request.weight = weight;
729 d->request.style = italic ? QFont::StyleItalic : QFont::StyleNormal;
733 Constructs a font that is a copy of \a font.
735 QFont::QFont(const QFont &font)
736 : d(font.d.data()), resolve_mask(font.resolve_mask)
741 Destroys the font object and frees all allocated resources.
748 Assigns \a font to this font and returns a reference to it.
750 QFont &QFont::operator=(const QFont &font)
753 resolve_mask = font.resolve_mask;
758 Returns the requested font family name, i.e. the name set in the
759 constructor or the last setFont() call.
761 \sa setFamily(), substitutes(), substitute()
763 QString QFont::family() const
765 return d->request.family;
769 Sets the family name of the font. The name is case insensitive and
770 may include a foundry name.
772 The \a family name may optionally also include a foundry name,
773 e.g. "Helvetica [Cronyx]". If the \a family is
774 available from more than one foundry and the foundry isn't
775 specified, an arbitrary foundry is chosen. If the family isn't
776 available a family will be set using the \l{QFont}{font matching}
779 \sa family(), setStyleHint(), QFontInfo
781 void QFont::setFamily(const QString &family)
785 d->request.family = family;
787 resolve_mask |= QFont::FamilyResolved;
793 Returns the requested font style name, it will be used to match the
794 font with irregular styles (that can't be normalized in other style
795 properties). It depends on system font support, thus only works for
796 Mac OS X and X11 so far. On Windows irregular styles will be added
797 as separate font families so there is no need for this.
799 \sa setFamily(), setStyle()
801 QString QFont::styleName() const
803 return d->request.styleName;
809 Sets the style name of the font. When set, other style properties
810 like \a style() and \a weight() will be ignored for font matching.
814 void QFont::setStyleName(const QString &styleName)
818 d->request.styleName = styleName;
819 resolve_mask |= QFont::StyleNameResolved;
823 Returns the point size of the font. Returns -1 if the font size
824 was specified in pixels.
826 \sa setPointSize(), pointSizeF()
828 int QFont::pointSize() const
830 return qRound(d->request.pointSize);
836 \enum QFont::HintingPreference
838 This enum describes the different levels of hinting that can be applied
839 to glyphs to improve legibility on displays where it might be warranted
840 by the density of pixels.
842 \value PreferDefaultHinting Use the default hinting level for the target platform.
843 \value PreferNoHinting If possible, render text without hinting the outlines
844 of the glyphs. The text layout will be typographically accurate and
845 scalable, using the same metrics as are used e.g. when printing.
846 \value PreferVerticalHinting If possible, render text with no horizontal hinting,
847 but align glyphs to the pixel grid in the vertical direction. The text will appear
848 crisper on displays where the density is too low to give an accurate rendering
849 of the glyphs. But since the horizontal metrics of the glyphs are unhinted, the text's
850 layout will be scalable to higher density devices (such as printers) without impacting
851 details such as line breaks.
852 \value PreferFullHinting If possible, render text with hinting in both horizontal and
853 vertical directions. The text will be altered to optimize legibility on the target
854 device, but since the metrics will depend on the target size of the text, the positions
855 of glyphs, line breaks, and other typographical detail will not scale, meaning that a
856 text layout may look different on devices with different pixel densities.
858 Please note that this enum only describes a preference, as the full range of hinting levels
859 are not supported on all of Qt's supported platforms. The following table details the effect
860 of a given hinting preference on a selected set of target platforms.
865 \li PreferDefaultHinting
867 \li PreferVerticalHinting
868 \li PreferFullHinting
870 \li Windows Vista (w/o Platform Update) and earlier
876 \li Windows 7 and Windows Vista (w/Platform Update) and DirectWrite enabled in Qt
883 \li Operating System setting
885 \li Vertical hinting (light)
888 \li Cocoa on Mac OS X
895 \note Please be aware that altering the hinting preference on Windows is available through
896 the DirectWrite font engine. This is available on Windows Vista after installing the platform
897 update, and on Windows 7. In order to use this extension, configure Qt using -directwrite.
898 The target application will then depend on the availability of DirectWrite on the target
906 Set the preference for the hinting level of the glyphs to \a hintingPreference. This is a hint
907 to the underlying font rendering system to use a certain level of hinting, and has varying
908 support across platforms. See the table in the documentation for QFont::HintingPreference for
911 The default hinting preference is QFont::PreferDefaultHinting.
913 void QFont::setHintingPreference(HintingPreference hintingPreference)
917 d->request.hintingPreference = hintingPreference;
919 resolve_mask |= QFont::HintingPreferenceResolved;
925 Returns the currently preferred hinting level for glyphs rendered with this font.
927 QFont::HintingPreference QFont::hintingPreference() const
929 return QFont::HintingPreference(d->request.hintingPreference);
933 Sets the point size to \a pointSize. The point size must be
936 \sa pointSize(), setPointSizeF()
938 void QFont::setPointSize(int pointSize)
940 if (pointSize <= 0) {
941 qWarning("QFont::setPointSize: Point size <= 0 (%d), must be greater than 0", pointSize);
947 d->request.pointSize = qreal(pointSize);
948 d->request.pixelSize = -1;
950 resolve_mask |= QFont::SizeResolved;
954 Sets the point size to \a pointSize. The point size must be
955 greater than zero. The requested precision may not be achieved on
958 \sa pointSizeF(), setPointSize(), setPixelSize()
960 void QFont::setPointSizeF(qreal pointSize)
962 if (pointSize <= 0) {
963 qWarning("QFont::setPointSizeF: Point size <= 0 (%f), must be greater than 0", pointSize);
969 d->request.pointSize = pointSize;
970 d->request.pixelSize = -1;
972 resolve_mask |= QFont::SizeResolved;
976 Returns the point size of the font. Returns -1 if the font size was
979 \sa pointSize(), setPointSizeF(), pixelSize(), QFontInfo::pointSize(), QFontInfo::pixelSize()
981 qreal QFont::pointSizeF() const
983 return d->request.pointSize;
987 Sets the font size to \a pixelSize pixels.
989 Using this function makes the font device dependent. Use
990 setPointSize() or setPointSizeF() to set the size of the font
991 in a device independent manner.
995 void QFont::setPixelSize(int pixelSize)
997 if (pixelSize <= 0) {
998 qWarning("QFont::setPixelSize: Pixel size <= 0 (%d)", pixelSize);
1004 d->request.pixelSize = pixelSize;
1005 d->request.pointSize = -1;
1007 resolve_mask |= QFont::SizeResolved;
1011 Returns the pixel size of the font if it was set with
1012 setPixelSize(). Returns -1 if the size was set with setPointSize()
1015 \sa setPixelSize(), pointSize(), QFontInfo::pointSize(), QFontInfo::pixelSize()
1017 int QFont::pixelSize() const
1019 return d->request.pixelSize;
1023 \fn bool QFont::italic() const
1025 Returns true if the style() of the font is not QFont::StyleNormal
1027 \sa setItalic(), style()
1031 \fn void QFont::setItalic(bool enable)
1033 Sets the style() of the font to QFont::StyleItalic if \a enable is true;
1034 otherwise the style is set to QFont::StyleNormal.
1036 \sa italic(), QFontInfo
1040 Returns the style of the font.
1044 QFont::Style QFont::style() const
1046 return (QFont::Style)d->request.style;
1051 Sets the style of the font to \a style.
1053 \sa italic(), QFontInfo
1055 void QFont::setStyle(Style style)
1059 d->request.style = style;
1060 resolve_mask |= QFont::StyleResolved;
1064 Returns the weight of the font which is one of the enumerated
1065 values from \l{QFont::Weight}.
1067 \sa setWeight(), Weight, QFontInfo
1069 int QFont::weight() const
1071 return d->request.weight;
1077 Qt uses a weighting scale from 0 to 99 similar to, but not the
1078 same as, the scales used in Windows or CSS. A weight of 0 is
1079 ultralight, whilst 99 will be an extremely black.
1081 This enum contains the predefined font weights:
1091 Sets the weight the font to \a weight, which should be a value
1092 from the \l QFont::Weight enumeration.
1094 \sa weight(), QFontInfo
1096 void QFont::setWeight(int weight)
1098 Q_ASSERT_X(weight >= 0 && weight <= 99, "QFont::setWeight", "Weight must be between 0 and 99");
1102 d->request.weight = weight;
1103 resolve_mask |= QFont::WeightResolved;
1107 \fn bool QFont::bold() const
1109 Returns true if weight() is a value greater than
1110 \l{Weight}{QFont::Normal}; otherwise returns false.
1112 \sa weight(), setBold(), QFontInfo::bold()
1116 \fn void QFont::setBold(bool enable)
1118 If \a enable is true sets the font's weight to
1119 \l{Weight}{QFont::Bold};
1120 otherwise sets the weight to \l{Weight}{QFont::Normal}.
1122 For finer boldness control use setWeight().
1124 \sa bold(), setWeight()
1128 Returns true if underline has been set; otherwise returns false.
1132 bool QFont::underline() const
1134 return d->underline;
1138 If \a enable is true, sets underline on; otherwise sets underline
1141 \sa underline(), QFontInfo
1143 void QFont::setUnderline(bool enable)
1147 d->underline = enable;
1148 resolve_mask |= QFont::UnderlineResolved;
1152 Returns true if overline has been set; otherwise returns false.
1156 bool QFont::overline() const
1162 If \a enable is true, sets overline on; otherwise sets overline off.
1164 \sa overline(), QFontInfo
1166 void QFont::setOverline(bool enable)
1170 d->overline = enable;
1171 resolve_mask |= QFont::OverlineResolved;
1175 Returns true if strikeout has been set; otherwise returns false.
1179 bool QFont::strikeOut() const
1181 return d->strikeOut;
1185 If \a enable is true, sets strikeout on; otherwise sets strikeout
1188 \sa strikeOut(), QFontInfo
1190 void QFont::setStrikeOut(bool enable)
1194 d->strikeOut = enable;
1195 resolve_mask |= QFont::StrikeOutResolved;
1199 Returns true if fixed pitch has been set; otherwise returns false.
1201 \sa setFixedPitch(), QFontInfo::fixedPitch()
1203 bool QFont::fixedPitch() const
1205 return d->request.fixedPitch;
1209 If \a enable is true, sets fixed pitch on; otherwise sets fixed
1212 \sa fixedPitch(), QFontInfo
1214 void QFont::setFixedPitch(bool enable)
1218 d->request.fixedPitch = enable;
1219 d->request.ignorePitch = false;
1220 resolve_mask |= QFont::FixedPitchResolved;
1224 Returns true if kerning should be used when drawing text with this font.
1228 bool QFont::kerning() const
1234 Enables kerning for this font if \a enable is true; otherwise
1235 disables it. By default, kerning is enabled.
1237 When kerning is enabled, glyph metrics do not add up anymore,
1238 even for Latin text. In other words, the assumption that
1239 width('a') + width('b') is equal to width("ab") is not
1242 \sa kerning(), QFontMetrics
1244 void QFont::setKerning(bool enable)
1247 d->kerning = enable;
1248 resolve_mask |= QFont::KerningResolved;
1252 Returns the StyleStrategy.
1254 The style strategy affects the \l{QFont}{font matching} algorithm.
1255 See \l QFont::StyleStrategy for the list of available strategies.
1257 \sa setStyleHint(), QFont::StyleHint
1259 QFont::StyleStrategy QFont::styleStrategy() const
1261 return (StyleStrategy) d->request.styleStrategy;
1265 Returns the StyleHint.
1267 The style hint affects the \l{QFont}{font matching} algorithm.
1268 See \l QFont::StyleHint for the list of available hints.
1270 \sa setStyleHint(), QFont::StyleStrategy, QFontInfo::styleHint()
1272 QFont::StyleHint QFont::styleHint() const
1274 return (StyleHint) d->request.styleHint;
1278 \enum QFont::StyleHint
1280 Style hints are used by the \l{QFont}{font matching} algorithm to
1281 find an appropriate default family if a selected font family is
1284 \value AnyStyle leaves the font matching algorithm to choose the
1285 family. This is the default.
1287 \value SansSerif the font matcher prefer sans serif fonts.
1288 \value Helvetica is a synonym for \c SansSerif.
1290 \value Serif the font matcher prefers serif fonts.
1291 \value Times is a synonym for \c Serif.
1293 \value TypeWriter the font matcher prefers fixed pitch fonts.
1294 \value Courier a synonym for \c TypeWriter.
1296 \value OldEnglish the font matcher prefers decorative fonts.
1297 \value Decorative is a synonym for \c OldEnglish.
1299 \value Monospace the font matcher prefers fonts that map to the
1300 CSS generic font-family 'monospace'.
1302 \value Fantasy the font matcher prefers fonts that map to the
1303 CSS generic font-family 'fantasy'.
1305 \value Cursive the font matcher prefers fonts that map to the
1306 CSS generic font-family 'cursive'.
1308 \value System the font matcher prefers system fonts.
1312 \enum QFont::StyleStrategy
1314 The style strategy tells the \l{QFont}{font matching} algorithm
1315 what type of fonts should be used to find an appropriate default
1318 The following strategies are available:
1320 \value PreferDefault the default style strategy. It does not prefer
1322 \value PreferBitmap prefers bitmap fonts (as opposed to outline
1324 \value PreferDevice prefers device fonts.
1325 \value PreferOutline prefers outline fonts (as opposed to bitmap fonts).
1326 \value ForceOutline forces the use of outline fonts.
1327 \value NoAntialias don't antialias the fonts.
1328 \value PreferAntialias antialias if possible.
1329 \value OpenGLCompatible forces the use of OpenGL compatible
1331 \value NoFontMerging If the font selected for a certain writing system
1332 does not contain a character requested to draw, then Qt automatically chooses a similar
1333 looking font that contains the character. The NoFontMerging flag disables this feature.
1334 Please note that enabling this flag will not prevent Qt from automatically picking a
1335 suitable font when the selected font does not support the writing system of the text.
1337 Any of these may be OR-ed with one of these flags:
1339 \value PreferMatch prefer an exact match. The font matcher will try to
1340 use the exact font size that has been specified.
1341 \value PreferQuality prefer the best quality font. The font matcher
1342 will use the nearest standard point size that the font
1344 \value ForceIntegerMetrics forces the use of integer values in font engines that support fractional
1349 Sets the style hint and strategy to \a hint and \a strategy,
1352 If these aren't set explicitly the style hint will default to
1353 \c AnyStyle and the style strategy to \c PreferDefault.
1355 Qt does not support style hints on X11 since this information
1356 is not provided by the window system.
1358 \sa StyleHint, styleHint(), StyleStrategy, styleStrategy(), QFontInfo
1360 void QFont::setStyleHint(StyleHint hint, StyleStrategy strategy)
1364 if ((resolve_mask & (QFont::StyleHintResolved | QFont::StyleStrategyResolved)) &&
1365 (StyleHint) d->request.styleHint == hint &&
1366 (StyleStrategy) d->request.styleStrategy == strategy)
1369 d->request.styleHint = hint;
1370 d->request.styleStrategy = strategy;
1371 resolve_mask |= QFont::StyleHintResolved;
1372 resolve_mask |= QFont::StyleStrategyResolved;
1377 Sets the style strategy for the font to \a s.
1379 \sa QFont::StyleStrategy
1381 void QFont::setStyleStrategy(StyleStrategy s)
1385 if ((resolve_mask & QFont::StyleStrategyResolved) &&
1386 s == (StyleStrategy)d->request.styleStrategy)
1389 d->request.styleStrategy = s;
1390 resolve_mask |= QFont::StyleStrategyResolved;
1395 \enum QFont::Stretch
1397 Predefined stretch values that follow the CSS naming convention. The higher
1398 the value, the more stretched the text is.
1400 \value UltraCondensed 50
1401 \value ExtraCondensed 62
1403 \value SemiCondensed 87
1404 \value Unstretched 100
1405 \value SemiExpanded 112
1407 \value ExtraExpanded 150
1408 \value UltraExpanded 200
1410 \sa setStretch(), stretch()
1414 Returns the stretch factor for the font.
1418 int QFont::stretch() const
1420 return d->request.stretch;
1424 Sets the stretch factor for the font.
1426 The stretch factor changes the width of all characters in the font
1427 by \a factor percent. For example, setting \a factor to 150
1428 results in all characters in the font being 1.5 times (ie. 150%)
1429 wider. The default stretch factor is 100. The minimum stretch
1430 factor is 1, and the maximum stretch factor is 4000.
1432 The stretch factor is only applied to outline fonts. The stretch
1433 factor is ignored for bitmap fonts.
1435 NOTE: QFont cannot stretch XLFD fonts. When loading XLFD fonts on
1436 X11, the stretch factor is matched against a predefined set of
1437 values for the SETWIDTH_NAME field of the XLFD.
1439 \sa stretch(), QFont::Stretch
1441 void QFont::setStretch(int factor)
1443 if (factor < 1 || factor > 4000) {
1444 qWarning("QFont::setStretch: Parameter '%d' out of range", factor);
1448 if ((resolve_mask & QFont::StretchResolved) &&
1449 d->request.stretch == (uint)factor)
1454 d->request.stretch = (uint)factor;
1455 resolve_mask |= QFont::StretchResolved;
1459 \enum QFont::SpacingType
1462 \value PercentageSpacing A value of 100 will keep the spacing unchanged; a value of 200 will enlarge the
1463 spacing after a character by the width of the character itself.
1464 \value AbsoluteSpacing A positive value increases the letter spacing by the corresponding pixels; a negative
1465 value decreases the spacing.
1470 Returns the letter spacing for the font.
1472 \sa setLetterSpacing(), letterSpacingType(), setWordSpacing()
1474 qreal QFont::letterSpacing() const
1476 return d->letterSpacing.toReal();
1481 Sets the letter spacing for the font to \a spacing and the type
1482 of spacing to \a type.
1484 Letter spacing changes the default spacing between individual
1485 letters in the font. The spacing between the letters can be
1486 made smaller as well as larger.
1488 \sa letterSpacing(), letterSpacingType(), setWordSpacing()
1490 void QFont::setLetterSpacing(SpacingType type, qreal spacing)
1492 const QFixed newSpacing = QFixed::fromReal(spacing);
1493 const bool absoluteSpacing = type == AbsoluteSpacing;
1494 if ((resolve_mask & QFont::LetterSpacingResolved) &&
1495 d->letterSpacingIsAbsolute == absoluteSpacing &&
1496 d->letterSpacing == newSpacing)
1501 d->letterSpacing = newSpacing;
1502 d->letterSpacingIsAbsolute = absoluteSpacing;
1503 resolve_mask |= QFont::LetterSpacingResolved;
1508 Returns the spacing type used for letter spacing.
1510 \sa letterSpacing(), setLetterSpacing(), setWordSpacing()
1512 QFont::SpacingType QFont::letterSpacingType() const
1514 return d->letterSpacingIsAbsolute ? AbsoluteSpacing : PercentageSpacing;
1519 Returns the word spacing for the font.
1521 \sa setWordSpacing(), setLetterSpacing()
1523 qreal QFont::wordSpacing() const
1525 return d->wordSpacing.toReal();
1530 Sets the word spacing for the font to \a spacing.
1532 Word spacing changes the default spacing between individual
1533 words. A positive value increases the word spacing
1534 by a corresponding amount of pixels, while a negative value
1535 decreases the inter-word spacing accordingly.
1537 Word spacing will not apply to writing systems, where indiviaul
1538 words are not separated by white space.
1540 \sa wordSpacing(), setLetterSpacing()
1542 void QFont::setWordSpacing(qreal spacing)
1544 const QFixed newSpacing = QFixed::fromReal(spacing);
1545 if ((resolve_mask & QFont::WordSpacingResolved) &&
1546 d->wordSpacing == newSpacing)
1551 d->wordSpacing = newSpacing;
1552 resolve_mask |= QFont::WordSpacingResolved;
1556 \enum QFont::Capitalization
1559 Rendering option for text this font applies to.
1562 \value MixedCase This is the normal text rendering option where no capitalization change is applied.
1563 \value AllUppercase This alters the text to be rendered in all uppercase type.
1564 \value AllLowercase This alters the text to be rendered in all lowercase type.
1565 \value SmallCaps This alters the text to be rendered in small-caps type.
1566 \value Capitalize This alters the text to be rendered with the first character of each word as an uppercase character.
1571 Sets the capitalization of the text in this font to \a caps.
1573 A font's capitalization makes the text appear in the selected capitalization mode.
1575 \sa capitalization()
1577 void QFont::setCapitalization(Capitalization caps)
1579 if ((resolve_mask & QFont::CapitalizationResolved) &&
1580 capitalization() == caps)
1586 resolve_mask |= QFont::CapitalizationResolved;
1591 Returns the current capitalization type of the font.
1593 \sa setCapitalization()
1595 QFont::Capitalization QFont::capitalization() const
1597 return static_cast<QFont::Capitalization> (d->capital);
1602 If \a enable is true, turns raw mode on; otherwise turns raw mode
1603 off. This function only has an effect under X11.
1605 If raw mode is enabled, Qt will search for an X font with a
1606 complete font name matching the family name, ignoring all other
1607 values set for the QFont. If the font name matches several fonts,
1608 Qt will use the first font returned by X. QFontInfo \e cannot be
1609 used to fetch information about a QFont using raw mode (it will
1610 return the values set in the QFont for all parameters, including
1613 \warning Do not use raw mode unless you really, really need it! In
1614 most (if not all) cases, setRawName() is a much better choice.
1616 \sa rawMode(), setRawName()
1618 void QFont::setRawMode(bool enable)
1622 if ((bool) d->rawMode == enable) return;
1624 d->rawMode = enable;
1628 Returns true if a window system font exactly matching the settings
1629 of this font is available.
1633 bool QFont::exactMatch() const
1635 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1636 Q_ASSERT(engine != 0);
1638 ? engine->type() != QFontEngine::Box
1639 : d->request.exactMatch(engine->fontDef));
1643 Returns true if this font is equal to \a f; otherwise returns
1646 Two QFonts are considered equal if their font attributes are
1647 equal. If rawMode() is enabled for both fonts, only the family
1648 fields are compared.
1650 \sa operator!=(), isCopyOf()
1652 bool QFont::operator==(const QFont &f) const
1655 || (f.d->request == d->request
1656 && f.d->request.pointSize == d->request.pointSize
1657 && f.d->underline == d->underline
1658 && f.d->overline == d->overline
1659 && f.d->strikeOut == d->strikeOut
1660 && f.d->kerning == d->kerning
1661 && f.d->capital == d->capital
1662 && f.d->letterSpacingIsAbsolute == d->letterSpacingIsAbsolute
1663 && f.d->letterSpacing == d->letterSpacing
1664 && f.d->wordSpacing == d->wordSpacing
1670 Provides an arbitrary comparison of this font and font \a f.
1671 All that is guaranteed is that the operator returns false if both
1672 fonts are equal and that (f1 \< f2) == !(f2 \< f1) if the fonts
1675 This function is useful in some circumstances, for example if you
1676 want to use QFont objects as keys in a QMap.
1678 \sa operator==(), operator!=(), isCopyOf()
1680 bool QFont::operator<(const QFont &f) const
1682 if (f.d == d) return false;
1683 // the < operator for fontdefs ignores point sizes.
1684 QFontDef &r1 = f.d->request;
1685 QFontDef &r2 = d->request;
1686 if (r1.pointSize != r2.pointSize) return r1.pointSize < r2.pointSize;
1687 if (r1.pixelSize != r2.pixelSize) return r1.pixelSize < r2.pixelSize;
1688 if (r1.weight != r2.weight) return r1.weight < r2.weight;
1689 if (r1.style != r2.style) return r1.style < r2.style;
1690 if (r1.stretch != r2.stretch) return r1.stretch < r2.stretch;
1691 if (r1.styleHint != r2.styleHint) return r1.styleHint < r2.styleHint;
1692 if (r1.styleStrategy != r2.styleStrategy) return r1.styleStrategy < r2.styleStrategy;
1693 if (r1.family != r2.family) return r1.family < r2.family;
1694 if (f.d->capital != d->capital) return f.d->capital < d->capital;
1696 if (f.d->letterSpacingIsAbsolute != d->letterSpacingIsAbsolute) return f.d->letterSpacingIsAbsolute < d->letterSpacingIsAbsolute;
1697 if (f.d->letterSpacing != d->letterSpacing) return f.d->letterSpacing < d->letterSpacing;
1698 if (f.d->wordSpacing != d->wordSpacing) return f.d->wordSpacing < d->wordSpacing;
1700 int f1attrs = (f.d->underline << 3) + (f.d->overline << 2) + (f.d->strikeOut<<1) + f.d->kerning;
1701 int f2attrs = (d->underline << 3) + (d->overline << 2) + (d->strikeOut<<1) + d->kerning;
1702 return f1attrs < f2attrs;
1707 Returns true if this font is different from \a f; otherwise
1710 Two QFonts are considered to be different if their font attributes
1711 are different. If rawMode() is enabled for both fonts, only the
1712 family fields are compared.
1716 bool QFont::operator!=(const QFont &f) const
1718 return !(operator==(f));
1722 Returns the font as a QVariant
1724 QFont::operator QVariant() const
1726 return QVariant(QVariant::Font, this);
1730 Returns true if this font and \a f are copies of each other, i.e.
1731 one of them was created as a copy of the other and neither has
1732 been modified since. This is much stricter than equality.
1734 \sa operator=(), operator==()
1736 bool QFont::isCopyOf(const QFont & f) const
1742 Returns true if raw mode is used for font name matching; otherwise
1745 \sa setRawMode(), rawName()
1747 bool QFont::rawMode() const
1753 Returns a new QFont that has attributes copied from \a other that
1754 have not been previously set on this font.
1756 QFont QFont::resolve(const QFont &other) const
1759 && (resolve_mask == other.resolve_mask || resolve_mask == 0)
1760 && d->dpi == other.d->dpi) {
1762 o.resolve_mask = resolve_mask;
1768 font.d->resolve(resolve_mask, other.d.data());
1774 \fn uint QFont::resolve() const
1779 \fn void QFont::resolve(uint mask)
1784 /*****************************************************************************
1785 QFont substitution management
1786 *****************************************************************************/
1788 typedef QHash<QString, QStringList> QFontSubst;
1789 Q_GLOBAL_STATIC(QFontSubst, globalFontSubst)
1792 Returns the first family name to be used whenever \a familyName is
1793 specified. The lookup is case insensitive.
1795 If there is no substitution for \a familyName, \a familyName is
1798 To obtain a list of substitutions use substitutes().
1800 \sa setFamily(), insertSubstitutions(), insertSubstitution(), removeSubstitutions()
1802 QString QFont::substitute(const QString &familyName)
1804 QFontSubst *fontSubst = globalFontSubst();
1805 Q_ASSERT(fontSubst != 0);
1806 QFontSubst::ConstIterator it = fontSubst->constFind(familyName.toLower());
1807 if (it != fontSubst->constEnd() && !(*it).isEmpty())
1808 return (*it).first();
1815 Returns a list of family names to be used whenever \a familyName
1816 is specified. The lookup is case insensitive.
1818 If there is no substitution for \a familyName, an empty list is
1821 \sa substitute(), insertSubstitutions(), insertSubstitution(), removeSubstitutions()
1823 QStringList QFont::substitutes(const QString &familyName)
1825 QFontSubst *fontSubst = globalFontSubst();
1826 Q_ASSERT(fontSubst != 0);
1827 return fontSubst->value(familyName.toLower(), QStringList());
1832 Inserts \a substituteName into the substitution
1833 table for the family \a familyName.
1835 \sa insertSubstitutions(), removeSubstitutions(), substitutions(), substitute(), substitutes()
1837 void QFont::insertSubstitution(const QString &familyName,
1838 const QString &substituteName)
1840 QFontSubst *fontSubst = globalFontSubst();
1841 Q_ASSERT(fontSubst != 0);
1842 QStringList &list = (*fontSubst)[familyName.toLower()];
1843 QString s = substituteName.toLower();
1844 if (!list.contains(s))
1850 Inserts the list of families \a substituteNames into the
1851 substitution list for \a familyName.
1853 \sa insertSubstitution(), removeSubstitutions(), substitutions(), substitute()
1855 void QFont::insertSubstitutions(const QString &familyName,
1856 const QStringList &substituteNames)
1858 QFontSubst *fontSubst = globalFontSubst();
1859 Q_ASSERT(fontSubst != 0);
1860 QStringList &list = (*fontSubst)[familyName.toLower()];
1861 foreach (const QString &substituteName, substituteNames) {
1862 const QString lowerSubstituteName = substituteName.toLower();
1863 if (!list.contains(lowerSubstituteName))
1864 list.append(lowerSubstituteName);
1868 /*! \fn void QFont::initialize()
1871 Internal function that initializes the font system. The font cache
1872 and font dict do not alloc the keys. The key is a QString which is
1873 shared between QFontPrivate and QXFontName.
1876 /*! \fn void QFont::cleanup()
1879 Internal function that cleans up the font system.
1883 Removes all the substitutions for \a familyName.
1885 \sa insertSubstitutions(), insertSubstitution(), substitutions(), substitute()
1888 void QFont::removeSubstitutions(const QString &familyName)
1890 QFontSubst *fontSubst = globalFontSubst();
1891 Q_ASSERT(fontSubst != 0);
1892 fontSubst->remove(familyName.toLower());
1896 \fn void QFont::removeSubstitution(const QString &familyName)
1900 This function is deprecated. Use removeSubstitutions() instead.
1904 Returns a sorted list of substituted family names.
1906 \sa insertSubstitution(), removeSubstitution(), substitute()
1908 QStringList QFont::substitutions()
1910 typedef QFontSubst::const_iterator QFontSubstConstIterator;
1912 QFontSubst *fontSubst = globalFontSubst();
1913 Q_ASSERT(fontSubst != 0);
1915 const QFontSubstConstIterator cend = fontSubst->constEnd();
1916 for (QFontSubstConstIterator it = fontSubst->constBegin(); it != cend; ++it)
1917 ret.append(it.key());
1925 Internal function. Converts boolean font settings to an unsigned
1926 8-bit number. Used for serialization etc.
1928 static quint8 get_font_bits(int version, const QFontPrivate *f)
1932 if (f->request.style)
1940 if (f->request.fixedPitch)
1942 // if (f.hintSetByUser)
1946 if (version >= QDataStream::Qt_4_0) {
1950 if (f->request.style == QFont::StyleOblique)
1955 static quint8 get_extended_font_bits(const QFontPrivate *f)
1959 if (f->request.ignorePitch)
1961 if (f->letterSpacingIsAbsolute)
1966 #ifndef QT_NO_DATASTREAM
1969 Internal function. Sets boolean font settings from an unsigned
1970 8-bit number. Used for serialization etc.
1972 static void set_font_bits(int version, quint8 bits, QFontPrivate *f)
1975 f->request.style = (bits & 0x01) != 0 ? QFont::StyleItalic : QFont::StyleNormal;
1976 f->underline = (bits & 0x02) != 0;
1977 f->overline = (bits & 0x40) != 0;
1978 f->strikeOut = (bits & 0x04) != 0;
1979 f->request.fixedPitch = (bits & 0x08) != 0;
1980 // f->hintSetByUser = (bits & 0x10) != 0;
1981 f->rawMode = (bits & 0x20) != 0;
1982 if (version >= QDataStream::Qt_4_0)
1983 f->kerning = (bits & 0x10) != 0;
1984 if ((bits & 0x80) != 0)
1985 f->request.style = QFont::StyleOblique;
1988 static void set_extended_font_bits(quint8 bits, QFontPrivate *f)
1991 f->request.ignorePitch = (bits & 0x01) != 0;
1992 f->letterSpacingIsAbsolute = (bits & 0x02) != 0;
1998 Returns the font's key, a textual representation of a font. It is
1999 typically used as the key for a cache or dictionary of fonts.
2003 QString QFont::key() const
2009 Returns a description of the font. The description is a
2010 comma-separated list of the attributes, perfectly suited for use
2015 QString QFont::toString() const
2017 const QChar comma(QLatin1Char(','));
2018 return family() + comma +
2019 QString::number( pointSizeF()) + comma +
2020 QString::number( pixelSize()) + comma +
2021 QString::number((int) styleHint()) + comma +
2022 QString::number( weight()) + comma +
2023 QString::number((int) style()) + comma +
2024 QString::number((int) underline()) + comma +
2025 QString::number((int) strikeOut()) + comma +
2026 QString::number((int)fixedPitch()) + comma +
2027 QString::number((int) rawMode());
2032 Sets this font to match the description \a descrip. The description
2033 is a comma-separated list of the font attributes, as returned by
2038 bool QFont::fromString(const QString &descrip)
2040 QStringList l(descrip.split(QLatin1Char(',')));
2042 int count = l.count();
2043 if (!count || (count > 2 && count < 9) || count > 11) {
2044 qWarning("QFont::fromString: Invalid description '%s'",
2045 descrip.isEmpty() ? "(empty)" : descrip.toLatin1().data());
2050 if (count > 1 && l[1].toDouble() > 0.0)
2051 setPointSizeF(l[1].toDouble());
2053 setStyleHint((StyleHint) l[2].toInt());
2054 setWeight(qMax(qMin(99, l[3].toInt()), 0));
2055 setItalic(l[4].toInt());
2056 setUnderline(l[5].toInt());
2057 setStrikeOut(l[6].toInt());
2058 setFixedPitch(l[7].toInt());
2059 setRawMode(l[8].toInt());
2060 } else if (count == 10) {
2061 if (l[2].toInt() > 0)
2062 setPixelSize(l[2].toInt());
2063 setStyleHint((StyleHint) l[3].toInt());
2064 setWeight(qMax(qMin(99, l[4].toInt()), 0));
2065 setStyle((QFont::Style)l[5].toInt());
2066 setUnderline(l[6].toInt());
2067 setStrikeOut(l[7].toInt());
2068 setFixedPitch(l[8].toInt());
2069 setRawMode(l[9].toInt());
2071 if (count >= 9 && !d->request.fixedPitch) // assume 'false' fixedPitch equals default
2072 d->request.ignorePitch = true;
2079 Internal function that dumps font cache statistics.
2081 void QFont::cacheStatistics()
2089 /*****************************************************************************
2090 QFont stream functions
2091 *****************************************************************************/
2092 #ifndef QT_NO_DATASTREAM
2097 Writes the font \a font to the data stream \a s. (toString()
2098 writes to a text stream.)
2100 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2102 QDataStream &operator<<(QDataStream &s, const QFont &font)
2104 if (s.version() == 1) {
2105 s << font.d->request.family.toLatin1();
2107 s << font.d->request.family;
2110 if (s.version() >= QDataStream::Qt_4_0) {
2112 double pointSize = font.d->request.pointSize;
2113 qint32 pixelSize = font.d->request.pixelSize;
2116 } else if (s.version() <= 3) {
2117 qint16 pointSize = (qint16) (font.d->request.pointSize * 10);
2118 if (pointSize < 0) {
2119 pointSize = (qint16)QFontInfo(font).pointSize() * 10;
2123 s << (qint16) (font.d->request.pointSize * 10);
2124 s << (qint16) font.d->request.pixelSize;
2127 s << (quint8) font.d->request.styleHint;
2128 if (s.version() >= QDataStream::Qt_3_1)
2129 s << (quint8) font.d->request.styleStrategy;
2131 << (quint8) font.d->request.weight
2132 << get_font_bits(s.version(), font.d.data());
2133 if (s.version() >= QDataStream::Qt_4_3)
2134 s << (quint16)font.d->request.stretch;
2135 if (s.version() >= QDataStream::Qt_4_4)
2136 s << get_extended_font_bits(font.d.data());
2137 if (s.version() >= QDataStream::Qt_4_5) {
2138 s << font.d->letterSpacing.value();
2139 s << font.d->wordSpacing.value();
2148 Reads the font \a font from the data stream \a s. (fromString()
2149 reads from a text stream.)
2151 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2153 QDataStream &operator>>(QDataStream &s, QFont &font)
2155 font.d = new QFontPrivate;
2156 font.resolve_mask = QFont::AllPropertiesResolved;
2158 quint8 styleHint, styleStrategy = QFont::PreferDefault, charSet, weight, bits;
2160 if (s.version() == 1) {
2163 font.d->request.family = QString::fromLatin1(fam);
2165 s >> font.d->request.family;
2168 if (s.version() >= QDataStream::Qt_4_0) {
2174 font.d->request.pointSize = qreal(pointSize);
2175 font.d->request.pixelSize = pixelSize;
2177 qint16 pointSize, pixelSize = -1;
2179 if (s.version() >= 4)
2181 font.d->request.pointSize = qreal(pointSize / 10.);
2182 font.d->request.pixelSize = pixelSize;
2185 if (s.version() >= QDataStream::Qt_3_1)
2192 font.d->request.styleHint = styleHint;
2193 font.d->request.styleStrategy = styleStrategy;
2194 font.d->request.weight = weight;
2196 set_font_bits(s.version(), bits, font.d.data());
2198 if (s.version() >= QDataStream::Qt_4_3) {
2201 font.d->request.stretch = stretch;
2204 if (s.version() >= QDataStream::Qt_4_4) {
2205 quint8 extendedBits;
2207 set_extended_font_bits(extendedBits, font.d.data());
2209 if (s.version() >= QDataStream::Qt_4_5) {
2212 font.d->letterSpacing.setValue(value);
2214 font.d->wordSpacing.setValue(value);
2220 #endif // QT_NO_DATASTREAM
2223 /*****************************************************************************
2224 QFontInfo member functions
2225 *****************************************************************************/
2231 \brief The QFontInfo class provides general information about fonts.
2236 The QFontInfo class provides the same access functions as QFont,
2237 e.g. family(), pointSize(), italic(), weight(), fixedPitch(),
2238 styleHint() etc. But whilst the QFont access functions return the
2239 values that were set, a QFontInfo object returns the values that
2240 apply to the font that will actually be used to draw the text.
2242 For example, when the program asks for a 25pt Courier font on a
2243 machine that has a non-scalable 24pt Courier font, QFont will
2244 (normally) use the 24pt Courier for rendering. In this case,
2245 QFont::pointSize() returns 25 and QFontInfo::pointSize() returns
2248 There are three ways to create a QFontInfo object.
2250 \li Calling the QFontInfo constructor with a QFont creates a font
2251 info object for a screen-compatible font, i.e. the font cannot be
2252 a printer font. If the font is changed later, the font
2253 info object is \e not updated.
2255 (Note: If you use a printer font the values returned may be
2256 inaccurate. Printer fonts are not always accessible so the nearest
2257 screen font is used if a printer font is supplied.)
2259 \li QWidget::fontInfo() returns the font info for a widget's font.
2260 This is equivalent to calling QFontInfo(widget->font()). If the
2261 widget's font is changed later, the font info object is \e not
2264 \li QPainter::fontInfo() returns the font info for a painter's
2265 current font. If the painter's font is changed later, the font
2266 info object is \e not updated.
2269 \sa QFont, QFontMetrics, QFontDatabase
2273 Constructs a font info object for \a font.
2275 The font must be screen-compatible, i.e. a font you use when
2276 drawing text in \l{QWidget}{widgets} or \l{QPixmap}{pixmaps}, not QPicture or QPrinter.
2278 The font info object holds the information for the font that is
2279 passed in the constructor at the time it is created, and is not
2280 updated if the font's attributes are changed later.
2282 Use QPainter::fontInfo() to get the font info when painting.
2283 This will give correct results also when painting on paint device
2284 that is not screen-compatible.
2286 QFontInfo::QFontInfo(const QFont &font)
2292 Constructs a copy of \a fi.
2294 QFontInfo::QFontInfo(const QFontInfo &fi)
2300 Destroys the font info object.
2302 QFontInfo::~QFontInfo()
2307 Assigns the font info in \a fi.
2309 QFontInfo &QFontInfo::operator=(const QFontInfo &fi)
2316 Returns the family name of the matched window system font.
2320 QString QFontInfo::family() const
2322 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2323 Q_ASSERT(engine != 0);
2324 return engine->fontDef.family;
2330 Returns the style name of the matched window system font on
2331 system that supports it.
2333 \sa QFont::styleName()
2335 QString QFontInfo::styleName() const
2337 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2338 Q_ASSERT(engine != 0);
2339 return engine->fontDef.styleName;
2343 Returns the point size of the matched window system font.
2345 \sa pointSizeF(), QFont::pointSize()
2347 int QFontInfo::pointSize() const
2349 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2350 Q_ASSERT(engine != 0);
2351 return qRound(engine->fontDef.pointSize);
2355 Returns the point size of the matched window system font.
2357 \sa QFont::pointSizeF()
2359 qreal QFontInfo::pointSizeF() const
2361 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2362 Q_ASSERT(engine != 0);
2363 return engine->fontDef.pointSize;
2367 Returns the pixel size of the matched window system font.
2369 \sa QFont::pointSize()
2371 int QFontInfo::pixelSize() const
2373 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2374 Q_ASSERT(engine != 0);
2375 return engine->fontDef.pixelSize;
2379 Returns the italic value of the matched window system font.
2383 bool QFontInfo::italic() const
2385 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2386 Q_ASSERT(engine != 0);
2387 return engine->fontDef.style != QFont::StyleNormal;
2391 Returns the style value of the matched window system font.
2395 QFont::Style QFontInfo::style() const
2397 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2398 Q_ASSERT(engine != 0);
2399 return (QFont::Style)engine->fontDef.style;
2403 Returns the weight of the matched window system font.
2405 \sa QFont::weight(), bold()
2407 int QFontInfo::weight() const
2409 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2410 Q_ASSERT(engine != 0);
2411 return engine->fontDef.weight;
2416 \fn bool QFontInfo::bold() const
2418 Returns true if weight() would return a value greater than
2419 QFont::Normal; otherwise returns false.
2421 \sa weight(), QFont::bold()
2425 Returns the underline value of the matched window system font.
2427 \sa QFont::underline()
2431 Here we read the underline flag directly from the QFont.
2432 This is OK for X11 and for Windows because we always get what we want.
2434 bool QFontInfo::underline() const
2436 return d->underline;
2440 Returns the overline value of the matched window system font.
2442 \sa QFont::overline()
2446 Here we read the overline flag directly from the QFont.
2447 This is OK for X11 and for Windows because we always get what we want.
2449 bool QFontInfo::overline() const
2455 Returns the strikeout value of the matched window system font.
2457 \sa QFont::strikeOut()
2459 \internal Here we read the strikeOut flag directly from the QFont.
2460 This is OK for X11 and for Windows because we always get what we want.
2462 bool QFontInfo::strikeOut() const
2464 return d->strikeOut;
2468 Returns the fixed pitch value of the matched window system font.
2470 \sa QFont::fixedPitch()
2472 bool QFontInfo::fixedPitch() const
2474 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2475 Q_ASSERT(engine != 0);
2477 if (!engine->fontDef.fixedPitchComputed) {
2478 QChar ch[2] = { QLatin1Char('i'), QLatin1Char('m') };
2479 QGlyphLayoutArray<2> g;
2481 engine->stringToCMap(ch, 2, &g, &l, 0);
2482 engine->fontDef.fixedPitch = g.advances_x[0] == g.advances_x[1];
2483 engine->fontDef.fixedPitchComputed = true;
2486 return engine->fontDef.fixedPitch;
2490 Returns the style of the matched window system font.
2492 Currently only returns the style hint set in QFont.
2494 \sa QFont::styleHint(), QFont::StyleHint
2496 QFont::StyleHint QFontInfo::styleHint() const
2498 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2499 Q_ASSERT(engine != 0);
2500 return (QFont::StyleHint) engine->fontDef.styleHint;
2504 Returns true if the font is a raw mode font; otherwise returns
2507 If it is a raw mode font, all other functions in QFontInfo will
2508 return the same values set in the QFont, regardless of the font
2511 \sa QFont::rawMode()
2513 bool QFontInfo::rawMode() const
2519 Returns true if the matched window system font is exactly the same
2520 as the one specified by the font; otherwise returns false.
2522 \sa QFont::exactMatch()
2524 bool QFontInfo::exactMatch() const
2526 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2527 Q_ASSERT(engine != 0);
2529 ? engine->type() != QFontEngine::Box
2530 : d->request.exactMatch(engine->fontDef));
2536 // **********************************************************************
2538 // **********************************************************************
2540 #ifdef QFONTCACHE_DEBUG
2541 // fast timeouts for debugging
2542 static const int fast_timeout = 1000; // 1s
2543 static const int slow_timeout = 5000; // 5s
2545 static const int fast_timeout = 10000; // 10s
2546 static const int slow_timeout = 300000; // 5m
2547 #endif // QFONTCACHE_DEBUG
2549 const uint QFontCache::min_cost = 4*1024; // 4mb
2552 Q_GLOBAL_STATIC(QFontCache, theFontCache)
2554 QFontCache *QFontCache::instance()
2556 return theFontCache();
2559 void QFontCache::cleanup()
2563 Q_GLOBAL_STATIC(QThreadStorage<QFontCache *>, theFontCache)
2565 QFontCache *QFontCache::instance()
2567 QFontCache *&fontCache = theFontCache()->localData();
2569 fontCache = new QFontCache;
2573 void QFontCache::cleanup()
2575 QThreadStorage<QFontCache *> *cache = 0;
2577 cache = theFontCache();
2578 } QT_CATCH (const std::bad_alloc &) {
2579 // no cache - just ignore
2581 if (cache && cache->hasLocalData())
2582 cache->setLocalData(0);
2584 #endif // QT_NO_THREAD
2586 QFontCache::QFontCache()
2587 : QObject(), total_cost(0), max_cost(min_cost),
2588 current_timestamp(0), fast(false), timer_id(-1)
2592 QFontCache::~QFontCache()
2596 EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
2597 end = engineDataCache.constEnd();
2599 if (it.value()->ref.load() == 0)
2602 FC_DEBUG("QFontCache::~QFontCache: engineData %p still has refcount %d",
2603 it.value(), it.value()->ref.load());
2607 EngineCache::ConstIterator it = engineCache.constBegin(),
2608 end = engineCache.constEnd();
2610 if (--it.value().data->cache_count == 0) {
2611 if (it.value().data->ref.load() == 0) {
2612 FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %g %d %d %d)",
2613 it.value().data, it.key().script, it.key().def.pointSize,
2614 it.key().def.pixelSize, it.key().def.weight, it.key().def.style,
2615 it.key().def.fixedPitch);
2617 delete it.value().data;
2619 FC_DEBUG("QFontCache::~QFontCache: engine = %p still has refcount %d",
2620 it.value().data, it.value().data->ref.load());
2627 void QFontCache::clear()
2630 EngineDataCache::Iterator it = engineDataCache.begin(),
2631 end = engineDataCache.end();
2633 QFontEngineData *data = it.value();
2634 for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
2635 if (data->engines[i]) {
2636 data->engines[i]->ref.deref();
2637 data->engines[i] = 0;
2644 for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
2646 if (it->data->ref.load() == 0) {
2652 for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
2654 if (it->data && it->data->ref.load() == 0) {
2660 engineCache.clear();
2664 QFontEngineData *QFontCache::findEngineData(const QFontDef &def) const
2666 EngineDataCache::ConstIterator it = engineDataCache.find(def),
2667 end = engineDataCache.end();
2668 if (it == end) return 0;
2674 void QFontCache::insertEngineData(const QFontDef &def, QFontEngineData *engineData)
2676 FC_DEBUG("QFontCache: inserting new engine data %p", engineData);
2678 engineDataCache.insert(def, engineData);
2679 increaseCost(sizeof(QFontEngineData));
2682 QFontEngine *QFontCache::findEngine(const Key &key)
2684 EngineCache::Iterator it = engineCache.find(key),
2685 end = engineCache.end();
2686 if (it == end) return 0;
2687 // found... update the hitcount and timestamp
2688 updateHitCountAndTimeStamp(it.value());
2690 return it.value().data;
2693 void QFontCache::updateHitCountAndTimeStamp(Engine &value)
2696 value.timestamp = ++current_timestamp;
2698 FC_DEBUG("QFontCache: found font engine\n"
2699 " %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'",
2700 value.data, value.timestamp, value.hits,
2701 value.data->ref.load(), value.data->cache_count,
2702 value.data->name());
2705 void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti)
2707 FC_DEBUG("QFontCache: inserting new engine %p", engine);
2709 Engine data(engine);
2710 data.timestamp = ++current_timestamp;
2713 engineCache.insertMulti(key, data);
2715 engineCache.insert(key, data);
2717 // only increase the cost if this is the first time we insert the engine
2718 if (engine->cache_count == 0)
2719 increaseCost(engine->cache_cost);
2721 ++engine->cache_count;
2724 void QFontCache::increaseCost(uint cost)
2726 cost = (cost + 512) / 1024; // store cost in kb
2727 cost = cost > 0 ? cost : 1;
2730 FC_DEBUG(" COST: increased %u kb, total_cost %u kb, max_cost %u kb",
2731 cost, total_cost, max_cost);
2733 if (total_cost > max_cost) {
2734 max_cost = total_cost;
2736 if (timer_id == -1 || ! fast) {
2737 FC_DEBUG(" TIMER: starting fast timer (%d ms)", fast_timeout);
2739 if (timer_id != -1) killTimer(timer_id);
2740 timer_id = startTimer(fast_timeout);
2746 void QFontCache::decreaseCost(uint cost)
2748 cost = (cost + 512) / 1024; // cost is stored in kb
2749 cost = cost > 0 ? cost : 1;
2750 Q_ASSERT(cost <= total_cost);
2753 FC_DEBUG(" COST: decreased %u kb, total_cost %u kb, max_cost %u kb",
2754 cost, total_cost, max_cost);
2757 void QFontCache::timerEvent(QTimerEvent *)
2759 FC_DEBUG("QFontCache::timerEvent: performing cache maintenance (timestamp %u)",
2762 if (total_cost <= max_cost && max_cost <= min_cost) {
2763 FC_DEBUG(" cache redused sufficiently, stopping timer");
2765 killTimer(timer_id);
2772 // go through the cache and count up everything in use
2773 uint in_use_cost = 0;
2776 FC_DEBUG(" SWEEP engine data:");
2778 // make sure the cost of each engine data is at least 1kb
2779 const uint engine_data_cost =
2780 sizeof(QFontEngineData) > 1024 ? sizeof(QFontEngineData) : 1024;
2782 EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
2783 end = engineDataCache.constEnd();
2784 for (; it != end; ++it) {
2785 #ifdef QFONTCACHE_DEBUG
2786 FC_DEBUG(" %p: ref %2d", it.value(), int(it.value()->ref));
2788 #endif // QFONTCACHE_DEBUG
2790 if (it.value()->ref.load() != 0)
2791 in_use_cost += engine_data_cost;
2796 FC_DEBUG(" SWEEP engine:");
2798 EngineCache::ConstIterator it = engineCache.constBegin(),
2799 end = engineCache.constEnd();
2800 for (; it != end; ++it) {
2801 FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, cost %u bytes",
2802 it.value().data, it.value().timestamp, it.value().hits,
2803 it.value().data->ref.load(), it.value().data->cache_count,
2804 it.value().data->cache_cost);
2806 if (it.value().data->ref.load() != 0)
2807 in_use_cost += it.value().data->cache_cost / it.value().data->cache_count;
2810 // attempt to make up for rounding errors
2811 in_use_cost += engineCache.size();
2814 in_use_cost = (in_use_cost + 512) / 1024; // cost is stored in kb
2817 calculate the new maximum cost for the cache
2819 NOTE: in_use_cost is *not* correct due to rounding errors in the
2820 above algorithm. instead of worrying about getting the
2821 calculation correct, we are more interested in speed, and use
2822 in_use_cost as a floor for new_max_cost
2824 uint new_max_cost = qMax(qMax(max_cost / 2, in_use_cost), min_cost);
2826 FC_DEBUG(" after sweep, in use %u kb, total %u kb, max %u kb, new max %u kb",
2827 in_use_cost, total_cost, max_cost, new_max_cost);
2829 if (new_max_cost == max_cost) {
2831 FC_DEBUG(" cannot shrink cache, slowing timer");
2833 killTimer(timer_id);
2834 timer_id = startTimer(slow_timeout);
2839 } else if (! fast) {
2840 FC_DEBUG(" dropping into passing gear");
2842 killTimer(timer_id);
2843 timer_id = startTimer(fast_timeout);
2847 max_cost = new_max_cost;
2850 FC_DEBUG(" CLEAN engine data:");
2852 // clean out all unused engine data
2853 EngineDataCache::Iterator it = engineDataCache.begin(),
2854 end = engineDataCache.end();
2856 if (it.value()->ref.load() != 0) {
2861 EngineDataCache::Iterator rem = it++;
2863 decreaseCost(sizeof(QFontEngineData));
2865 FC_DEBUG(" %p", rem.value());
2868 engineDataCache.erase(rem);
2872 // clean out the engine cache just enough to get below our new max cost
2875 current_cost = total_cost;
2877 EngineCache::Iterator it = engineCache.begin(),
2878 end = engineCache.end();
2879 // determine the oldest and least popular of the unused engines
2881 uint least_popular = ~0u;
2883 for (; it != end; ++it) {
2884 if (it.value().data->ref.load() != 0)
2887 if (it.value().timestamp < oldest &&
2888 it.value().hits <= least_popular) {
2889 oldest = it.value().timestamp;
2890 least_popular = it.value().hits;
2894 FC_DEBUG(" oldest %u least popular %u", oldest, least_popular);
2896 for (it = engineCache.begin(); it != end; ++it) {
2897 if (it.value().data->ref.load() == 0 &&
2898 it.value().timestamp == oldest &&
2899 it.value().hits == least_popular)
2904 FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'",
2905 it.value().data, it.value().timestamp, it.value().hits,
2906 it.value().data->ref.load(), it.value().data->cache_count,
2907 it.value().data->name());
2909 if (--it.value().data->cache_count == 0) {
2910 FC_DEBUG(" DELETE: last occurrence in cache");
2912 decreaseCost(it.value().data->cache_cost);
2913 delete it.value().data;
2916 this particular font engine is in the cache multiple
2917 times... set current_cost to zero, so that we can
2918 keep looping to get rid of all occurrences
2923 engineCache.erase(it);
2925 } while (current_cost != total_cost && total_cost > max_cost);
2929 #ifndef QT_NO_DEBUG_STREAM
2930 QDebug operator<<(QDebug stream, const QFont &font)
2932 return stream << "QFont(" << font.toString() << ')';