1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** 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 "qapplication.h"
52 #include "qstringlist.h"
55 #include "qthreadstorage.h"
57 #include <private/qunicodetables_p.h>
59 #include <private/qfontengine_p.h>
60 #include <private/qpainter_p.h>
61 #include <private/qtextengine_p.h>
65 #include "qx11info_x11.h"
66 #include <private/qt_x11_p.h>
69 #include "qscreen_qws.h"
70 #if !defined(QT_NO_QWS_QPF2)
72 #include "qfontengine_qpf_p.h"
76 #include <private/qt_s60_p.h>
79 #include <QtGui/qplatformscreen_qpa.h>
80 #include <QtGui/private/qapplication_p.h>
83 #include <QtCore/QMutexLocker>
84 #include <QtCore/QMutex>
86 // #define QFONTCACHE_DEBUG
87 #ifdef QFONTCACHE_DEBUG
88 # define FC_DEBUG qDebug
90 # define FC_DEBUG if (false) qDebug
96 extern HDC shared_dc();
100 extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
103 bool QFontDef::exactMatch(const QFontDef &other) const
106 QFontDef comparison is more complicated than just simple
107 per-member comparisons.
109 When comparing point/pixel sizes, either point or pixelsize
110 could be -1. in This case we have to compare the non negative
113 This test will fail if the point-sizes differ by 1/2 point or
114 more or they do not round to the same value. We have to do this
115 since our API still uses 'int' point-sizes in the API, but store
116 deci-point-sizes internally.
118 To compare the family members, we need to parse the font names
119 and compare the family/foundry strings separately. This allows
120 us to compare e.g. "Helvetica" and "Helvetica [Adobe]" with
123 if (pixelSize != -1 && other.pixelSize != -1) {
124 if (pixelSize != other.pixelSize)
126 } else if (pointSize != -1 && other.pointSize != -1) {
127 if (pointSize != other.pointSize)
133 if (!ignorePitch && !other.ignorePitch && fixedPitch != other.fixedPitch)
136 if (stretch != 0 && other.stretch != 0 && stretch != other.stretch)
139 QString this_family, this_foundry, other_family, other_foundry;
140 QFontDatabase::parseFontName(family, this_foundry, this_family);
141 QFontDatabase::parseFontName(other.family, other_foundry, other_family);
143 this_family = QFontDatabase::resolveFontFamilyAlias(this_family);
144 other_family = QFontDatabase::resolveFontFamilyAlias(other_family);
146 return (styleHint == other.styleHint
147 && styleStrategy == other.styleStrategy
148 && weight == other.weight
149 && style == other.style
150 && this_family == other_family
151 && (styleName.isEmpty() || other.styleName.isEmpty() || styleName == other.styleName)
152 && (this_foundry.isEmpty()
153 || other_foundry.isEmpty()
154 || this_foundry == other_foundry)
156 && addStyle == other.addStyle
161 extern bool qt_is_gui_used;
163 Q_GUI_EXPORT int qt_defaultDpiX()
170 dpi = QX11Info::appDpiX();
171 #elif defined(Q_WS_WIN)
172 dpi = GetDeviceCaps(shared_dc(),LOGPIXELSX);
173 #elif defined(Q_WS_MAC)
174 extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
175 dpi = qt_mac_defaultDpi_x();
176 #elif defined(Q_WS_QWS)
179 QScreen *screen = qt_screen;
180 const QList<QScreen*> subScreens = qt_screen->subScreens();
181 if (!subScreens.isEmpty())
182 screen = subScreens.at(0);
183 dpi = qRound(screen->width() / (screen->physicalWidth() / qreal(25.4)));
184 #elif defined(Q_WS_QPA)
185 QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
187 QPlatformScreen *screen = QApplicationPrivate::platformIntegration()->screens().at(0);
188 const QSize screenSize = screen->geometry().size();
189 const QSize physicalSize = screen->physicalSize();
190 dpi = qRound(screenSize.width() / (physicalSize.width() / qreal(25.4)));
192 //PI has not been initialised, or it is being initialised. Give a default dpi
195 #elif defined(Q_OS_SYMBIAN)
196 dpi = S60->defaultDpiX;
202 Q_GUI_EXPORT int qt_defaultDpiY()
209 dpi = QX11Info::appDpiY();
210 #elif defined(Q_WS_WIN)
211 dpi = GetDeviceCaps(shared_dc(),LOGPIXELSY);
212 #elif defined(Q_WS_MAC)
213 extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp
214 dpi = qt_mac_defaultDpi_y();
215 #elif defined(Q_WS_QWS)
218 QScreen *screen = qt_screen;
219 const QList<QScreen*> subScreens = qt_screen->subScreens();
220 if (!subScreens.isEmpty())
221 screen = subScreens.at(0);
222 dpi = qRound(screen->height() / (screen->physicalHeight() / qreal(25.4)));
223 #elif defined(Q_WS_QPA)
224 QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
226 QPlatformScreen *screen = QApplicationPrivate::platformIntegration()->screens().at(0);
227 const QSize screenSize = screen->geometry().size();
228 const QSize physicalSize = screen->physicalSize();
229 dpi = qRound(screenSize.height() / (physicalSize.height() / qreal(25.4)));
231 //PI has not been initialised, or it is being initialised. Give a default dpi
234 #elif defined(Q_OS_SYMBIAN)
235 dpi = S60->defaultDpiY;
241 Q_GUI_EXPORT int qt_defaultDpi()
243 return qt_defaultDpiY();
246 QFontPrivate::QFontPrivate()
247 : engineData(0), dpi(qt_defaultDpi()), screen(0),
248 rawMode(false), underline(false), overline(false), strikeOut(false), kerning(true),
249 capital(0), letterSpacingIsAbsolute(false), scFont(0)
252 if (QX11Info::display())
253 screen = QX11Info::appScreen();
262 QFontPrivate::QFontPrivate(const QFontPrivate &other)
263 : request(other.request), engineData(0), dpi(other.dpi), screen(other.screen),
264 rawMode(other.rawMode), underline(other.underline), overline(other.overline),
265 strikeOut(other.strikeOut), kerning(other.kerning),
266 capital(other.capital), letterSpacingIsAbsolute(other.letterSpacingIsAbsolute),
267 letterSpacing(other.letterSpacing), wordSpacing(other.wordSpacing),
273 if (scFont && scFont != this)
277 QFontPrivate::~QFontPrivate()
280 engineData->ref.deref();
282 if (scFont && scFont != this)
287 extern QMutex *qt_fontdatabase_mutex();
289 #if !defined(Q_WS_MAC)
290 #define QT_FONT_ENGINE_FROM_DATA(data, script) data->engines[script]
292 #define QT_FONT_ENGINE_FROM_DATA(data, script) data->engine
295 QFontEngine *QFontPrivate::engineForScript(int script) const
297 QMutexLocker locker(qt_fontdatabase_mutex());
298 if (script >= QUnicodeTables::Inherited)
299 script = QUnicodeTables::Common;
300 if (engineData && engineData->fontCache != QFontCache::instance()) {
301 // throw out engineData that came from a different thread
302 engineData->ref.deref();
305 if (!engineData || !QT_FONT_ENGINE_FROM_DATA(engineData, script))
306 QFontDatabase::load(this, script);
307 return QT_FONT_ENGINE_FROM_DATA(engineData, script);
310 void QFontPrivate::alterCharForCapitalization(QChar &c) const {
312 case QFont::AllUppercase:
313 case QFont::SmallCaps:
316 case QFont::AllLowercase:
319 case QFont::MixedCase:
324 QFontPrivate *QFontPrivate::smallCapsFontPrivate() const
328 QFont font(const_cast<QFontPrivate *>(this));
329 qreal pointSize = font.pointSizeF();
331 font.setPointSizeF(pointSize * .7);
333 font.setPixelSize((font.pixelSize() * 7 + 5) / 10);
334 scFont = font.d.data();
341 void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
343 Q_ASSERT(other != 0);
347 if ((mask & QFont::AllPropertiesResolved) == QFont::AllPropertiesResolved) return;
349 // assign the unset-bits with the set-bits of the other font def
350 if (! (mask & QFont::FamilyResolved))
351 request.family = other->request.family;
353 if (! (mask & QFont::StyleNameResolved))
354 request.styleName = other->request.styleName;
356 if (! (mask & QFont::SizeResolved)) {
357 request.pointSize = other->request.pointSize;
358 request.pixelSize = other->request.pixelSize;
361 if (! (mask & QFont::StyleHintResolved))
362 request.styleHint = other->request.styleHint;
364 if (! (mask & QFont::StyleStrategyResolved))
365 request.styleStrategy = other->request.styleStrategy;
367 if (! (mask & QFont::WeightResolved))
368 request.weight = other->request.weight;
370 if (! (mask & QFont::StyleResolved))
371 request.style = other->request.style;
373 if (! (mask & QFont::FixedPitchResolved))
374 request.fixedPitch = other->request.fixedPitch;
376 if (! (mask & QFont::StretchResolved))
377 request.stretch = other->request.stretch;
379 if (! (mask & QFont::HintingPreferenceResolved))
380 request.hintingPreference = other->request.hintingPreference;
382 if (! (mask & QFont::UnderlineResolved))
383 underline = other->underline;
385 if (! (mask & QFont::OverlineResolved))
386 overline = other->overline;
388 if (! (mask & QFont::StrikeOutResolved))
389 strikeOut = other->strikeOut;
391 if (! (mask & QFont::KerningResolved))
392 kerning = other->kerning;
394 if (! (mask & QFont::LetterSpacingResolved)) {
395 letterSpacing = other->letterSpacing;
396 letterSpacingIsAbsolute = other->letterSpacingIsAbsolute;
398 if (! (mask & QFont::WordSpacingResolved))
399 wordSpacing = other->wordSpacing;
400 if (! (mask & QFont::CapitalizationResolved))
401 capital = other->capital;
407 QFontEngineData::QFontEngineData()
408 : ref(1), fontCache(QFontCache::instance())
410 #if !defined(Q_WS_MAC)
411 memset(engines, 0, QUnicodeTables::ScriptCount * sizeof(QFontEngine *));
417 QFontEngineData::~QFontEngineData()
419 #if !defined(Q_WS_MAC)
420 for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
422 engines[i]->ref.deref();
429 #endif // Q_WS_X11 || Q_WS_WIN || Q_WS_MAC
439 \brief The QFont class specifies a font used for drawing text.
444 \ingroup richtext-processing
447 When you create a QFont object you specify various attributes that
448 you want the font to have. Qt will use the font with the specified
449 attributes, or if no matching font exists, Qt will use the closest
450 matching installed font. The attributes of the font that is
451 actually used are retrievable from a QFontInfo object. If the
452 window system provides an exact match exactMatch() returns true.
453 Use QFontMetrics to get measurements, e.g. the pixel length of a
454 string using QFontMetrics::width().
456 Note that a QApplication instance must exist before a QFont can be
457 used. You can set the application's default font with
458 QApplication::setFont().
460 If a chosen font does not include all the characters that
461 need to be displayed, QFont will try to find the characters in the
462 nearest equivalent fonts. When a QPainter draws a character from a
463 font the QFont will report whether or not it has the character; if
464 it does not, QPainter will draw an unfilled square.
466 Create QFonts like this:
468 \snippet doc/src/snippets/code/src_gui_text_qfont.cpp 0
470 The attributes set in the constructor can also be set later, e.g.
471 setFamily(), setPointSize(), setPointSizeFloat(), setWeight() and
472 setItalic(). The remaining attributes must be set after
473 contstruction, e.g. setBold(), setUnderline(), setOverline(),
474 setStrikeOut() and setFixedPitch(). QFontInfo objects should be
475 created \e after the font's attributes have been set. A QFontInfo
476 object will not change, even if you change the font's
477 attributes. The corresponding "get" functions, e.g. family(),
478 pointSize(), etc., return the values that were set, even though
479 the values used may differ. The actual values are available from a
482 If the requested font family is unavailable you can influence the
483 \link #fontmatching font matching algorithm\endlink by choosing a
484 particular \l{QFont::StyleHint} and \l{QFont::StyleStrategy} with
485 setStyleHint(). The default family (corresponding to the current
486 style hint) is returned by defaultFamily().
488 The font-matching algorithm has a lastResortFamily() and
489 lastResortFont() in cases where a suitable match cannot be found.
490 You can provide substitutions for font family names using
491 insertSubstitution() and insertSubstitutions(). Substitutions can
492 be removed with removeSubstitution(). Use substitute() to retrieve
493 a family's first substitute, or the family name itself if it has
494 no substitutes. Use substitutes() to retrieve a list of a family's
495 substitutes (which may be empty).
497 Every QFont has a key() which you can use, for example, as the key
498 in a cache or dictionary. If you want to store a user's font
499 preferences you could use QSettings, writing the font information
500 with toString() and reading it back with fromString(). The
501 operator<<() and operator>>() functions are also available, but
502 they work on a data stream.
504 It is possible to set the height of characters shown on the screen
505 to a specified number of pixels with setPixelSize(); however using
506 setPointSize() has a similar effect and provides device
509 In X11 you can set a font using its system
510 specific name with setRawName().
512 Loading fonts can be expensive, especially on X11. QFont contains
513 extensive optimizations to make the copying of QFont objects fast,
514 and to cache the results of the slow window system functions it
518 The font matching algorithm works as follows:
520 \o The specified font family is searched for.
521 \o If not found, the styleHint() is used to select a replacement
523 \o Each replacement font family is searched for.
524 \o If none of these are found or there was no styleHint(), "helvetica"
525 will be searched for.
526 \o If "helvetica" isn't found Qt will try the lastResortFamily().
527 \o If the lastResortFamily() isn't found Qt will try the
528 lastResortFont() which will always return a name of some kind.
531 Note that the actual font matching algorithm varies from platform to platform.
533 In Windows a request for the "Courier" font is automatically changed to
534 "Courier New", an improved version of Courier that allows for smooth scaling.
535 The older "Courier" bitmap font can be selected by setting the PreferBitmap
536 style strategy (see setStyleStrategy()).
538 Once a font is found, the remaining attributes are matched in order of
542 \o pointSize() (see below)
547 If you have a font which matches on family, even if none of the
548 other attributes match, this font will be chosen in preference to
549 a font which doesn't match on family but which does match on the
550 other attributes. This is because font family is the dominant
553 The point size is defined to match if it is within 20% of the
554 requested point size. When several fonts match and are only
555 distinguished by point size, the font with the closest point size
556 to the one requested will be chosen.
558 The actual family, font size, weight and other font attributes
559 used for drawing text will depend on what's available for the
560 chosen family under the window system. A QFontInfo object can be
561 used to determine the actual values used for drawing the text.
565 \snippet doc/src/snippets/code/src_gui_text_qfont.cpp 1
566 If you had both an Adobe and a Cronyx Helvetica, you might get
569 \snippet doc/src/snippets/code/src_gui_text_qfont.cpp 2
571 You can specify the foundry you want in the family name. The font f
572 in the above example will be set to "Helvetica
575 To determine the attributes of the font actually used in the window
576 system, use a QFontInfo object, e.g.
578 \snippet doc/src/snippets/code/src_gui_text_qfont.cpp 3
580 To find out font metrics use a QFontMetrics object, e.g.
582 \snippet doc/src/snippets/code/src_gui_text_qfont.cpp 4
584 For more general information on fonts, see the
585 \link http://nwalsh.com/comp.fonts/FAQ/ comp.fonts FAQ.\endlink
586 Information on encodings can be found from
587 \link http://czyborra.com/ Roman Czyborra's\endlink page.
589 \sa QFontComboBox, QFontMetrics, QFontInfo, QFontDatabase, {Character Map Example}
594 \enum QFont::ResolveProperties
596 This enum describes the properties of a QFont that can be set on a font
597 individually and then considered resolved.
599 \value FamilyResolved
601 \value StyleHintResolved
602 \value StyleStrategyResolved
603 \value WeightResolved
605 \value UnderlineResolved
606 \value OverlineResolved
607 \value StrikeOutResolved
608 \value FixedPitchResolved
609 \value StretchResolved
610 \value KerningResolved
611 \value CapitalizationResolved
612 \value LetterSpacingResolved
613 \value WordSpacingResolved
614 \value CompletelyResolved
620 This enum describes the different styles of glyphs that are used to
623 \value StyleNormal Normal glyphs used in unstyled text.
624 \value StyleItalic Italic glyphs that are specifically designed for
625 the purpose of representing italicized text.
626 \value StyleOblique Glyphs with an italic appearance that are typically
627 based on the unstyled glyphs, but are not fine-tuned
628 for the purpose of representing italicized text.
634 \fn Qt::HANDLE QFont::handle() const
636 Returns the window system handle to the font, for low-level
637 access. Using this function is \e not portable.
641 \fn FT_Face QFont::freetypeFace() const
643 Returns the handle to the primary FreeType face of the font. If font merging is not disabled a
644 QFont can contain several physical fonts.
646 Returns 0 if the font does not contain a FreeType face.
648 \note This function is only available on platforms that provide the FreeType library;
649 i.e., X11 and some Embedded Linux platforms.
653 \fn QString QFont::rawName() const
655 Returns the name of the font within the underlying window system.
657 On X11, this function will return an empty string if Qt is built with
658 FontConfig support; otherwise the XLFD (X Logical Font Description) is
661 Using the return value of this function is usually \e not \e
668 \fn void QFont::setRawName(const QString &name)
670 Sets a font by its system specific name. The function is
671 particularly useful under X, where system font settings (for
672 example X resources) are usually available in XLFD (X Logical Font
673 Description) form only. You can pass an XLFD as \a name to this
676 A font set with setRawName() is still a full-featured QFont. It can
677 be queried (for example with italic()) or modified (for example with
678 setItalic()) and is therefore also suitable for rendering rich text.
680 If Qt's internal font database cannot resolve the raw name, the
681 font becomes a raw font with \a name as its family.
683 Note that the present implementation does not handle wildcards in
684 XLFDs well, and that font aliases (file \c fonts.alias in the font
685 directory on X11) are not supported.
687 \sa rawName(), setRawMode(), setFamily()
691 \fn QString QFont::lastResortFamily() const
693 Returns the "last resort" font family name.
695 The current implementation tries a wide variety of common fonts,
696 returning the first one it finds. Is is possible that no family is
697 found in which case an empty string is returned.
703 \fn QString QFont::defaultFamily() const
705 Returns the family name that corresponds to the current style
708 \sa StyleHint styleHint() setStyleHint()
712 \fn QString QFont::lastResortFont() const
714 Returns a "last resort" font name for the font matching algorithm.
715 This is used if the last resort family is not available. It will
716 always return a name, if necessary returning something like
719 The current implementation tries a wide variety of common fonts,
720 returning the first one it finds. The implementation may change
721 at any time, but this function will always return a string
722 containing something.
724 It is theoretically possible that there really isn't a
725 lastResortFont() in which case Qt will abort with an error
726 message. We have not been able to identify a case where this
727 happens. Please \link bughowto.html report it as a bug\endlink if
728 it does, preferably with a list of the fonts you have installed.
730 \sa lastResortFamily() rawName()
734 Constructs a font from \a font for use on the paint device \a pd.
736 QFont::QFont(const QFont &font, QPaintDevice *pd)
737 : resolve_mask(font.resolve_mask)
740 int dpi = pd->logicalDpiY();
742 const QX11Info *info = qt_x11Info(pd);
743 int screen = info ? info->screen() : 0;
745 const int screen = 0;
747 if (font.d->dpi != dpi || font.d->screen != screen ) {
748 d = new QFontPrivate(*font.d);
755 if (pd->devType() == QInternal::Printer && pd->getDC())
756 d->hdc = pd->getDC();
763 QFont::QFont(QFontPrivate *data)
764 : d(data), resolve_mask(QFont::AllPropertiesResolved)
769 Detaches the font object from common font data.
775 d->engineData->ref.deref();
777 if (d->scFont && d->scFont != d.data())
778 d->scFont->ref.deref();
787 Constructs a font object that uses the application's default font.
789 \sa QApplication::setFont(), QApplication::font()
792 : d(QApplication::font().d.data()), resolve_mask(0)
797 Constructs a font object with the specified \a family, \a
798 pointSize, \a weight and \a italic settings.
800 If \a pointSize is zero or negative, the point size of the font
801 is set to a system-dependent default value. Generally, this is
802 12 points, except on Symbian where it is 7 points.
804 The \a family name may optionally also include a foundry name,
805 e.g. "Helvetica [Cronyx]". If the \a family is
806 available from more than one foundry and the foundry isn't
807 specified, an arbitrary foundry is chosen. If the family isn't
808 available a family will be set using the \l{QFont}{font matching}
811 \sa Weight, setFamily(), setPointSize(), setWeight(), setItalic(),
812 setStyleHint() QApplication::font()
814 QFont::QFont(const QString &family, int pointSize, int weight, bool italic)
815 : d(new QFontPrivate()), resolve_mask(QFont::FamilyResolved)
817 if (pointSize <= 0) {
824 resolve_mask |= QFont::SizeResolved;
830 resolve_mask |= QFont::WeightResolved | QFont::StyleResolved;
834 resolve_mask |= QFont::StyleResolved;
836 d->request.family = family;
837 d->request.pointSize = qreal(pointSize);
838 d->request.pixelSize = -1;
839 d->request.weight = weight;
840 d->request.style = italic ? QFont::StyleItalic : QFont::StyleNormal;
844 Constructs a font that is a copy of \a font.
846 QFont::QFont(const QFont &font)
847 : d(font.d.data()), resolve_mask(font.resolve_mask)
852 Destroys the font object and frees all allocated resources.
859 Assigns \a font to this font and returns a reference to it.
861 QFont &QFont::operator=(const QFont &font)
864 resolve_mask = font.resolve_mask;
869 Returns the requested font family name, i.e. the name set in the
870 constructor or the last setFont() call.
872 \sa setFamily() substitutes() substitute()
874 QString QFont::family() const
876 return d->request.family;
880 Sets the family name of the font. The name is case insensitive and
881 may include a foundry name.
883 The \a family name may optionally also include a foundry name,
884 e.g. "Helvetica [Cronyx]". If the \a family is
885 available from more than one foundry and the foundry isn't
886 specified, an arbitrary foundry is chosen. If the family isn't
887 available a family will be set using the \l{QFont}{font matching}
890 \sa family(), setStyleHint(), QFontInfo
892 void QFont::setFamily(const QString &family)
896 d->request.family = family;
897 #if defined(Q_WS_X11)
898 d->request.addStyle.clear();
901 resolve_mask |= QFont::FamilyResolved;
907 Returns the requested font style name, it will be used to match the
908 font with irregular styles (that can't be normalized in other style
909 properties). It depends on system font support, thus only works for
910 Mac OS X and X11 so far. On Windows irregular styles will be added
911 as separate font families so there is no need for this.
913 \sa setFamily() setStyle()
915 QString QFont::styleName() const
917 return d->request.styleName;
923 Sets the style name of the font. When set, other style properties
924 like \a style() and \a weight() will be ignored for font matching.
928 void QFont::setStyleName(const QString &styleName)
932 d->request.styleName = styleName;
933 resolve_mask |= QFont::StyleNameResolved;
937 Returns the point size of the font. Returns -1 if the font size
938 was specified in pixels.
940 \sa setPointSize() pointSizeF()
942 int QFont::pointSize() const
944 return qRound(d->request.pointSize);
950 \enum QFont::HintingPreference
952 This enum describes the different levels of hinting that can be applied
953 to glyphs to improve legibility on displays where it might be warranted
954 by the density of pixels.
956 \value PreferDefaultHinting Use the default hinting level for the target platform.
957 \value PreferNoHinting If possible, render text without hinting the outlines
958 of the glyphs. The text layout will be typographically accurate and
959 scalable, using the same metrics as are used e.g. when printing.
960 \value PreferVerticalHinting If possible, render text with no horizontal hinting,
961 but align glyphs to the pixel grid in the vertical direction. The text will appear
962 crisper on displays where the density is too low to give an accurate rendering
963 of the glyphs. But since the horizontal metrics of the glyphs are unhinted, the text's
964 layout will be scalable to higher density devices (such as printers) without impacting
965 details such as line breaks.
966 \value PreferFullHinting If possible, render text with hinting in both horizontal and
967 vertical directions. The text will be altered to optimize legibility on the target
968 device, but since the metrics will depend on the target size of the text, the positions
969 of glyphs, line breaks, and other typographical detail will not scale, meaning that a
970 text layout may look different on devices with different pixel densities.
972 Please note that this enum only describes a preference, as the full range of hinting levels
973 are not supported on all of Qt's supported platforms. The following table details the effect
974 of a given hinting preference on a selected set of target platforms.
979 \o PreferDefaultHinting
981 \o PreferVerticalHinting
984 \o Windows Vista (w/o Platform Update) and earlier
990 \o Windows 7 and Windows Vista (w/Platform Update) and DirectWrite enabled in Qt
997 \o Operating System setting
999 \o Vertical hinting (light)
1002 \o Cocoa on Mac OS X
1009 \note Please be aware that altering the hinting preference on Windows is available through
1010 the DirectWrite font engine. This is available on Windows Vista after installing the platform
1011 update, and on Windows 7. In order to use this extension, configure Qt using -directwrite.
1012 The target application will then depend on the availability of DirectWrite on the target
1020 Set the preference for the hinting level of the glyphs to \a hintingPreference. This is a hint
1021 to the underlying font rendering system to use a certain level of hinting, and has varying
1022 support across platforms. See the table in the documentation for QFont::HintingPreference for
1025 The default hinting preference is QFont::PreferDefaultHinting.
1027 void QFont::setHintingPreference(HintingPreference hintingPreference)
1031 d->request.hintingPreference = hintingPreference;
1033 resolve_mask |= QFont::HintingPreferenceResolved;
1039 Returns the currently preferred hinting level for glyphs rendered with this font.
1041 QFont::HintingPreference QFont::hintingPreference() const
1043 return QFont::HintingPreference(d->request.hintingPreference);
1047 Sets the point size to \a pointSize. The point size must be
1050 \sa pointSize() setPointSizeF()
1052 void QFont::setPointSize(int pointSize)
1054 if (pointSize <= 0) {
1055 qWarning("QFont::setPointSize: Point size <= 0 (%d), must be greater than 0", pointSize);
1061 d->request.pointSize = qreal(pointSize);
1062 d->request.pixelSize = -1;
1064 resolve_mask |= QFont::SizeResolved;
1068 Sets the point size to \a pointSize. The point size must be
1069 greater than zero. The requested precision may not be achieved on
1072 \sa pointSizeF() setPointSize() setPixelSize()
1074 void QFont::setPointSizeF(qreal pointSize)
1076 if (pointSize <= 0) {
1077 qWarning("QFont::setPointSizeF: Point size <= 0 (%f), must be greater than 0", pointSize);
1083 d->request.pointSize = pointSize;
1084 d->request.pixelSize = -1;
1086 resolve_mask |= QFont::SizeResolved;
1090 Returns the point size of the font. Returns -1 if the font size was
1091 specified in pixels.
1093 \sa pointSize() setPointSizeF() pixelSize() QFontInfo::pointSize() QFontInfo::pixelSize()
1095 qreal QFont::pointSizeF() const
1097 return d->request.pointSize;
1101 Sets the font size to \a pixelSize pixels.
1103 Using this function makes the font device dependent. Use
1104 setPointSize() or setPointSizeF() to set the size of the font
1105 in a device independent manner.
1109 void QFont::setPixelSize(int pixelSize)
1111 if (pixelSize <= 0) {
1112 qWarning("QFont::setPixelSize: Pixel size <= 0 (%d)", pixelSize);
1118 d->request.pixelSize = pixelSize;
1119 d->request.pointSize = -1;
1121 resolve_mask |= QFont::SizeResolved;
1125 Returns the pixel size of the font if it was set with
1126 setPixelSize(). Returns -1 if the size was set with setPointSize()
1129 \sa setPixelSize() pointSize() QFontInfo::pointSize() QFontInfo::pixelSize()
1131 int QFont::pixelSize() const
1133 return d->request.pixelSize;
1139 Sets the logical pixel height of font characters when shown on
1140 the screen to \a pixelSize.
1142 void QFont::setPixelSizeFloat(qreal pixelSize)
1144 setPixelSize((int)pixelSize);
1149 \fn bool QFont::italic() const
1151 Returns true if the style() of the font is not QFont::StyleNormal
1153 \sa setItalic() style()
1157 \fn void QFont::setItalic(bool enable)
1159 Sets the style() of the font to QFont::StyleItalic if \a enable is true;
1160 otherwise the style is set to QFont::StyleNormal.
1162 \sa italic() QFontInfo
1166 Returns the style of the font.
1170 QFont::Style QFont::style() const
1172 return (QFont::Style)d->request.style;
1177 Sets the style of the font to \a style.
1179 \sa italic(), QFontInfo
1181 void QFont::setStyle(Style style)
1185 d->request.style = style;
1186 resolve_mask |= QFont::StyleResolved;
1190 Returns the weight of the font which is one of the enumerated
1191 values from \l{QFont::Weight}.
1193 \sa setWeight(), Weight, QFontInfo
1195 int QFont::weight() const
1197 return d->request.weight;
1203 Qt uses a weighting scale from 0 to 99 similar to, but not the
1204 same as, the scales used in Windows or CSS. A weight of 0 is
1205 ultralight, whilst 99 will be an extremely black.
1207 This enum contains the predefined font weights:
1217 Sets the weight the font to \a weight, which should be a value
1218 from the \l QFont::Weight enumeration.
1220 \sa weight(), QFontInfo
1222 void QFont::setWeight(int weight)
1224 Q_ASSERT_X(weight >= 0 && weight <= 99, "QFont::setWeight", "Weight must be between 0 and 99");
1228 d->request.weight = weight;
1229 resolve_mask |= QFont::WeightResolved;
1233 \fn bool QFont::bold() const
1235 Returns true if weight() is a value greater than \link Weight
1236 QFont::Normal \endlink; otherwise returns false.
1238 \sa weight(), setBold(), QFontInfo::bold()
1242 \fn void QFont::setBold(bool enable)
1244 If \a enable is true sets the font's weight to \link Weight
1245 QFont::Bold \endlink; otherwise sets the weight to \link Weight
1246 QFont::Normal\endlink.
1248 For finer boldness control use setWeight().
1250 \sa bold(), setWeight()
1254 Returns true if underline has been set; otherwise returns false.
1258 bool QFont::underline() const
1260 return d->underline;
1264 If \a enable is true, sets underline on; otherwise sets underline
1267 \sa underline(), QFontInfo
1269 void QFont::setUnderline(bool enable)
1273 d->underline = enable;
1274 resolve_mask |= QFont::UnderlineResolved;
1278 Returns true if overline has been set; otherwise returns false.
1282 bool QFont::overline() const
1288 If \a enable is true, sets overline on; otherwise sets overline off.
1290 \sa overline(), QFontInfo
1292 void QFont::setOverline(bool enable)
1296 d->overline = enable;
1297 resolve_mask |= QFont::OverlineResolved;
1301 Returns true if strikeout has been set; otherwise returns false.
1305 bool QFont::strikeOut() const
1307 return d->strikeOut;
1311 If \a enable is true, sets strikeout on; otherwise sets strikeout
1314 \sa strikeOut(), QFontInfo
1316 void QFont::setStrikeOut(bool enable)
1320 d->strikeOut = enable;
1321 resolve_mask |= QFont::StrikeOutResolved;
1325 Returns true if fixed pitch has been set; otherwise returns false.
1327 \sa setFixedPitch(), QFontInfo::fixedPitch()
1329 bool QFont::fixedPitch() const
1331 return d->request.fixedPitch;
1335 If \a enable is true, sets fixed pitch on; otherwise sets fixed
1338 \sa fixedPitch(), QFontInfo
1340 void QFont::setFixedPitch(bool enable)
1344 d->request.fixedPitch = enable;
1345 d->request.ignorePitch = false;
1346 resolve_mask |= QFont::FixedPitchResolved;
1350 Returns true if kerning should be used when drawing text with this font.
1354 bool QFont::kerning() const
1360 Enables kerning for this font if \a enable is true; otherwise
1361 disables it. By default, kerning is enabled.
1363 When kerning is enabled, glyph metrics do not add up anymore,
1364 even for Latin text. In other words, the assumption that
1365 width('a') + width('b') is equal to width("ab") is not
1368 \sa kerning(), QFontMetrics
1370 void QFont::setKerning(bool enable)
1373 d->kerning = enable;
1374 resolve_mask |= QFont::KerningResolved;
1378 Returns the StyleStrategy.
1380 The style strategy affects the \l{QFont}{font matching} algorithm.
1381 See \l QFont::StyleStrategy for the list of available strategies.
1383 \sa setStyleHint() QFont::StyleHint
1385 QFont::StyleStrategy QFont::styleStrategy() const
1387 return (StyleStrategy) d->request.styleStrategy;
1391 Returns the StyleHint.
1393 The style hint affects the \l{QFont}{font matching} algorithm.
1394 See \l QFont::StyleHint for the list of available hints.
1396 \sa setStyleHint(), QFont::StyleStrategy QFontInfo::styleHint()
1398 QFont::StyleHint QFont::styleHint() const
1400 return (StyleHint) d->request.styleHint;
1404 \enum QFont::StyleHint
1406 Style hints are used by the \l{QFont}{font matching} algorithm to
1407 find an appropriate default family if a selected font family is
1410 \value AnyStyle leaves the font matching algorithm to choose the
1411 family. This is the default.
1413 \value SansSerif the font matcher prefer sans serif fonts.
1414 \value Helvetica is a synonym for \c SansSerif.
1416 \value Serif the font matcher prefers serif fonts.
1417 \value Times is a synonym for \c Serif.
1419 \value TypeWriter the font matcher prefers fixed pitch fonts.
1420 \value Courier a synonym for \c TypeWriter.
1422 \value OldEnglish the font matcher prefers decorative fonts.
1423 \value Decorative is a synonym for \c OldEnglish.
1425 \value Monospace the font matcher prefers fonts that map to the
1426 CSS generic font-family 'monospace'.
1428 \value Fantasy the font matcher prefers fonts that map to the
1429 CSS generic font-family 'fantasy'.
1431 \value Cursive the font matcher prefers fonts that map to the
1432 CSS generic font-family 'cursive'.
1434 \value System the font matcher prefers system fonts.
1438 \enum QFont::StyleStrategy
1440 The style strategy tells the \l{QFont}{font matching} algorithm
1441 what type of fonts should be used to find an appropriate default
1444 The following strategies are available:
1446 \value PreferDefault the default style strategy. It does not prefer
1448 \value PreferBitmap prefers bitmap fonts (as opposed to outline
1450 \value PreferDevice prefers device fonts.
1451 \value PreferOutline prefers outline fonts (as opposed to bitmap fonts).
1452 \value ForceOutline forces the use of outline fonts.
1453 \value NoAntialias don't antialias the fonts.
1454 \value PreferAntialias antialias if possible.
1455 \value OpenGLCompatible forces the use of OpenGL compatible
1457 \value NoFontMerging If the font selected for a certain writing system
1458 does not contain a character requested to draw, then Qt automatically chooses a similar
1459 looking font that contains the character. The NoFontMerging flag disables this feature.
1460 Please note that enabling this flag will not prevent Qt from automatically picking a
1461 suitable font when the selected font does not support the writing system of the text.
1463 Any of these may be OR-ed with one of these flags:
1465 \value PreferMatch prefer an exact match. The font matcher will try to
1466 use the exact font size that has been specified.
1467 \value PreferQuality prefer the best quality font. The font matcher
1468 will use the nearest standard point size that the font
1470 \value ForceIntegerMetrics forces the use of integer values in font engines that support fractional
1475 Sets the style hint and strategy to \a hint and \a strategy,
1478 If these aren't set explicitly the style hint will default to
1479 \c AnyStyle and the style strategy to \c PreferDefault.
1481 Qt does not support style hints on X11 since this information
1482 is not provided by the window system.
1484 \sa StyleHint, styleHint(), StyleStrategy, styleStrategy(), QFontInfo
1486 void QFont::setStyleHint(StyleHint hint, StyleStrategy strategy)
1490 if ((resolve_mask & (QFont::StyleHintResolved | QFont::StyleStrategyResolved)) &&
1491 (StyleHint) d->request.styleHint == hint &&
1492 (StyleStrategy) d->request.styleStrategy == strategy)
1495 d->request.styleHint = hint;
1496 d->request.styleStrategy = strategy;
1497 resolve_mask |= QFont::StyleHintResolved;
1498 resolve_mask |= QFont::StyleStrategyResolved;
1500 #if defined(Q_WS_X11)
1501 d->request.addStyle.clear();
1506 Sets the style strategy for the font to \a s.
1508 \sa QFont::StyleStrategy
1510 void QFont::setStyleStrategy(StyleStrategy s)
1514 if ((resolve_mask & QFont::StyleStrategyResolved) &&
1515 s == (StyleStrategy)d->request.styleStrategy)
1518 d->request.styleStrategy = s;
1519 resolve_mask |= QFont::StyleStrategyResolved;
1524 \enum QFont::Stretch
1526 Predefined stretch values that follow the CSS naming convention. The higher
1527 the value, the more stretched the text is.
1529 \value UltraCondensed 50
1530 \value ExtraCondensed 62
1532 \value SemiCondensed 87
1533 \value Unstretched 100
1534 \value SemiExpanded 112
1536 \value ExtraExpanded 150
1537 \value UltraExpanded 200
1539 \sa setStretch() stretch()
1543 Returns the stretch factor for the font.
1547 int QFont::stretch() const
1549 return d->request.stretch;
1553 Sets the stretch factor for the font.
1555 The stretch factor changes the width of all characters in the font
1556 by \a factor percent. For example, setting \a factor to 150
1557 results in all characters in the font being 1.5 times (ie. 150%)
1558 wider. The default stretch factor is 100. The minimum stretch
1559 factor is 1, and the maximum stretch factor is 4000.
1561 The stretch factor is only applied to outline fonts. The stretch
1562 factor is ignored for bitmap fonts.
1564 NOTE: QFont cannot stretch XLFD fonts. When loading XLFD fonts on
1565 X11, the stretch factor is matched against a predefined set of
1566 values for the SETWIDTH_NAME field of the XLFD.
1568 \sa stretch() QFont::Stretch
1570 void QFont::setStretch(int factor)
1572 if (factor < 1 || factor > 4000) {
1573 qWarning("QFont::setStretch: Parameter '%d' out of range", factor);
1577 if ((resolve_mask & QFont::StretchResolved) &&
1578 d->request.stretch == (uint)factor)
1583 d->request.stretch = (uint)factor;
1584 resolve_mask |= QFont::StretchResolved;
1588 \enum QFont::SpacingType
1591 \value PercentageSpacing A value of 100 will keep the spacing unchanged; a value of 200 will enlarge the
1592 spacing after a character by the width of the character itself.
1593 \value AbsoluteSpacing A positive value increases the letter spacing by the corresponding pixels; a negative
1594 value decreases the spacing.
1599 Returns the letter spacing for the font.
1601 \sa setLetterSpacing(), letterSpacingType(), setWordSpacing()
1603 qreal QFont::letterSpacing() const
1605 return d->letterSpacing.toReal();
1610 Sets the letter spacing for the font to \a spacing and the type
1611 of spacing to \a type.
1613 Letter spacing changes the default spacing between individual
1614 letters in the font. The spacing between the letters can be
1615 made smaller as well as larger.
1617 \sa letterSpacing(), letterSpacingType(), setWordSpacing()
1619 void QFont::setLetterSpacing(SpacingType type, qreal spacing)
1621 const QFixed newSpacing = QFixed::fromReal(spacing);
1622 const bool absoluteSpacing = type == AbsoluteSpacing;
1623 if ((resolve_mask & QFont::LetterSpacingResolved) &&
1624 d->letterSpacingIsAbsolute == absoluteSpacing &&
1625 d->letterSpacing == newSpacing)
1630 d->letterSpacing = newSpacing;
1631 d->letterSpacingIsAbsolute = absoluteSpacing;
1632 resolve_mask |= QFont::LetterSpacingResolved;
1637 Returns the spacing type used for letter spacing.
1639 \sa letterSpacing(), setLetterSpacing(), setWordSpacing()
1641 QFont::SpacingType QFont::letterSpacingType() const
1643 return d->letterSpacingIsAbsolute ? AbsoluteSpacing : PercentageSpacing;
1648 Returns the word spacing for the font.
1650 \sa setWordSpacing(), setLetterSpacing()
1652 qreal QFont::wordSpacing() const
1654 return d->wordSpacing.toReal();
1659 Sets the word spacing for the font to \a spacing.
1661 Word spacing changes the default spacing between individual
1662 words. A positive value increases the word spacing
1663 by a corresponding amount of pixels, while a negative value
1664 decreases the inter-word spacing accordingly.
1666 Word spacing will not apply to writing systems, where indiviaul
1667 words are not separated by white space.
1669 \sa wordSpacing(), setLetterSpacing()
1671 void QFont::setWordSpacing(qreal spacing)
1673 const QFixed newSpacing = QFixed::fromReal(spacing);
1674 if ((resolve_mask & QFont::WordSpacingResolved) &&
1675 d->wordSpacing == newSpacing)
1680 d->wordSpacing = newSpacing;
1681 resolve_mask |= QFont::WordSpacingResolved;
1685 \enum QFont::Capitalization
1688 Rendering option for text this font applies to.
1691 \value MixedCase This is the normal text rendering option where no capitalization change is applied.
1692 \value AllUppercase This alters the text to be rendered in all uppercase type.
1693 \value AllLowercase This alters the text to be rendered in all lowercase type.
1694 \value SmallCaps This alters the text to be rendered in small-caps type.
1695 \value Capitalize This alters the text to be rendered with the first character of each word as an uppercase character.
1700 Sets the capitalization of the text in this font to \a caps.
1702 A font's capitalization makes the text appear in the selected capitalization mode.
1704 \sa capitalization()
1706 void QFont::setCapitalization(Capitalization caps)
1708 if ((resolve_mask & QFont::CapitalizationResolved) &&
1709 capitalization() == caps)
1715 resolve_mask |= QFont::CapitalizationResolved;
1720 Returns the current capitalization type of the font.
1722 \sa setCapitalization()
1724 QFont::Capitalization QFont::capitalization() const
1726 return static_cast<QFont::Capitalization> (d->capital);
1731 If \a enable is true, turns raw mode on; otherwise turns raw mode
1732 off. This function only has an effect under X11.
1734 If raw mode is enabled, Qt will search for an X font with a
1735 complete font name matching the family name, ignoring all other
1736 values set for the QFont. If the font name matches several fonts,
1737 Qt will use the first font returned by X. QFontInfo \e cannot be
1738 used to fetch information about a QFont using raw mode (it will
1739 return the values set in the QFont for all parameters, including
1742 \warning Do not use raw mode unless you really, really need it! In
1743 most (if not all) cases, setRawName() is a much better choice.
1745 \sa rawMode(), setRawName()
1747 void QFont::setRawMode(bool enable)
1751 if ((bool) d->rawMode == enable) return;
1753 d->rawMode = enable;
1757 Returns true if a window system font exactly matching the settings
1758 of this font is available.
1762 bool QFont::exactMatch() const
1764 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1765 Q_ASSERT(engine != 0);
1767 ? engine->type() != QFontEngine::Box
1768 : d->request.exactMatch(engine->fontDef));
1772 Returns true if this font is equal to \a f; otherwise returns
1775 Two QFonts are considered equal if their font attributes are
1776 equal. If rawMode() is enabled for both fonts, only the family
1777 fields are compared.
1779 \sa operator!=() isCopyOf()
1781 bool QFont::operator==(const QFont &f) const
1784 || (f.d->request == d->request
1785 && f.d->request.pointSize == d->request.pointSize
1786 && f.d->underline == d->underline
1787 && f.d->overline == d->overline
1788 && f.d->strikeOut == d->strikeOut
1789 && f.d->kerning == d->kerning
1790 && f.d->capital == d->capital
1791 && f.d->letterSpacingIsAbsolute == d->letterSpacingIsAbsolute
1792 && f.d->letterSpacing == d->letterSpacing
1793 && f.d->wordSpacing == d->wordSpacing
1799 Provides an arbitrary comparison of this font and font \a f.
1800 All that is guaranteed is that the operator returns false if both
1801 fonts are equal and that (f1 \< f2) == !(f2 \< f1) if the fonts
1804 This function is useful in some circumstances, for example if you
1805 want to use QFont objects as keys in a QMap.
1807 \sa operator==() operator!=() isCopyOf()
1809 bool QFont::operator<(const QFont &f) const
1811 if (f.d == d) return false;
1812 // the < operator for fontdefs ignores point sizes.
1813 QFontDef &r1 = f.d->request;
1814 QFontDef &r2 = d->request;
1815 if (r1.pointSize != r2.pointSize) return r1.pointSize < r2.pointSize;
1816 if (r1.pixelSize != r2.pixelSize) return r1.pixelSize < r2.pixelSize;
1817 if (r1.weight != r2.weight) return r1.weight < r2.weight;
1818 if (r1.style != r2.style) return r1.style < r2.style;
1819 if (r1.stretch != r2.stretch) return r1.stretch < r2.stretch;
1820 if (r1.styleHint != r2.styleHint) return r1.styleHint < r2.styleHint;
1821 if (r1.styleStrategy != r2.styleStrategy) return r1.styleStrategy < r2.styleStrategy;
1822 if (r1.family != r2.family) return r1.family < r2.family;
1824 if (r1.addStyle != r2.addStyle) return r1.addStyle < r2.addStyle;
1826 if (f.d->capital != d->capital) return f.d->capital < d->capital;
1828 if (f.d->letterSpacingIsAbsolute != d->letterSpacingIsAbsolute) return f.d->letterSpacingIsAbsolute < d->letterSpacingIsAbsolute;
1829 if (f.d->letterSpacing != d->letterSpacing) return f.d->letterSpacing < d->letterSpacing;
1830 if (f.d->wordSpacing != d->wordSpacing) return f.d->wordSpacing < d->wordSpacing;
1832 int f1attrs = (f.d->underline << 3) + (f.d->overline << 2) + (f.d->strikeOut<<1) + f.d->kerning;
1833 int f2attrs = (d->underline << 3) + (d->overline << 2) + (d->strikeOut<<1) + d->kerning;
1834 return f1attrs < f2attrs;
1839 Returns true if this font is different from \a f; otherwise
1842 Two QFonts are considered to be different if their font attributes
1843 are different. If rawMode() is enabled for both fonts, only the
1844 family fields are compared.
1848 bool QFont::operator!=(const QFont &f) const
1850 return !(operator==(f));
1854 Returns the font as a QVariant
1856 QFont::operator QVariant() const
1858 return QVariant(QVariant::Font, this);
1862 Returns true if this font and \a f are copies of each other, i.e.
1863 one of them was created as a copy of the other and neither has
1864 been modified since. This is much stricter than equality.
1866 \sa operator=() operator==()
1868 bool QFont::isCopyOf(const QFont & f) const
1874 Returns true if raw mode is used for font name matching; otherwise
1877 \sa setRawMode() rawName()
1879 bool QFont::rawMode() const
1885 Returns a new QFont that has attributes copied from \a other that
1886 have not been previously set on this font.
1888 QFont QFont::resolve(const QFont &other) const
1891 && (resolve_mask == other.resolve_mask || resolve_mask == 0)
1892 && d->dpi == other.d->dpi) {
1894 o.resolve_mask = resolve_mask;
1900 font.d->resolve(resolve_mask, other.d.data());
1906 \fn uint QFont::resolve() const
1911 \fn void QFont::resolve(uint mask)
1919 Please use QApplication::font() instead.
1921 QFont QFont::defaultFont()
1923 return QApplication::font();
1928 Please use QApplication::setFont() instead.
1930 void QFont::setDefaultFont(const QFont &f)
1932 QApplication::setFont(f);
1936 \fn qreal QFont::pointSizeFloat() const
1939 Use pointSizeF() instead.
1943 \fn void QFont::setPointSizeFloat(qreal size)
1946 Use setPointSizeF() instead.
1953 /*****************************************************************************
1954 QFont substitution management
1955 *****************************************************************************/
1957 typedef QHash<QString, QStringList> QFontSubst;
1958 Q_GLOBAL_STATIC(QFontSubst, globalFontSubst)
1960 // create substitution dict
1961 static void initFontSubst()
1963 // default substitutions
1964 static const char * const initTbl[] = {
1966 #if defined(Q_WS_X11)
1967 "arial", "helvetica",
1968 "times new roman", "times",
1969 "courier new", "courier",
1970 "sans serif", "helvetica",
1971 #elif defined(Q_WS_WIN)
1972 "times", "times new roman",
1973 "courier", "courier new",
1974 "helvetica", "arial",
1975 "sans serif", "arial",
1981 QFontSubst *fontSubst = globalFontSubst();
1982 Q_ASSERT(fontSubst != 0);
1983 if (!fontSubst->isEmpty())
1985 #if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
1986 if (X11->has_fontconfig)
1990 for (int i=0; initTbl[i] != 0; i += 2) {
1991 QStringList &list = (*fontSubst)[QString::fromLatin1(initTbl[i])];
1992 list.append(QString::fromLatin1(initTbl[i+1]));
1997 Returns the first family name to be used whenever \a familyName is
1998 specified. The lookup is case insensitive.
2000 If there is no substitution for \a familyName, \a familyName is
2003 To obtain a list of substitutions use substitutes().
2005 \sa setFamily() insertSubstitutions() insertSubstitution() removeSubstitution()
2007 QString QFont::substitute(const QString &familyName)
2011 QFontSubst *fontSubst = globalFontSubst();
2012 Q_ASSERT(fontSubst != 0);
2013 QFontSubst::ConstIterator it = fontSubst->constFind(familyName.toLower());
2014 if (it != fontSubst->constEnd() && !(*it).isEmpty())
2015 return (*it).first();
2022 Returns a list of family names to be used whenever \a familyName
2023 is specified. The lookup is case insensitive.
2025 If there is no substitution for \a familyName, an empty list is
2028 \sa substitute() insertSubstitutions() insertSubstitution() removeSubstitution()
2030 QStringList QFont::substitutes(const QString &familyName)
2034 QFontSubst *fontSubst = globalFontSubst();
2035 Q_ASSERT(fontSubst != 0);
2036 return fontSubst->value(familyName.toLower(), QStringList());
2041 Inserts \a substituteName into the substitution
2042 table for the family \a familyName.
2044 \sa insertSubstitutions() removeSubstitution() substitutions() substitute() substitutes()
2046 void QFont::insertSubstitution(const QString &familyName,
2047 const QString &substituteName)
2051 QFontSubst *fontSubst = globalFontSubst();
2052 Q_ASSERT(fontSubst != 0);
2053 QStringList &list = (*fontSubst)[familyName.toLower()];
2054 QString s = substituteName.toLower();
2055 if (!list.contains(s))
2061 Inserts the list of families \a substituteNames into the
2062 substitution list for \a familyName.
2064 \sa insertSubstitution(), removeSubstitution(), substitutions(), substitute()
2066 void QFont::insertSubstitutions(const QString &familyName,
2067 const QStringList &substituteNames)
2071 QFontSubst *fontSubst = globalFontSubst();
2072 Q_ASSERT(fontSubst != 0);
2073 QStringList &list = (*fontSubst)[familyName.toLower()];
2074 QStringList::ConstIterator it = substituteNames.constBegin();
2075 while (it != substituteNames.constEnd()) {
2076 QString s = (*it).toLower();
2077 if (!list.contains(s))
2083 /*! \fn void QFont::initialize()
2086 Internal function that initializes the font system. The font cache
2087 and font dict do not alloc the keys. The key is a QString which is
2088 shared between QFontPrivate and QXFontName.
2091 /*! \fn void QFont::cleanup()
2094 Internal function that cleans up the font system.
2097 // ### mark: should be called removeSubstitutions()
2099 Removes all the substitutions for \a familyName.
2101 \sa insertSubstitutions(), insertSubstitution(), substitutions(), substitute()
2103 void QFont::removeSubstitution(const QString &familyName)
2104 { // ### function name should be removeSubstitutions() or
2105 // ### removeSubstitutionList()
2108 QFontSubst *fontSubst = globalFontSubst();
2109 Q_ASSERT(fontSubst != 0);
2110 fontSubst->remove(familyName.toLower());
2115 Returns a sorted list of substituted family names.
2117 \sa insertSubstitution(), removeSubstitution(), substitute()
2119 QStringList QFont::substitutions()
2123 QFontSubst *fontSubst = globalFontSubst();
2124 Q_ASSERT(fontSubst != 0);
2126 QFontSubst::ConstIterator it = fontSubst->constBegin();
2128 while (it != fontSubst->constEnd()) {
2129 ret.append(it.key());
2139 Internal function. Converts boolean font settings to an unsigned
2140 8-bit number. Used for serialization etc.
2142 static quint8 get_font_bits(int version, const QFontPrivate *f)
2146 if (f->request.style)
2154 if (f->request.fixedPitch)
2156 // if (f.hintSetByUser)
2160 if (version >= QDataStream::Qt_4_0) {
2164 if (f->request.style == QFont::StyleOblique)
2169 static quint8 get_extended_font_bits(const QFontPrivate *f)
2173 if (f->request.ignorePitch)
2175 if (f->letterSpacingIsAbsolute)
2180 #ifndef QT_NO_DATASTREAM
2183 Internal function. Sets boolean font settings from an unsigned
2184 8-bit number. Used for serialization etc.
2186 static void set_font_bits(int version, quint8 bits, QFontPrivate *f)
2189 f->request.style = (bits & 0x01) != 0 ? QFont::StyleItalic : QFont::StyleNormal;
2190 f->underline = (bits & 0x02) != 0;
2191 f->overline = (bits & 0x40) != 0;
2192 f->strikeOut = (bits & 0x04) != 0;
2193 f->request.fixedPitch = (bits & 0x08) != 0;
2194 // f->hintSetByUser = (bits & 0x10) != 0;
2195 f->rawMode = (bits & 0x20) != 0;
2196 if (version >= QDataStream::Qt_4_0)
2197 f->kerning = (bits & 0x10) != 0;
2198 if ((bits & 0x80) != 0)
2199 f->request.style = QFont::StyleOblique;
2202 static void set_extended_font_bits(quint8 bits, QFontPrivate *f)
2205 f->request.ignorePitch = (bits & 0x01) != 0;
2206 f->letterSpacingIsAbsolute = (bits & 0x02) != 0;
2212 Returns the font's key, a textual representation of a font. It is
2213 typically used as the key for a cache or dictionary of fonts.
2217 QString QFont::key() const
2223 Returns a description of the font. The description is a
2224 comma-separated list of the attributes, perfectly suited for use
2229 QString QFont::toString() const
2231 const QChar comma(QLatin1Char(','));
2232 return family() + comma +
2233 QString::number( pointSizeF()) + comma +
2234 QString::number( pixelSize()) + comma +
2235 QString::number((int) styleHint()) + comma +
2236 QString::number( weight()) + comma +
2237 QString::number((int) style()) + comma +
2238 QString::number((int) underline()) + comma +
2239 QString::number((int) strikeOut()) + comma +
2240 QString::number((int)fixedPitch()) + comma +
2241 QString::number((int) rawMode());
2246 Sets this font to match the description \a descrip. The description
2247 is a comma-separated list of the font attributes, as returned by
2252 bool QFont::fromString(const QString &descrip)
2254 QStringList l(descrip.split(QLatin1Char(',')));
2256 int count = l.count();
2257 if (!count || (count > 2 && count < 9) || count > 11) {
2258 qWarning("QFont::fromString: Invalid description '%s'",
2259 descrip.isEmpty() ? "(empty)" : descrip.toLatin1().data());
2264 if (count > 1 && l[1].toDouble() > 0.0)
2265 setPointSizeF(l[1].toDouble());
2267 setStyleHint((StyleHint) l[2].toInt());
2268 setWeight(qMax(qMin(99, l[3].toInt()), 0));
2269 setItalic(l[4].toInt());
2270 setUnderline(l[5].toInt());
2271 setStrikeOut(l[6].toInt());
2272 setFixedPitch(l[7].toInt());
2273 setRawMode(l[8].toInt());
2274 } else if (count == 10) {
2275 if (l[2].toInt() > 0)
2276 setPixelSize(l[2].toInt());
2277 setStyleHint((StyleHint) l[3].toInt());
2278 setWeight(qMax(qMin(99, l[4].toInt()), 0));
2279 setStyle((QFont::Style)l[5].toInt());
2280 setUnderline(l[6].toInt());
2281 setStrikeOut(l[7].toInt());
2282 setFixedPitch(l[8].toInt());
2283 setRawMode(l[9].toInt());
2285 if (count >= 9 && !d->request.fixedPitch) // assume 'false' fixedPitch equals default
2286 d->request.ignorePitch = true;
2291 #if !defined(Q_WS_QWS)
2294 Internal function that dumps font cache statistics.
2296 void QFont::cacheStatistics()
2305 /*****************************************************************************
2306 QFont stream functions
2307 *****************************************************************************/
2308 #ifndef QT_NO_DATASTREAM
2313 Writes the font \a font to the data stream \a s. (toString()
2314 writes to a text stream.)
2316 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
2318 QDataStream &operator<<(QDataStream &s, const QFont &font)
2320 if (s.version() == 1) {
2321 s << font.d->request.family.toLatin1();
2323 s << font.d->request.family;
2326 if (s.version() >= QDataStream::Qt_4_0) {
2328 double pointSize = font.d->request.pointSize;
2329 qint32 pixelSize = font.d->request.pixelSize;
2332 } else if (s.version() <= 3) {
2333 qint16 pointSize = (qint16) (font.d->request.pointSize * 10);
2334 if (pointSize < 0) {
2336 pointSize = (qint16)(font.d->request.pixelSize*720/QX11Info::appDpiY());
2338 pointSize = (qint16)QFontInfo(font).pointSize() * 10;
2343 s << (qint16) (font.d->request.pointSize * 10);
2344 s << (qint16) font.d->request.pixelSize;
2347 s << (quint8) font.d->request.styleHint;
2348 if (s.version() >= QDataStream::Qt_3_1)
2349 s << (quint8) font.d->request.styleStrategy;
2351 << (quint8) font.d->request.weight
2352 << get_font_bits(s.version(), font.d.data());
2353 if (s.version() >= QDataStream::Qt_4_3)
2354 s << (quint16)font.d->request.stretch;
2355 if (s.version() >= QDataStream::Qt_4_4)
2356 s << get_extended_font_bits(font.d.data());
2357 if (s.version() >= QDataStream::Qt_4_5) {
2358 s << font.d->letterSpacing.value();
2359 s << font.d->wordSpacing.value();
2368 Reads the font \a font from the data stream \a s. (fromString()
2369 reads from a text stream.)
2371 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
2373 QDataStream &operator>>(QDataStream &s, QFont &font)
2375 font.d = new QFontPrivate;
2376 font.resolve_mask = QFont::AllPropertiesResolved;
2378 quint8 styleHint, styleStrategy = QFont::PreferDefault, charSet, weight, bits;
2380 if (s.version() == 1) {
2383 font.d->request.family = QString::fromLatin1(fam);
2385 s >> font.d->request.family;
2388 if (s.version() >= QDataStream::Qt_4_0) {
2394 font.d->request.pointSize = qreal(pointSize);
2395 font.d->request.pixelSize = pixelSize;
2397 qint16 pointSize, pixelSize = -1;
2399 if (s.version() >= 4)
2401 font.d->request.pointSize = qreal(pointSize / 10.);
2402 font.d->request.pixelSize = pixelSize;
2405 if (s.version() >= QDataStream::Qt_3_1)
2412 font.d->request.styleHint = styleHint;
2413 font.d->request.styleStrategy = styleStrategy;
2414 font.d->request.weight = weight;
2416 set_font_bits(s.version(), bits, font.d.data());
2418 if (s.version() >= QDataStream::Qt_4_3) {
2421 font.d->request.stretch = stretch;
2424 if (s.version() >= QDataStream::Qt_4_4) {
2425 quint8 extendedBits;
2427 set_extended_font_bits(extendedBits, font.d.data());
2429 if (s.version() >= QDataStream::Qt_4_5) {
2432 font.d->letterSpacing.setValue(value);
2434 font.d->wordSpacing.setValue(value);
2440 #endif // QT_NO_DATASTREAM
2443 /*****************************************************************************
2444 QFontInfo member functions
2445 *****************************************************************************/
2451 \brief The QFontInfo class provides general information about fonts.
2456 The QFontInfo class provides the same access functions as QFont,
2457 e.g. family(), pointSize(), italic(), weight(), fixedPitch(),
2458 styleHint() etc. But whilst the QFont access functions return the
2459 values that were set, a QFontInfo object returns the values that
2460 apply to the font that will actually be used to draw the text.
2462 For example, when the program asks for a 25pt Courier font on a
2463 machine that has a non-scalable 24pt Courier font, QFont will
2464 (normally) use the 24pt Courier for rendering. In this case,
2465 QFont::pointSize() returns 25 and QFontInfo::pointSize() returns
2468 There are three ways to create a QFontInfo object.
2470 \o Calling the QFontInfo constructor with a QFont creates a font
2471 info object for a screen-compatible font, i.e. the font cannot be
2472 a printer font. If the font is changed later, the font
2473 info object is \e not updated.
2475 (Note: If you use a printer font the values returned may be
2476 inaccurate. Printer fonts are not always accessible so the nearest
2477 screen font is used if a printer font is supplied.)
2479 \o QWidget::fontInfo() returns the font info for a widget's font.
2480 This is equivalent to calling QFontInfo(widget->font()). If the
2481 widget's font is changed later, the font info object is \e not
2484 \o QPainter::fontInfo() returns the font info for a painter's
2485 current font. If the painter's font is changed later, the font
2486 info object is \e not updated.
2489 \sa QFont QFontMetrics QFontDatabase
2493 Constructs a font info object for \a font.
2495 The font must be screen-compatible, i.e. a font you use when
2496 drawing text in \link QWidget widgets\endlink or \link QPixmap
2497 pixmaps\endlink, not QPicture or QPrinter.
2499 The font info object holds the information for the font that is
2500 passed in the constructor at the time it is created, and is not
2501 updated if the font's attributes are changed later.
2503 Use QPainter::fontInfo() to get the font info when painting.
2504 This will give correct results also when painting on paint device
2505 that is not screen-compatible.
2507 QFontInfo::QFontInfo(const QFont &font)
2513 Constructs a copy of \a fi.
2515 QFontInfo::QFontInfo(const QFontInfo &fi)
2521 Destroys the font info object.
2523 QFontInfo::~QFontInfo()
2528 Assigns the font info in \a fi.
2530 QFontInfo &QFontInfo::operator=(const QFontInfo &fi)
2537 Returns the family name of the matched window system font.
2541 QString QFontInfo::family() const
2543 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2544 Q_ASSERT(engine != 0);
2545 return engine->fontDef.family;
2551 Returns the style name of the matched window system font on
2552 system that supports it.
2554 \sa QFont::styleName()
2556 QString QFontInfo::styleName() const
2558 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2559 Q_ASSERT(engine != 0);
2560 return engine->fontDef.styleName;
2564 Returns the point size of the matched window system font.
2566 \sa pointSizeF() QFont::pointSize()
2568 int QFontInfo::pointSize() const
2570 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2571 Q_ASSERT(engine != 0);
2572 return qRound(engine->fontDef.pointSize);
2576 Returns the point size of the matched window system font.
2578 \sa QFont::pointSizeF()
2580 qreal QFontInfo::pointSizeF() const
2582 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2583 Q_ASSERT(engine != 0);
2584 return engine->fontDef.pointSize;
2588 Returns the pixel size of the matched window system font.
2590 \sa QFont::pointSize()
2592 int QFontInfo::pixelSize() const
2594 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2595 Q_ASSERT(engine != 0);
2596 return engine->fontDef.pixelSize;
2600 Returns the italic value of the matched window system font.
2604 bool QFontInfo::italic() const
2606 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2607 Q_ASSERT(engine != 0);
2608 return engine->fontDef.style != QFont::StyleNormal;
2612 Returns the style value of the matched window system font.
2616 QFont::Style QFontInfo::style() const
2618 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2619 Q_ASSERT(engine != 0);
2620 return (QFont::Style)engine->fontDef.style;
2624 Returns the weight of the matched window system font.
2626 \sa QFont::weight(), bold()
2628 int QFontInfo::weight() const
2630 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2631 Q_ASSERT(engine != 0);
2632 return engine->fontDef.weight;
2637 \fn bool QFontInfo::bold() const
2639 Returns true if weight() would return a value greater than
2640 QFont::Normal; otherwise returns false.
2642 \sa weight(), QFont::bold()
2646 Returns the underline value of the matched window system font.
2648 \sa QFont::underline()
2652 Here we read the underline flag directly from the QFont.
2653 This is OK for X11 and for Windows because we always get what we want.
2655 bool QFontInfo::underline() const
2657 return d->underline;
2661 Returns the overline value of the matched window system font.
2663 \sa QFont::overline()
2667 Here we read the overline flag directly from the QFont.
2668 This is OK for X11 and for Windows because we always get what we want.
2670 bool QFontInfo::overline() const
2676 Returns the strikeout value of the matched window system font.
2678 \sa QFont::strikeOut()
2680 \internal Here we read the strikeOut flag directly from the QFont.
2681 This is OK for X11 and for Windows because we always get what we want.
2683 bool QFontInfo::strikeOut() const
2685 return d->strikeOut;
2689 Returns the fixed pitch value of the matched window system font.
2691 \sa QFont::fixedPitch()
2693 bool QFontInfo::fixedPitch() const
2695 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2696 Q_ASSERT(engine != 0);
2698 if (!engine->fontDef.fixedPitchComputed) {
2699 QChar ch[2] = { QLatin1Char('i'), QLatin1Char('m') };
2700 QGlyphLayoutArray<2> g;
2702 engine->stringToCMap(ch, 2, &g, &l, 0);
2703 engine->fontDef.fixedPitch = g.advances_x[0] == g.advances_x[1];
2704 engine->fontDef.fixedPitchComputed = true;
2707 return engine->fontDef.fixedPitch;
2711 Returns the style of the matched window system font.
2713 Currently only returns the style hint set in QFont.
2715 \sa QFont::styleHint() QFont::StyleHint
2717 QFont::StyleHint QFontInfo::styleHint() const
2719 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2720 Q_ASSERT(engine != 0);
2721 return (QFont::StyleHint) engine->fontDef.styleHint;
2725 Returns true if the font is a raw mode font; otherwise returns
2728 If it is a raw mode font, all other functions in QFontInfo will
2729 return the same values set in the QFont, regardless of the font
2732 \sa QFont::rawMode()
2734 bool QFontInfo::rawMode() const
2740 Returns true if the matched window system font is exactly the same
2741 as the one specified by the font; otherwise returns false.
2743 \sa QFont::exactMatch()
2745 bool QFontInfo::exactMatch() const
2747 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2748 Q_ASSERT(engine != 0);
2750 ? engine->type() != QFontEngine::Box
2751 : d->request.exactMatch(engine->fontDef));
2757 // **********************************************************************
2759 // **********************************************************************
2761 #ifdef QFONTCACHE_DEBUG
2762 // fast timeouts for debugging
2763 static const int fast_timeout = 1000; // 1s
2764 static const int slow_timeout = 5000; // 5s
2766 static const int fast_timeout = 10000; // 10s
2767 static const int slow_timeout = 300000; // 5m
2768 #endif // QFONTCACHE_DEBUG
2770 const uint QFontCache::min_cost = 4*1024; // 4mb
2773 Q_GLOBAL_STATIC(QFontCache, theFontCache)
2775 QFontCache *QFontCache::instance()
2777 return theFontCache();
2780 void QFontCache::cleanup()
2784 Q_GLOBAL_STATIC(QThreadStorage<QFontCache *>, theFontCache)
2786 QFontCache *QFontCache::instance()
2788 QFontCache *&fontCache = theFontCache()->localData();
2790 fontCache = new QFontCache;
2794 void QFontCache::cleanup()
2796 QThreadStorage<QFontCache *> *cache = 0;
2798 cache = theFontCache();
2799 } QT_CATCH (const std::bad_alloc &) {
2800 // no cache - just ignore
2802 if (cache && cache->hasLocalData())
2803 cache->setLocalData(0);
2805 #endif // QT_NO_THREAD
2807 QFontCache::QFontCache()
2808 : QObject(), total_cost(0), max_cost(min_cost),
2809 current_timestamp(0), fast(false), timer_id(-1)
2813 QFontCache::~QFontCache()
2817 EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
2818 end = engineDataCache.constEnd();
2820 if (it.value()->ref == 0)
2823 FC_DEBUG("QFontCache::~QFontCache: engineData %p still has refcount %d",
2824 it.value(), int(it.value()->ref));
2828 EngineCache::ConstIterator it = engineCache.constBegin(),
2829 end = engineCache.constEnd();
2831 if (--it.value().data->cache_count == 0) {
2832 if (it.value().data->ref == 0) {
2833 FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %g %d %d %d)",
2834 it.value().data, it.key().script, it.key().def.pointSize,
2835 it.key().def.pixelSize, it.key().def.weight, it.key().def.style,
2836 it.key().def.fixedPitch);
2838 delete it.value().data;
2840 FC_DEBUG("QFontCache::~QFontCache: engine = %p still has refcount %d",
2841 it.value().data, int(it.value().data->ref));
2848 void QFontCache::clear()
2851 EngineDataCache::Iterator it = engineDataCache.begin(),
2852 end = engineDataCache.end();
2854 QFontEngineData *data = it.value();
2855 #if !defined(Q_WS_MAC)
2856 for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
2857 if (data->engines[i]) {
2858 data->engines[i]->ref.deref();
2859 data->engines[i] = 0;
2864 data->engine->ref.deref();
2872 for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
2874 if (it->data->ref == 0) {
2880 for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
2882 if (it->data && it->data->ref == 0) {
2888 engineCache.clear();
2891 #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_QPF2)
2892 void QFontCache::removeEngineForFont(const QByteArray &_fontName)
2895 /* This could be optimized but the code becomes much more complex if we want to handle multi
2896 * font engines and it is probably not worth it. Therefore we just clear the entire font cache.
2898 Q_UNUSED(_fontName);
2903 QFontEngineData *QFontCache::findEngineData(const Key &key) const
2905 EngineDataCache::ConstIterator it = engineDataCache.find(key),
2906 end = engineDataCache.end();
2907 if (it == end) return 0;
2913 void QFontCache::insertEngineData(const Key &key, QFontEngineData *engineData)
2915 FC_DEBUG("QFontCache: inserting new engine data %p", engineData);
2917 engineDataCache.insert(key, engineData);
2918 increaseCost(sizeof(QFontEngineData));
2921 QFontEngine *QFontCache::findEngine(const Key &key)
2923 EngineCache::Iterator it = engineCache.find(key),
2924 end = engineCache.end();
2925 if (it == end) return 0;
2927 // found... update the hitcount and timestamp
2929 it.value().timestamp = ++current_timestamp;
2931 FC_DEBUG("QFontCache: found font engine\n"
2932 " %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'",
2933 it.value().data, it.value().timestamp, it.value().hits,
2934 int(it.value().data->ref), it.value().data->cache_count,
2935 it.value().data->name());
2937 return it.value().data;
2940 void QFontCache::insertEngine(const Key &key, QFontEngine *engine)
2942 FC_DEBUG("QFontCache: inserting new engine %p", engine);
2944 Engine data(engine);
2945 data.timestamp = ++current_timestamp;
2947 engineCache.insert(key, data);
2949 // only increase the cost if this is the first time we insert the engine
2950 if (engine->cache_count == 0)
2951 increaseCost(engine->cache_cost);
2953 ++engine->cache_count;
2956 void QFontCache::increaseCost(uint cost)
2958 cost = (cost + 512) / 1024; // store cost in kb
2959 cost = cost > 0 ? cost : 1;
2962 FC_DEBUG(" COST: increased %u kb, total_cost %u kb, max_cost %u kb",
2963 cost, total_cost, max_cost);
2965 if (total_cost > max_cost) {
2966 max_cost = total_cost;
2968 if (timer_id == -1 || ! fast) {
2969 FC_DEBUG(" TIMER: starting fast timer (%d ms)", fast_timeout);
2971 if (timer_id != -1) killTimer(timer_id);
2972 timer_id = startTimer(fast_timeout);
2978 void QFontCache::decreaseCost(uint cost)
2980 cost = (cost + 512) / 1024; // cost is stored in kb
2981 cost = cost > 0 ? cost : 1;
2982 Q_ASSERT(cost <= total_cost);
2985 FC_DEBUG(" COST: decreased %u kb, total_cost %u kb, max_cost %u kb",
2986 cost, total_cost, max_cost);
2989 #if defined(Q_WS_WIN) || defined (Q_WS_QWS)
2990 void QFontCache::cleanupPrinterFonts()
2992 FC_DEBUG("QFontCache::cleanupPrinterFonts");
2995 FC_DEBUG(" CLEAN engine data:");
2997 // clean out all unused engine data
2998 EngineDataCache::Iterator it = engineDataCache.begin(),
2999 end = engineDataCache.end();
3001 if (it.key().screen == 0) {
3006 if(it.value()->ref != 0) {
3007 for(int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
3008 if(it.value()->engines[i]) {
3009 it.value()->engines[i]->ref.deref();
3010 it.value()->engines[i] = 0;
3016 EngineDataCache::Iterator rem = it++;
3018 decreaseCost(sizeof(QFontEngineData));
3020 FC_DEBUG(" %p", rem.value());
3023 engineDataCache.erase(rem);
3028 EngineCache::Iterator it = engineCache.begin(),
3029 end = engineCache.end();
3031 if (it.value().data->ref != 0 || it.key().screen == 0) {
3036 FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'",
3037 it.value().data, it.value().timestamp, it.value().hits,
3038 int(it.value().data->ref), it.value().data->cache_count,
3039 it.value().data->name());
3041 if (--it.value().data->cache_count == 0) {
3042 FC_DEBUG(" DELETE: last occurrence in cache");
3044 decreaseCost(it.value().data->cache_cost);
3045 delete it.value().data;
3048 engineCache.erase(it++);
3053 void QFontCache::timerEvent(QTimerEvent *)
3055 FC_DEBUG("QFontCache::timerEvent: performing cache maintenance (timestamp %u)",
3058 if (total_cost <= max_cost && max_cost <= min_cost) {
3059 FC_DEBUG(" cache redused sufficiently, stopping timer");
3061 killTimer(timer_id);
3068 // go through the cache and count up everything in use
3069 uint in_use_cost = 0;
3072 FC_DEBUG(" SWEEP engine data:");
3074 // make sure the cost of each engine data is at least 1kb
3075 const uint engine_data_cost =
3076 sizeof(QFontEngineData) > 1024 ? sizeof(QFontEngineData) : 1024;
3078 EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
3079 end = engineDataCache.constEnd();
3080 for (; it != end; ++it) {
3081 #ifdef QFONTCACHE_DEBUG
3082 FC_DEBUG(" %p: ref %2d", it.value(), int(it.value()->ref));
3084 # if defined(Q_WS_X11) || defined(Q_WS_WIN)
3085 // print out all engines
3086 for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
3087 if (! it.value()->engines[i])
3089 FC_DEBUG(" contains %p", it.value()->engines[i]);
3091 # endif // Q_WS_X11 || Q_WS_WIN
3092 #endif // QFONTCACHE_DEBUG
3094 if (it.value()->ref != 0)
3095 in_use_cost += engine_data_cost;
3100 FC_DEBUG(" SWEEP engine:");
3102 EngineCache::ConstIterator it = engineCache.constBegin(),
3103 end = engineCache.constEnd();
3104 for (; it != end; ++it) {
3105 FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, cost %u bytes",
3106 it.value().data, it.value().timestamp, it.value().hits,
3107 int(it.value().data->ref), it.value().data->cache_count,
3108 it.value().data->cache_cost);
3110 if (it.value().data->ref != 0)
3111 in_use_cost += it.value().data->cache_cost / it.value().data->cache_count;
3114 // attempt to make up for rounding errors
3115 in_use_cost += engineCache.size();
3118 in_use_cost = (in_use_cost + 512) / 1024; // cost is stored in kb
3121 calculate the new maximum cost for the cache
3123 NOTE: in_use_cost is *not* correct due to rounding errors in the
3124 above algorithm. instead of worrying about getting the
3125 calculation correct, we are more interested in speed, and use
3126 in_use_cost as a floor for new_max_cost
3128 uint new_max_cost = qMax(qMax(max_cost / 2, in_use_cost), min_cost);
3130 FC_DEBUG(" after sweep, in use %u kb, total %u kb, max %u kb, new max %u kb",
3131 in_use_cost, total_cost, max_cost, new_max_cost);
3133 if (new_max_cost == max_cost) {
3135 FC_DEBUG(" cannot shrink cache, slowing timer");
3137 killTimer(timer_id);
3138 timer_id = startTimer(slow_timeout);
3143 } else if (! fast) {
3144 FC_DEBUG(" dropping into passing gear");
3146 killTimer(timer_id);
3147 timer_id = startTimer(fast_timeout);
3151 max_cost = new_max_cost;
3154 FC_DEBUG(" CLEAN engine data:");
3156 // clean out all unused engine data
3157 EngineDataCache::Iterator it = engineDataCache.begin(),
3158 end = engineDataCache.end();
3160 if (it.value()->ref != 0) {
3165 EngineDataCache::Iterator rem = it++;
3167 decreaseCost(sizeof(QFontEngineData));
3169 FC_DEBUG(" %p", rem.value());
3172 engineDataCache.erase(rem);
3176 // clean out the engine cache just enough to get below our new max cost
3179 current_cost = total_cost;
3181 EngineCache::Iterator it = engineCache.begin(),
3182 end = engineCache.end();
3183 // determine the oldest and least popular of the unused engines
3185 uint least_popular = ~0u;
3187 for (; it != end; ++it) {
3188 if (it.value().data->ref != 0)
3191 if (it.value().timestamp < oldest &&
3192 it.value().hits <= least_popular) {
3193 oldest = it.value().timestamp;
3194 least_popular = it.value().hits;
3198 FC_DEBUG(" oldest %u least popular %u", oldest, least_popular);
3200 for (it = engineCache.begin(); it != end; ++it) {
3201 if (it.value().data->ref == 0 &&
3202 it.value().timestamp == oldest &&
3203 it.value().hits == least_popular)
3208 FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'",
3209 it.value().data, it.value().timestamp, it.value().hits,
3210 int(it.value().data->ref), it.value().data->cache_count,
3211 it.value().data->name());
3213 if (--it.value().data->cache_count == 0) {
3214 FC_DEBUG(" DELETE: last occurrence in cache");
3216 decreaseCost(it.value().data->cache_cost);
3217 delete it.value().data;
3220 this particular font engine is in the cache multiple
3221 times... set current_cost to zero, so that we can
3222 keep looping to get rid of all occurrences
3227 engineCache.erase(it);
3229 } while (current_cost != total_cost && total_cost > max_cost);
3233 #ifndef QT_NO_DEBUG_STREAM
3234 QDebug operator<<(QDebug stream, const QFont &font)
3236 return stream << "QFont(" << font.toString() << ')';