Get started with patching up the Qt GUI docs
[profile/ivi/qtbase.git] / src / gui / text / qfont.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qfont.h"
43 #include "qdebug.h"
44 #include "qpaintdevice.h"
45 #include "qfontdatabase.h"
46 #include "qfontmetrics.h"
47 #include "qfontinfo.h"
48 #include "qpainter.h"
49 #include "qhash.h"
50 #include "qdatastream.h"
51 #include "qguiapplication.h"
52 #include "qstringlist.h"
53 #include "qscreen.h"
54
55 #include "qthread.h"
56 #include "qthreadstorage.h"
57
58 #include <private/qunicodetables_p.h>
59 #include "qfont_p.h"
60 #include <private/qfontengine_p.h>
61 #include <private/qpainter_p.h>
62 #include <private/qtextengine_p.h>
63 #include <limits.h>
64
65 #include <qpa/qplatformscreen.h>
66 #include <QtGui/private/qguiapplication_p.h>
67
68 #include <QtCore/QMutexLocker>
69 #include <QtCore/QMutex>
70
71 // #define QFONTCACHE_DEBUG
72 #ifdef QFONTCACHE_DEBUG
73 #  define FC_DEBUG qDebug
74 #else
75 #  define FC_DEBUG if (false) qDebug
76 #endif
77
78 QT_BEGIN_NAMESPACE
79
80
81
82 bool QFontDef::exactMatch(const QFontDef &other) const
83 {
84     /*
85       QFontDef comparison is more complicated than just simple
86       per-member comparisons.
87
88       When comparing point/pixel sizes, either point or pixelsize
89       could be -1.  in This case we have to compare the non negative
90       size value.
91
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.
96
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
100       positive results.
101     */
102     if (pixelSize != -1 && other.pixelSize != -1) {
103         if (pixelSize != other.pixelSize)
104             return false;
105     } else if (pointSize != -1 && other.pointSize != -1) {
106         if (pointSize != other.pointSize)
107             return false;
108     } else {
109         return false;
110     }
111
112     if (!ignorePitch && !other.ignorePitch && fixedPitch != other.fixedPitch)
113         return false;
114
115     if (stretch != 0 && other.stretch != 0 && stretch != other.stretch)
116         return false;
117
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);
121
122     this_family = QFontDatabase::resolveFontFamilyAlias(this_family);
123     other_family = QFontDatabase::resolveFontFamilyAlias(other_family);
124
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)
134        );
135 }
136
137 extern bool qt_is_gui_used;
138
139 Q_GUI_EXPORT int qt_defaultDpiX()
140 {
141     if (qApp->testAttribute(Qt::AA_Use96Dpi))
142         return 96;
143
144     if (!qt_is_gui_used)
145         return 75;
146
147     if (const QScreen *screen = QGuiApplication::primaryScreen())
148         return qRound(screen->logicalDotsPerInchX());
149
150     //PI has not been initialised, or it is being initialised. Give a default dpi
151     return 100;
152 }
153
154 Q_GUI_EXPORT int qt_defaultDpiY()
155 {
156     if (qApp->testAttribute(Qt::AA_Use96Dpi))
157         return 96;
158
159     if (!qt_is_gui_used)
160         return 75;
161
162     if (const QScreen *screen = QGuiApplication::primaryScreen())
163         return qRound(screen->logicalDotsPerInchY());
164
165     //PI has not been initialised, or it is being initialised. Give a default dpi
166     return 100;
167 }
168
169 Q_GUI_EXPORT int qt_defaultDpi()
170 {
171     return qt_defaultDpiY();
172 }
173
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)
178 {
179 }
180
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),
187       scFont(other.scFont)
188 {
189     if (scFont && scFont != this)
190         scFont->ref.ref();
191 }
192
193 QFontPrivate::~QFontPrivate()
194 {
195     if (engineData)
196         engineData->ref.deref();
197     engineData = 0;
198     if (scFont && scFont != this)
199         scFont->ref.deref();
200     scFont = 0;
201 }
202
203 extern QMutex *qt_fontdatabase_mutex();
204
205 #define QT_FONT_ENGINE_FROM_DATA(data, script) data->engines[script]
206
207 QFontEngine *QFontPrivate::engineForScript(int script) const
208 {
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();
215         engineData = 0;
216     }
217     if (!engineData || !QT_FONT_ENGINE_FROM_DATA(engineData, script))
218         QFontDatabase::load(this, script);
219     return QT_FONT_ENGINE_FROM_DATA(engineData, script);
220 }
221
222 void QFontPrivate::alterCharForCapitalization(QChar &c) const {
223     switch (capital) {
224     case QFont::AllUppercase:
225     case QFont::SmallCaps:
226         c = c.toUpper();
227         break;
228     case QFont::AllLowercase:
229         c = c.toLower();
230         break;
231     case QFont::MixedCase:
232         break;
233     }
234 }
235
236 QFontPrivate *QFontPrivate::smallCapsFontPrivate() const
237 {
238     if (scFont)
239         return scFont;
240     QFont font(const_cast<QFontPrivate *>(this));
241     qreal pointSize = font.pointSizeF();
242     if (pointSize > 0)
243         font.setPointSizeF(pointSize * .7);
244     else
245         font.setPixelSize((font.pixelSize() * 7 + 5) / 10);
246     scFont = font.d.data();
247     if (scFont != this)
248         scFont->ref.ref();
249     return scFont;
250 }
251
252
253 void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
254 {
255     Q_ASSERT(other != 0);
256
257     dpi = other->dpi;
258
259     if ((mask & QFont::AllPropertiesResolved) == QFont::AllPropertiesResolved) return;
260
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;
264
265     if (! (mask & QFont::StyleNameResolved))
266         request.styleName = other->request.styleName;
267
268     if (! (mask & QFont::SizeResolved)) {
269         request.pointSize = other->request.pointSize;
270         request.pixelSize = other->request.pixelSize;
271     }
272
273     if (! (mask & QFont::StyleHintResolved))
274         request.styleHint = other->request.styleHint;
275
276     if (! (mask & QFont::StyleStrategyResolved))
277         request.styleStrategy = other->request.styleStrategy;
278
279     if (! (mask & QFont::WeightResolved))
280         request.weight = other->request.weight;
281
282     if (! (mask & QFont::StyleResolved))
283         request.style = other->request.style;
284
285     if (! (mask & QFont::FixedPitchResolved))
286         request.fixedPitch = other->request.fixedPitch;
287
288     if (! (mask & QFont::StretchResolved))
289         request.stretch = other->request.stretch;
290
291     if (! (mask & QFont::HintingPreferenceResolved))
292         request.hintingPreference = other->request.hintingPreference;
293
294     if (! (mask & QFont::UnderlineResolved))
295         underline = other->underline;
296
297     if (! (mask & QFont::OverlineResolved))
298         overline = other->overline;
299
300     if (! (mask & QFont::StrikeOutResolved))
301         strikeOut = other->strikeOut;
302
303     if (! (mask & QFont::KerningResolved))
304         kerning = other->kerning;
305
306     if (! (mask & QFont::LetterSpacingResolved)) {
307         letterSpacing = other->letterSpacing;
308         letterSpacingIsAbsolute = other->letterSpacingIsAbsolute;
309     }
310     if (! (mask & QFont::WordSpacingResolved))
311         wordSpacing = other->wordSpacing;
312     if (! (mask & QFont::CapitalizationResolved))
313         capital = other->capital;
314 }
315
316
317
318
319 QFontEngineData::QFontEngineData()
320     : ref(1), fontCache(QFontCache::instance())
321 {
322     memset(engines, 0, QUnicodeTables::ScriptCount * sizeof(QFontEngine *));
323 }
324
325 QFontEngineData::~QFontEngineData()
326 {
327     for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
328         if (engines[i])
329             engines[i]->ref.deref();
330         engines[i] = 0;
331     }
332 }
333
334
335
336
337 /*!
338     \class QFont
339     \reentrant
340
341     \brief The QFont class specifies a font used for drawing text.
342
343     \ingroup painting
344     \ingroup appearance
345     \ingroup shared
346     \ingroup richtext-processing
347     \inmodule QtGui
348
349
350     When you create a QFont object you specify various attributes that
351     you want the font to have. Qt will use the font with the specified
352     attributes, or if no matching font exists, Qt will use the closest
353     matching installed font. The attributes of the font that is
354     actually used are retrievable from a QFontInfo object. If the
355     window system provides an exact match exactMatch() returns true.
356     Use QFontMetrics to get measurements, e.g. the pixel length of a
357     string using QFontMetrics::width().
358
359     Note that a QGuiApplication instance must exist before a QFont can be
360     used. You can set the application's default font with
361     QGuiApplication::setFont().
362
363     If a chosen font does not include all the characters that
364     need to be displayed, QFont will try to find the characters in the
365     nearest equivalent fonts. When a QPainter draws a character from a
366     font the QFont will report whether or not it has the character; if
367     it does not, QPainter will draw an unfilled square.
368
369     Create QFonts like this:
370
371     \snippet code/src_gui_text_qfont.cpp 0
372
373     The attributes set in the constructor can also be set later, e.g.
374     setFamily(), setPointSize(), setPointSizeFloat(), setWeight() and
375     setItalic(). The remaining attributes must be set after
376     contstruction, e.g. setBold(), setUnderline(), setOverline(),
377     setStrikeOut() and setFixedPitch(). QFontInfo objects should be
378     created \e after the font's attributes have been set. A QFontInfo
379     object will not change, even if you change the font's
380     attributes. The corresponding "get" functions, e.g. family(),
381     pointSize(), etc., return the values that were set, even though
382     the values used may differ. The actual values are available from a
383     QFontInfo object.
384
385     If the requested font family is unavailable you can influence the
386     \l{#fontmatching}{font matching algorithm} by choosing a
387     particular \l{QFont::StyleHint} and \l{QFont::StyleStrategy} with
388     setStyleHint(). The default family (corresponding to the current
389     style hint) is returned by defaultFamily().
390
391     The font-matching algorithm has a lastResortFamily() and
392     lastResortFont() in cases where a suitable match cannot be found.
393     You can provide substitutions for font family names using
394     insertSubstitution() and insertSubstitutions(). Substitutions can
395     be removed with removeSubstitutions(). Use substitute() to retrieve
396     a family's first substitute, or the family name itself if it has
397     no substitutes. Use substitutes() to retrieve a list of a family's
398     substitutes (which may be empty).
399
400     Every QFont has a key() which you can use, for example, as the key
401     in a cache or dictionary. If you want to store a user's font
402     preferences you could use QSettings, writing the font information
403     with toString() and reading it back with fromString(). The
404     operator<<() and operator>>() functions are also available, but
405     they work on a data stream.
406
407     It is possible to set the height of characters shown on the screen
408     to a specified number of pixels with setPixelSize(); however using
409     setPointSize() has a similar effect and provides device
410     independence.
411
412     In X11 you can set a font using its system
413     specific name with setRawName().
414
415     Loading fonts can be expensive, especially on X11. QFont contains
416     extensive optimizations to make the copying of QFont objects fast,
417     and to cache the results of the slow window system functions it
418     depends upon.
419
420     \target fontmatching
421     The font matching algorithm works as follows:
422     \list 1
423     \li The specified font family is searched for.
424     \li If not found, the styleHint() is used to select a replacement
425        family.
426     \li Each replacement font family is searched for.
427     \li If none of these are found or there was no styleHint(), "helvetica"
428        will be searched for.
429     \li If "helvetica" isn't found Qt will try the lastResortFamily().
430     \li If the lastResortFamily() isn't found Qt will try the
431        lastResortFont() which will always return a name of some kind.
432     \endlist
433
434     Note that the actual font matching algorithm varies from platform to platform.
435
436     In Windows a request for the "Courier" font is automatically changed to
437     "Courier New", an improved version of Courier that allows for smooth scaling.
438     The older "Courier" bitmap font can be selected by setting the PreferBitmap
439     style strategy (see setStyleStrategy()).
440
441     Once a font is found, the remaining attributes are matched in order of
442     priority:
443     \list 1
444     \li fixedPitch()
445     \li pointSize() (see below)
446     \li weight()
447     \li style()
448     \endlist
449
450     If you have a font which matches on family, even if none of the
451     other attributes match, this font will be chosen in preference to
452     a font which doesn't match on family but which does match on the
453     other attributes. This is because font family is the dominant
454     search criteria.
455
456     The point size is defined to match if it is within 20% of the
457     requested point size. When several fonts match and are only
458     distinguished by point size, the font with the closest point size
459     to the one requested will be chosen.
460
461     The actual family, font size, weight and other font attributes
462     used for drawing text will depend on what's available for the
463     chosen family under the window system. A QFontInfo object can be
464     used to determine the actual values used for drawing the text.
465
466     Examples:
467
468     \snippet code/src_gui_text_qfont.cpp 1
469     If you had both an Adobe and a Cronyx Helvetica, you might get
470     either.
471
472     \snippet code/src_gui_text_qfont.cpp 2
473
474     You can specify the foundry you want in the family name. The font f
475     in the above example will be set to "Helvetica
476     [Cronyx]".
477
478     To determine the attributes of the font actually used in the window
479     system, use a QFontInfo object, e.g.
480
481     \snippet code/src_gui_text_qfont.cpp 3
482
483     To find out font metrics use a QFontMetrics object, e.g.
484
485     \snippet code/src_gui_text_qfont.cpp 4
486
487     For more general information on fonts, see the
488     \l{comp.fonts FAQ}{comp.fonts FAQ}.
489     Information on encodings can be found from
490     \l{Roman Czyborra's} page.
491
492     \sa QFontComboBox, QFontMetrics, QFontInfo, QFontDatabase, {Character Map Example}
493 */
494
495 /*!
496     \internal
497     \enum QFont::ResolveProperties
498
499     This enum describes the properties of a QFont that can be set on a font
500     individually and then considered resolved.
501
502     \value FamilyResolved
503     \value SizeResolved
504     \value StyleHintResolved
505     \value StyleStrategyResolved
506     \value WeightResolved
507     \value StyleResolved
508     \value UnderlineResolved
509     \value OverlineResolved
510     \value StrikeOutResolved
511     \value FixedPitchResolved
512     \value StretchResolved
513     \value KerningResolved
514     \value CapitalizationResolved
515     \value LetterSpacingResolved
516     \value WordSpacingResolved
517     \value CompletelyResolved
518 */
519
520 /*!
521     \enum QFont::Style
522
523     This enum describes the different styles of glyphs that are used to
524     display text.
525
526     \value StyleNormal  Normal glyphs used in unstyled text.
527     \value StyleItalic  Italic glyphs that are specifically designed for
528                         the purpose of representing italicized text.
529     \value StyleOblique Glyphs with an italic appearance that are typically
530                         based on the unstyled glyphs, but are not fine-tuned
531                         for the purpose of representing italicized text.
532
533     \sa Weight
534 */
535
536 /*!
537     \fn FT_Face QFont::freetypeFace() const
538
539     Returns the handle to the primary FreeType face of the font. If font merging is not disabled a
540     QFont can contain several physical fonts.
541
542     Returns 0 if the font does not contain a FreeType face.
543
544     \note This function is only available on platforms that provide the FreeType library;
545     i.e., X11 and some Embedded Linux platforms.
546 */
547
548 /*!
549     \fn QString QFont::rawName() const
550
551     Returns the name of the font within the underlying window system.
552
553     On X11, this function will return an empty string.
554
555     Using the return value of this function is usually \e not \e
556     portable.
557
558     \sa setRawName()
559 */
560
561 /*!
562     \fn void QFont::setRawName(const QString &name)
563
564     Sets a font by its system specific name.
565
566     A font set with setRawName() is still a full-featured QFont. It can
567     be queried (for example with italic()) or modified (for example with
568     setItalic()) and is therefore also suitable for rendering rich text.
569
570     If Qt's internal font database cannot resolve the raw name, the
571     font becomes a raw font with \a name as its family.
572
573     \sa rawName(), setRawMode(), setFamily()
574 */
575
576 /*!
577     \fn QString QFont::lastResortFamily() const
578
579     Returns the "last resort" font family name.
580
581     The current implementation tries a wide variety of common fonts,
582     returning the first one it finds. Is is possible that no family is
583     found in which case an empty string is returned.
584
585     \sa lastResortFont()
586 */
587
588 /*!
589     \fn QString QFont::defaultFamily() const
590
591     Returns the family name that corresponds to the current style
592     hint.
593
594     \sa StyleHint, styleHint(), setStyleHint()
595 */
596
597 /*!
598     \fn QString QFont::lastResortFont() const
599
600     Returns a "last resort" font name for the font matching algorithm.
601     This is used if the last resort family is not available. It will
602     always return a name, if necessary returning something like
603     "fixed" or "system".
604
605     The current implementation tries a wide variety of common fonts,
606     returning the first one it finds. The implementation may change
607     at any time, but this function will always return a string
608     containing something.
609
610     It is theoretically possible that there really isn't a
611     lastResortFont() in which case Qt will abort with an error
612     message. We have not been able to identify a case where this
613     happens. Please \l{bughowto.html}{report it as a bug} if
614     it does, preferably with a list of the fonts you have installed.
615
616     \sa lastResortFamily(), rawName()
617 */
618
619 /*!
620   Constructs a font from \a font for use on the paint device \a pd.
621 */
622 QFont::QFont(const QFont &font, QPaintDevice *pd)
623     : resolve_mask(font.resolve_mask)
624 {
625     Q_ASSERT(pd != 0);
626     int dpi = pd->logicalDpiY();
627     const int screen = 0;
628     if (font.d->dpi != dpi || font.d->screen != screen ) {
629         d = new QFontPrivate(*font.d);
630         d->dpi = dpi;
631         d->screen = screen;
632     } else {
633         d = font.d.data();
634     }
635 }
636
637 /*!
638   \internal
639 */
640 QFont::QFont(QFontPrivate *data)
641     : d(data), resolve_mask(QFont::AllPropertiesResolved)
642 {
643 }
644
645 /*! \internal
646     Detaches the font object from common font data.
647 */
648 void QFont::detach()
649 {
650     if (d->ref.load() == 1) {
651         if (d->engineData)
652             d->engineData->ref.deref();
653         d->engineData = 0;
654         if (d->scFont && d->scFont != d.data())
655             d->scFont->ref.deref();
656         d->scFont = 0;
657         return;
658     }
659
660     d.detach();
661 }
662
663 /*!
664     Constructs a font object that uses the application's default font.
665
666     \sa QGuiApplication::setFont(), QGuiApplication::font()
667 */
668 QFont::QFont()
669     : d(QGuiApplication::font().d.data()), resolve_mask(0)
670 {
671 }
672
673 /*!
674     Constructs a font object with the specified \a family, \a
675     pointSize, \a weight and \a italic settings.
676
677     If \a pointSize is zero or negative, the point size of the font
678     is set to a system-dependent default value. Generally, this is
679     12 points.
680
681     The \a family name may optionally also include a foundry name,
682     e.g. "Helvetica [Cronyx]". If the \a family is
683     available from more than one foundry and the foundry isn't
684     specified, an arbitrary foundry is chosen. If the family isn't
685     available a family will be set using the \l{QFont}{font matching}
686     algorithm.
687
688     \sa Weight, setFamily(), setPointSize(), setWeight(), setItalic(),
689     setStyleHint(), QGuiApplication::font()
690 */
691 QFont::QFont(const QString &family, int pointSize, int weight, bool italic)
692     : d(new QFontPrivate()), resolve_mask(QFont::FamilyResolved)
693 {
694     if (pointSize <= 0) {
695         pointSize = 12;
696     } else {
697         resolve_mask |= QFont::SizeResolved;
698     }
699
700     if (weight < 0) {
701         weight = Normal;
702     } else {
703         resolve_mask |= QFont::WeightResolved | QFont::StyleResolved;
704     }
705
706     if (italic)
707         resolve_mask |= QFont::StyleResolved;
708
709     d->request.family = family;
710     d->request.pointSize = qreal(pointSize);
711     d->request.pixelSize = -1;
712     d->request.weight = weight;
713     d->request.style = italic ? QFont::StyleItalic : QFont::StyleNormal;
714 }
715
716 /*!
717     Constructs a font that is a copy of \a font.
718 */
719 QFont::QFont(const QFont &font)
720     : d(font.d.data()), resolve_mask(font.resolve_mask)
721 {
722 }
723
724 /*!
725     Destroys the font object and frees all allocated resources.
726 */
727 QFont::~QFont()
728 {
729 }
730
731 /*!
732     Assigns \a font to this font and returns a reference to it.
733 */
734 QFont &QFont::operator=(const QFont &font)
735 {
736     d = font.d.data();
737     resolve_mask = font.resolve_mask;
738     return *this;
739 }
740
741 /*!
742     Returns the requested font family name, i.e. the name set in the
743     constructor or the last setFont() call.
744
745     \sa setFamily(), substitutes(), substitute()
746 */
747 QString QFont::family() const
748 {
749     return d->request.family;
750 }
751
752 /*!
753     Sets the family name of the font. The name is case insensitive and
754     may include a foundry name.
755
756     The \a family name may optionally also include a foundry name,
757     e.g. "Helvetica [Cronyx]". If the \a family is
758     available from more than one foundry and the foundry isn't
759     specified, an arbitrary foundry is chosen. If the family isn't
760     available a family will be set using the \l{QFont}{font matching}
761     algorithm.
762
763     \sa family(), setStyleHint(), QFontInfo
764 */
765 void QFont::setFamily(const QString &family)
766 {
767     detach();
768
769     d->request.family = family;
770
771     resolve_mask |= QFont::FamilyResolved;
772 }
773
774 /*!
775     \since 4.8
776
777     Returns the requested font style name, it will be used to match the
778     font with irregular styles (that can't be normalized in other style
779     properties). It depends on system font support, thus only works for
780     Mac OS X and X11 so far. On Windows irregular styles will be added
781     as separate font families so there is no need for this.
782
783     \sa setFamily(), setStyle()
784 */
785 QString QFont::styleName() const
786 {
787     return d->request.styleName;
788 }
789
790 /*!
791     \since 4.8
792
793     Sets the style name of the font. When set, other style properties
794     like \a style() and \a weight() will be ignored for font matching.
795
796     \sa styleName()
797 */
798 void QFont::setStyleName(const QString &styleName)
799 {
800     detach();
801
802     d->request.styleName = styleName;
803     resolve_mask |= QFont::StyleNameResolved;
804 }
805
806 /*!
807     Returns the point size of the font. Returns -1 if the font size
808     was specified in pixels.
809
810     \sa setPointSize(), pointSizeF()
811 */
812 int QFont::pointSize() const
813 {
814     return qRound(d->request.pointSize);
815 }
816
817 /*!
818     \since 4.8
819
820     \enum QFont::HintingPreference
821
822     This enum describes the different levels of hinting that can be applied
823     to glyphs to improve legibility on displays where it might be warranted
824     by the density of pixels.
825
826     \value PreferDefaultHinting Use the default hinting level for the target platform.
827     \value PreferNoHinting If possible, render text without hinting the outlines
828            of the glyphs. The text layout will be typographically accurate and
829            scalable, using the same metrics as are used e.g. when printing.
830     \value PreferVerticalHinting If possible, render text with no horizontal hinting,
831            but align glyphs to the pixel grid in the vertical direction. The text will appear
832            crisper on displays where the density is too low to give an accurate rendering
833            of the glyphs. But since the horizontal metrics of the glyphs are unhinted, the text's
834            layout will be scalable to higher density devices (such as printers) without impacting
835            details such as line breaks.
836     \value PreferFullHinting If possible, render text with hinting in both horizontal and
837            vertical directions. The text will be altered to optimize legibility on the target
838            device, but since the metrics will depend on the target size of the text, the positions
839            of glyphs, line breaks, and other typographical detail will not scale, meaning that a
840            text layout may look different on devices with different pixel densities.
841
842     Please note that this enum only describes a preference, as the full range of hinting levels
843     are not supported on all of Qt's supported platforms. The following table details the effect
844     of a given hinting preference on a selected set of target platforms.
845
846     \table
847     \header
848     \li
849     \li PreferDefaultHinting
850     \li PreferNoHinting
851     \li PreferVerticalHinting
852     \li PreferFullHinting
853     \row
854     \li Windows Vista (w/o Platform Update) and earlier
855     \li Full hinting
856     \li Full hinting
857     \li Full hinting
858     \li Full hinting
859     \row
860     \li Windows 7 and Windows Vista (w/Platform Update) and DirectWrite enabled in Qt
861     \li Full hinting
862     \li Vertical hinting
863     \li Vertical hinting
864     \li Full hinting
865     \row
866     \li FreeType
867     \li Operating System setting
868     \li No hinting
869     \li Vertical hinting (light)
870     \li Full hinting
871     \row
872     \li Cocoa on Mac OS X
873     \li No hinting
874     \li No hinting
875     \li No hinting
876     \li No hinting
877     \endtable
878
879     \note Please be aware that altering the hinting preference on Windows is available through
880     the DirectWrite font engine. This is available on Windows Vista after installing the platform
881     update, and on Windows 7. In order to use this extension, configure Qt using -directwrite.
882     The target application will then depend on the availability of DirectWrite on the target
883     system.
884
885 */
886
887 /*!
888     \since 4.8
889
890     Set the preference for the hinting level of the glyphs to \a hintingPreference. This is a hint
891     to the underlying font rendering system to use a certain level of hinting, and has varying
892     support across platforms. See the table in the documentation for QFont::HintingPreference for
893     more details.
894
895     The default hinting preference is QFont::PreferDefaultHinting.
896 */
897 void QFont::setHintingPreference(HintingPreference hintingPreference)
898 {
899     detach();
900
901     d->request.hintingPreference = hintingPreference;
902
903     resolve_mask |= QFont::HintingPreferenceResolved;
904 }
905
906 /*!
907     \since 4.8
908
909     Returns the currently preferred hinting level for glyphs rendered with this font.
910 */
911 QFont::HintingPreference QFont::hintingPreference() const
912 {
913     return QFont::HintingPreference(d->request.hintingPreference);
914 }
915
916 /*!
917     Sets the point size to \a pointSize. The point size must be
918     greater than zero.
919
920     \sa pointSize(), setPointSizeF()
921 */
922 void QFont::setPointSize(int pointSize)
923 {
924     if (pointSize <= 0) {
925         qWarning("QFont::setPointSize: Point size <= 0 (%d), must be greater than 0", pointSize);
926         return;
927     }
928
929     detach();
930
931     d->request.pointSize = qreal(pointSize);
932     d->request.pixelSize = -1;
933
934     resolve_mask |= QFont::SizeResolved;
935 }
936
937 /*!
938     Sets the point size to \a pointSize. The point size must be
939     greater than zero. The requested precision may not be achieved on
940     all platforms.
941
942     \sa pointSizeF(), setPointSize(), setPixelSize()
943 */
944 void QFont::setPointSizeF(qreal pointSize)
945 {
946     if (pointSize <= 0) {
947         qWarning("QFont::setPointSizeF: Point size <= 0 (%f), must be greater than 0", pointSize);
948         return;
949     }
950
951     detach();
952
953     d->request.pointSize = pointSize;
954     d->request.pixelSize = -1;
955
956     resolve_mask |= QFont::SizeResolved;
957 }
958
959 /*!
960     Returns the point size of the font. Returns -1 if the font size was
961     specified in pixels.
962
963     \sa pointSize(), setPointSizeF(), pixelSize(), QFontInfo::pointSize(), QFontInfo::pixelSize()
964 */
965 qreal QFont::pointSizeF() const
966 {
967     return d->request.pointSize;
968 }
969
970 /*!
971     Sets the font size to \a pixelSize pixels.
972
973     Using this function makes the font device dependent. Use
974     setPointSize() or setPointSizeF() to set the size of the font
975     in a device independent manner.
976
977     \sa pixelSize()
978 */
979 void QFont::setPixelSize(int pixelSize)
980 {
981     if (pixelSize <= 0) {
982         qWarning("QFont::setPixelSize: Pixel size <= 0 (%d)", pixelSize);
983         return;
984     }
985
986     detach();
987
988     d->request.pixelSize = pixelSize;
989     d->request.pointSize = -1;
990
991     resolve_mask |= QFont::SizeResolved;
992 }
993
994 /*!
995     Returns the pixel size of the font if it was set with
996     setPixelSize(). Returns -1 if the size was set with setPointSize()
997     or setPointSizeF().
998
999     \sa setPixelSize(), pointSize(), QFontInfo::pointSize(), QFontInfo::pixelSize()
1000 */
1001 int QFont::pixelSize() const
1002 {
1003     return d->request.pixelSize;
1004 }
1005
1006 /*!
1007   \fn bool QFont::italic() const
1008
1009     Returns true if the style() of the font is not QFont::StyleNormal
1010
1011     \sa setItalic(), style()
1012 */
1013
1014 /*!
1015   \fn void QFont::setItalic(bool enable)
1016
1017   Sets the style() of the font to QFont::StyleItalic if \a enable is true;
1018   otherwise the style is set to QFont::StyleNormal.
1019
1020   \sa italic(), QFontInfo
1021 */
1022
1023 /*!
1024     Returns the style of the font.
1025
1026     \sa setStyle()
1027 */
1028 QFont::Style QFont::style() const
1029 {
1030     return (QFont::Style)d->request.style;
1031 }
1032
1033
1034 /*!
1035   Sets the style of the font to \a style.
1036
1037   \sa italic(), QFontInfo
1038 */
1039 void QFont::setStyle(Style style)
1040 {
1041     detach();
1042
1043     d->request.style = style;
1044     resolve_mask |= QFont::StyleResolved;
1045 }
1046
1047 /*!
1048     Returns the weight of the font which is one of the enumerated
1049     values from \l{QFont::Weight}.
1050
1051     \sa setWeight(), Weight, QFontInfo
1052 */
1053 int QFont::weight() const
1054 {
1055     return d->request.weight;
1056 }
1057
1058 /*!
1059     \enum QFont::Weight
1060
1061     Qt uses a weighting scale from 0 to 99 similar to, but not the
1062     same as, the scales used in Windows or CSS. A weight of 0 is
1063     ultralight, whilst 99 will be an extremely black.
1064
1065     This enum contains the predefined font weights:
1066
1067     \value Light 25
1068     \value Normal 50
1069     \value DemiBold 63
1070     \value Bold 75
1071     \value Black 87
1072 */
1073
1074 /*!
1075     Sets the weight the font to \a weight, which should be a value
1076     from the \l QFont::Weight enumeration.
1077
1078     \sa weight(), QFontInfo
1079 */
1080 void QFont::setWeight(int weight)
1081 {
1082     Q_ASSERT_X(weight >= 0 && weight <= 99, "QFont::setWeight", "Weight must be between 0 and 99");
1083
1084     detach();
1085
1086     d->request.weight = weight;
1087     resolve_mask |= QFont::WeightResolved;
1088 }
1089
1090 /*!
1091     \fn bool QFont::bold() const
1092
1093     Returns true if weight() is a value greater than
1094    \l{Weight}{QFont::Normal}; otherwise returns false.
1095
1096     \sa weight(), setBold(), QFontInfo::bold()
1097 */
1098
1099 /*!
1100     \fn void QFont::setBold(bool enable)
1101
1102     If \a enable is true sets the font's weight to
1103     \l{Weight}{QFont::Bold};
1104     otherwise sets the weight to \l{Weight}{QFont::Normal}.
1105
1106     For finer boldness control use setWeight().
1107
1108     \sa bold(), setWeight()
1109 */
1110
1111 /*!
1112     Returns true if underline has been set; otherwise returns false.
1113
1114     \sa setUnderline()
1115 */
1116 bool QFont::underline() const
1117 {
1118     return d->underline;
1119 }
1120
1121 /*!
1122     If \a enable is true, sets underline on; otherwise sets underline
1123     off.
1124
1125     \sa underline(), QFontInfo
1126 */
1127 void QFont::setUnderline(bool enable)
1128 {
1129     detach();
1130
1131     d->underline = enable;
1132     resolve_mask |= QFont::UnderlineResolved;
1133 }
1134
1135 /*!
1136     Returns true if overline has been set; otherwise returns false.
1137
1138     \sa setOverline()
1139 */
1140 bool QFont::overline() const
1141 {
1142     return d->overline;
1143 }
1144
1145 /*!
1146   If \a enable is true, sets overline on; otherwise sets overline off.
1147
1148   \sa overline(), QFontInfo
1149 */
1150 void QFont::setOverline(bool enable)
1151 {
1152     detach();
1153
1154     d->overline = enable;
1155     resolve_mask |= QFont::OverlineResolved;
1156 }
1157
1158 /*!
1159     Returns true if strikeout has been set; otherwise returns false.
1160
1161     \sa setStrikeOut()
1162 */
1163 bool QFont::strikeOut() const
1164 {
1165     return d->strikeOut;
1166 }
1167
1168 /*!
1169     If \a enable is true, sets strikeout on; otherwise sets strikeout
1170     off.
1171
1172     \sa strikeOut(), QFontInfo
1173 */
1174 void QFont::setStrikeOut(bool enable)
1175 {
1176     detach();
1177
1178     d->strikeOut = enable;
1179     resolve_mask |= QFont::StrikeOutResolved;
1180 }
1181
1182 /*!
1183     Returns true if fixed pitch has been set; otherwise returns false.
1184
1185     \sa setFixedPitch(), QFontInfo::fixedPitch()
1186 */
1187 bool QFont::fixedPitch() const
1188 {
1189     return d->request.fixedPitch;
1190 }
1191
1192 /*!
1193     If \a enable is true, sets fixed pitch on; otherwise sets fixed
1194     pitch off.
1195
1196     \sa fixedPitch(), QFontInfo
1197 */
1198 void QFont::setFixedPitch(bool enable)
1199 {
1200     detach();
1201
1202     d->request.fixedPitch = enable;
1203     d->request.ignorePitch = false;
1204     resolve_mask |= QFont::FixedPitchResolved;
1205 }
1206
1207 /*!
1208   Returns true if kerning should be used when drawing text with this font.
1209
1210   \sa setKerning()
1211 */
1212 bool QFont::kerning() const
1213 {
1214     return d->kerning;
1215 }
1216
1217 /*!
1218     Enables kerning for this font if \a enable is true; otherwise
1219     disables it. By default, kerning is enabled.
1220
1221     When kerning is enabled, glyph metrics do not add up anymore,
1222     even for Latin text. In other words, the assumption that
1223     width('a') + width('b') is equal to width("ab") is not
1224     neccesairly true.
1225
1226     \sa kerning(), QFontMetrics
1227 */
1228 void QFont::setKerning(bool enable)
1229 {
1230     detach();
1231     d->kerning = enable;
1232     resolve_mask |= QFont::KerningResolved;
1233 }
1234
1235 /*!
1236     Returns the StyleStrategy.
1237
1238     The style strategy affects the \l{QFont}{font matching} algorithm.
1239     See \l QFont::StyleStrategy for the list of available strategies.
1240
1241     \sa setStyleHint(), QFont::StyleHint
1242 */
1243 QFont::StyleStrategy QFont::styleStrategy() const
1244 {
1245     return (StyleStrategy) d->request.styleStrategy;
1246 }
1247
1248 /*!
1249     Returns the StyleHint.
1250
1251     The style hint affects the \l{QFont}{font matching} algorithm.
1252     See \l QFont::StyleHint for the list of available hints.
1253
1254     \sa setStyleHint(), QFont::StyleStrategy, QFontInfo::styleHint()
1255 */
1256 QFont::StyleHint QFont::styleHint() const
1257 {
1258     return (StyleHint) d->request.styleHint;
1259 }
1260
1261 /*!
1262     \enum QFont::StyleHint
1263
1264     Style hints are used by the \l{QFont}{font matching} algorithm to
1265     find an appropriate default family if a selected font family is
1266     not available.
1267
1268     \value AnyStyle leaves the font matching algorithm to choose the
1269            family. This is the default.
1270
1271     \value SansSerif the font matcher prefer sans serif fonts.
1272     \value Helvetica is a synonym for \c SansSerif.
1273
1274     \value Serif the font matcher prefers serif fonts.
1275     \value Times is a synonym for \c Serif.
1276
1277     \value TypeWriter the font matcher prefers fixed pitch fonts.
1278     \value Courier a synonym for \c TypeWriter.
1279
1280     \value OldEnglish the font matcher prefers decorative fonts.
1281     \value Decorative is a synonym for \c OldEnglish.
1282
1283     \value Monospace the font matcher prefers fonts that map to the
1284     CSS generic font-family 'monospace'.
1285
1286     \value Fantasy the font matcher prefers fonts that map to the
1287     CSS generic font-family 'fantasy'.
1288
1289     \value Cursive the font matcher prefers fonts that map to the
1290     CSS generic font-family 'cursive'.
1291
1292     \value System the font matcher prefers system fonts.
1293 */
1294
1295 /*!
1296     \enum QFont::StyleStrategy
1297
1298     The style strategy tells the \l{QFont}{font matching} algorithm
1299     what type of fonts should be used to find an appropriate default
1300     family.
1301
1302     The following strategies are available:
1303
1304     \value PreferDefault the default style strategy. It does not prefer
1305            any type of font.
1306     \value PreferBitmap prefers bitmap fonts (as opposed to outline
1307            fonts).
1308     \value PreferDevice prefers device fonts.
1309     \value PreferOutline prefers outline fonts (as opposed to bitmap fonts).
1310     \value ForceOutline forces the use of outline fonts.
1311     \value NoAntialias don't antialias the fonts.
1312     \value PreferAntialias antialias if possible.
1313     \value OpenGLCompatible forces the use of OpenGL compatible
1314            fonts.
1315     \value NoFontMerging If the font selected for a certain writing system
1316            does not contain a character requested to draw, then Qt automatically chooses a similar
1317            looking font that contains the character. The NoFontMerging flag disables this feature.
1318            Please note that enabling this flag will not prevent Qt from automatically picking a
1319            suitable font when the selected font does not support the writing system of the text.
1320
1321     Any of these may be OR-ed with one of these flags:
1322
1323     \value PreferMatch prefer an exact match. The font matcher will try to
1324            use the exact font size that has been specified.
1325     \value PreferQuality prefer the best quality font. The font matcher
1326            will use the nearest standard point size that the font
1327            supports.
1328     \value ForceIntegerMetrics forces the use of integer values in font engines that support fractional
1329            font metrics.
1330 */
1331
1332 /*!
1333     Sets the style hint and strategy to \a hint and \a strategy,
1334     respectively.
1335
1336     If these aren't set explicitly the style hint will default to
1337     \c AnyStyle and the style strategy to \c PreferDefault.
1338
1339     Qt does not support style hints on X11 since this information
1340     is not provided by the window system.
1341
1342     \sa StyleHint, styleHint(), StyleStrategy, styleStrategy(), QFontInfo
1343 */
1344 void QFont::setStyleHint(StyleHint hint, StyleStrategy strategy)
1345 {
1346     detach();
1347
1348     if ((resolve_mask & (QFont::StyleHintResolved | QFont::StyleStrategyResolved)) &&
1349          (StyleHint) d->request.styleHint == hint &&
1350          (StyleStrategy) d->request.styleStrategy == strategy)
1351         return;
1352
1353     d->request.styleHint = hint;
1354     d->request.styleStrategy = strategy;
1355     resolve_mask |= QFont::StyleHintResolved;
1356     resolve_mask |= QFont::StyleStrategyResolved;
1357
1358 }
1359
1360 /*!
1361     Sets the style strategy for the font to \a s.
1362
1363     \sa QFont::StyleStrategy
1364 */
1365 void QFont::setStyleStrategy(StyleStrategy s)
1366 {
1367     detach();
1368
1369     if ((resolve_mask & QFont::StyleStrategyResolved) &&
1370          s == (StyleStrategy)d->request.styleStrategy)
1371         return;
1372
1373     d->request.styleStrategy = s;
1374     resolve_mask |= QFont::StyleStrategyResolved;
1375 }
1376
1377
1378 /*!
1379     \enum QFont::Stretch
1380
1381     Predefined stretch values that follow the CSS naming convention. The higher
1382     the value, the more stretched the text is.
1383
1384     \value UltraCondensed 50
1385     \value ExtraCondensed 62
1386     \value Condensed 75
1387     \value SemiCondensed 87
1388     \value Unstretched 100
1389     \value SemiExpanded 112
1390     \value Expanded 125
1391     \value ExtraExpanded 150
1392     \value UltraExpanded 200
1393
1394     \sa setStretch(), stretch()
1395 */
1396
1397 /*!
1398     Returns the stretch factor for the font.
1399
1400     \sa setStretch()
1401  */
1402 int QFont::stretch() const
1403 {
1404     return d->request.stretch;
1405 }
1406
1407 /*!
1408     Sets the stretch factor for the font.
1409
1410     The stretch factor changes the width of all characters in the font
1411     by \a factor percent.  For example, setting \a factor to 150
1412     results in all characters in the font being 1.5 times (ie. 150%)
1413     wider.  The default stretch factor is 100.  The minimum stretch
1414     factor is 1, and the maximum stretch factor is 4000.
1415
1416     The stretch factor is only applied to outline fonts.  The stretch
1417     factor is ignored for bitmap fonts.
1418
1419     \sa stretch(), QFont::Stretch
1420 */
1421 void QFont::setStretch(int factor)
1422 {
1423     if (factor < 1 || factor > 4000) {
1424         qWarning("QFont::setStretch: Parameter '%d' out of range", factor);
1425         return;
1426     }
1427
1428     if ((resolve_mask & QFont::StretchResolved) &&
1429          d->request.stretch == (uint)factor)
1430         return;
1431
1432     detach();
1433
1434     d->request.stretch = (uint)factor;
1435     resolve_mask |= QFont::StretchResolved;
1436 }
1437
1438 /*!
1439     \enum QFont::SpacingType
1440     \since 4.4
1441
1442     \value PercentageSpacing  A value of 100 will keep the spacing unchanged; a value of 200 will enlarge the
1443                                                    spacing after a character by the width of the character itself.
1444     \value AbsoluteSpacing      A positive value increases the letter spacing by the corresponding pixels; a negative
1445                                                    value decreases the spacing.
1446 */
1447
1448 /*!
1449     \since 4.4
1450     Returns the letter spacing for the font.
1451
1452     \sa setLetterSpacing(), letterSpacingType(), setWordSpacing()
1453  */
1454 qreal QFont::letterSpacing() const
1455 {
1456     return d->letterSpacing.toReal();
1457 }
1458
1459 /*!
1460     \since 4.4
1461     Sets the letter spacing for the font to \a spacing and the type
1462     of spacing to \a type.
1463
1464     Letter spacing changes the default spacing between individual
1465     letters in the font.  The spacing between the letters can be
1466     made smaller as well as larger.
1467
1468     \sa letterSpacing(), letterSpacingType(), setWordSpacing()
1469 */
1470 void QFont::setLetterSpacing(SpacingType type, qreal spacing)
1471 {
1472     const QFixed newSpacing = QFixed::fromReal(spacing);
1473     const bool absoluteSpacing = type == AbsoluteSpacing;
1474     if ((resolve_mask & QFont::LetterSpacingResolved) &&
1475         d->letterSpacingIsAbsolute == absoluteSpacing &&
1476         d->letterSpacing == newSpacing)
1477         return;
1478
1479     detach();
1480
1481     d->letterSpacing = newSpacing;
1482     d->letterSpacingIsAbsolute = absoluteSpacing;
1483     resolve_mask |= QFont::LetterSpacingResolved;
1484 }
1485
1486 /*!
1487     \since 4.4
1488     Returns the spacing type used for letter spacing.
1489
1490     \sa letterSpacing(), setLetterSpacing(), setWordSpacing()
1491 */
1492 QFont::SpacingType QFont::letterSpacingType() const
1493 {
1494     return d->letterSpacingIsAbsolute ? AbsoluteSpacing : PercentageSpacing;
1495 }
1496
1497 /*!
1498     \since 4.4
1499     Returns the word spacing for the font.
1500
1501     \sa setWordSpacing(), setLetterSpacing()
1502  */
1503 qreal QFont::wordSpacing() const
1504 {
1505     return d->wordSpacing.toReal();
1506 }
1507
1508 /*!
1509     \since 4.4
1510     Sets the word spacing for the font to \a spacing.
1511
1512     Word spacing changes the default spacing between individual
1513     words. A positive value increases the word spacing
1514     by a corresponding amount of pixels, while a negative value
1515     decreases the inter-word spacing accordingly.
1516
1517     Word spacing will not apply to writing systems, where indiviaul
1518     words are not separated by white space.
1519
1520     \sa wordSpacing(), setLetterSpacing()
1521 */
1522 void QFont::setWordSpacing(qreal spacing)
1523 {
1524     const QFixed newSpacing = QFixed::fromReal(spacing);
1525     if ((resolve_mask & QFont::WordSpacingResolved) &&
1526         d->wordSpacing == newSpacing)
1527         return;
1528
1529     detach();
1530
1531     d->wordSpacing = newSpacing;
1532     resolve_mask |= QFont::WordSpacingResolved;
1533 }
1534
1535 /*!
1536     \enum QFont::Capitalization
1537     \since 4.4
1538
1539     Rendering option for text this font applies to.
1540
1541
1542     \value MixedCase    This is the normal text rendering option where no capitalization change is applied.
1543     \value AllUppercase This alters the text to be rendered in all uppercase type.
1544     \value AllLowercase This alters the text to be rendered in all lowercase type.
1545     \value SmallCaps    This alters the text to be rendered in small-caps type.
1546     \value Capitalize   This alters the text to be rendered with the first character of each word as an uppercase character.
1547 */
1548
1549 /*!
1550     \since 4.4
1551     Sets the capitalization of the text in this font to \a caps.
1552
1553     A font's capitalization makes the text appear in the selected capitalization mode.
1554
1555     \sa capitalization()
1556 */
1557 void QFont::setCapitalization(Capitalization caps)
1558 {
1559     if ((resolve_mask & QFont::CapitalizationResolved) &&
1560         capitalization() == caps)
1561         return;
1562
1563     detach();
1564
1565     d->capital = caps;
1566     resolve_mask |= QFont::CapitalizationResolved;
1567 }
1568
1569 /*!
1570     \since 4.4
1571     Returns the current capitalization type of the font.
1572
1573     \sa setCapitalization()
1574 */
1575 QFont::Capitalization QFont::capitalization() const
1576 {
1577     return static_cast<QFont::Capitalization> (d->capital);
1578 }
1579
1580
1581 /*!
1582     If \a enable is true, turns raw mode on; otherwise turns raw mode
1583     off. This function only has an effect under X11.
1584
1585     If raw mode is enabled, Qt will search for an X font with a
1586     complete font name matching the family name, ignoring all other
1587     values set for the QFont. If the font name matches several fonts,
1588     Qt will use the first font returned by X. QFontInfo \e cannot be
1589     used to fetch information about a QFont using raw mode (it will
1590     return the values set in the QFont for all parameters, including
1591     the family name).
1592
1593     \warning Do not use raw mode unless you really, really need it! In
1594     most (if not all) cases, setRawName() is a much better choice.
1595
1596     \sa rawMode(), setRawName()
1597 */
1598 void QFont::setRawMode(bool enable)
1599 {
1600     detach();
1601
1602     if ((bool) d->rawMode == enable) return;
1603
1604     d->rawMode = enable;
1605 }
1606
1607 /*!
1608     Returns true if a window system font exactly matching the settings
1609     of this font is available.
1610
1611     \sa QFontInfo
1612 */
1613 bool QFont::exactMatch() const
1614 {
1615     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1616     Q_ASSERT(engine != 0);
1617     return (d->rawMode
1618             ? engine->type() != QFontEngine::Box
1619             : d->request.exactMatch(engine->fontDef));
1620 }
1621
1622 /*!
1623     Returns true if this font is equal to \a f; otherwise returns
1624     false.
1625
1626     Two QFonts are considered equal if their font attributes are
1627     equal. If rawMode() is enabled for both fonts, only the family
1628     fields are compared.
1629
1630     \sa operator!=(), isCopyOf()
1631 */
1632 bool QFont::operator==(const QFont &f) const
1633 {
1634     return (f.d == d
1635             || (f.d->request   == d->request
1636                 && f.d->request.pointSize == d->request.pointSize
1637                 && f.d->underline == d->underline
1638                 && f.d->overline  == d->overline
1639                 && f.d->strikeOut == d->strikeOut
1640                 && f.d->kerning == d->kerning
1641                 && f.d->capital == d->capital
1642                 && f.d->letterSpacingIsAbsolute == d->letterSpacingIsAbsolute
1643                 && f.d->letterSpacing == d->letterSpacing
1644                 && f.d->wordSpacing == d->wordSpacing
1645             ));
1646 }
1647
1648
1649 /*!
1650     Provides an arbitrary comparison of this font and font \a f.
1651     All that is guaranteed is that the operator returns false if both
1652     fonts are equal and that (f1 \< f2) == !(f2 \< f1) if the fonts
1653     are not equal.
1654
1655     This function is useful in some circumstances, for example if you
1656     want to use QFont objects as keys in a QMap.
1657
1658     \sa operator==(), operator!=(), isCopyOf()
1659 */
1660 bool QFont::operator<(const QFont &f) const
1661 {
1662     if (f.d == d) return false;
1663     // the < operator for fontdefs ignores point sizes.
1664     QFontDef &r1 = f.d->request;
1665     QFontDef &r2 = d->request;
1666     if (r1.pointSize != r2.pointSize) return r1.pointSize < r2.pointSize;
1667     if (r1.pixelSize != r2.pixelSize) return r1.pixelSize < r2.pixelSize;
1668     if (r1.weight != r2.weight) return r1.weight < r2.weight;
1669     if (r1.style != r2.style) return r1.style < r2.style;
1670     if (r1.stretch != r2.stretch) return r1.stretch < r2.stretch;
1671     if (r1.styleHint != r2.styleHint) return r1.styleHint < r2.styleHint;
1672     if (r1.styleStrategy != r2.styleStrategy) return r1.styleStrategy < r2.styleStrategy;
1673     if (r1.family != r2.family) return r1.family < r2.family;
1674     if (f.d->capital != d->capital) return f.d->capital < d->capital;
1675
1676     if (f.d->letterSpacingIsAbsolute != d->letterSpacingIsAbsolute) return f.d->letterSpacingIsAbsolute < d->letterSpacingIsAbsolute;
1677     if (f.d->letterSpacing != d->letterSpacing) return f.d->letterSpacing < d->letterSpacing;
1678     if (f.d->wordSpacing != d->wordSpacing) return f.d->wordSpacing < d->wordSpacing;
1679
1680     int f1attrs = (f.d->underline << 3) + (f.d->overline << 2) + (f.d->strikeOut<<1) + f.d->kerning;
1681     int f2attrs = (d->underline << 3) + (d->overline << 2) + (d->strikeOut<<1) + d->kerning;
1682     return f1attrs < f2attrs;
1683 }
1684
1685
1686 /*!
1687     Returns true if this font is different from \a f; otherwise
1688     returns false.
1689
1690     Two QFonts are considered to be different if their font attributes
1691     are different. If rawMode() is enabled for both fonts, only the
1692     family fields are compared.
1693
1694     \sa operator==()
1695 */
1696 bool QFont::operator!=(const QFont &f) const
1697 {
1698     return !(operator==(f));
1699 }
1700
1701 /*!
1702    Returns the font as a QVariant
1703 */
1704 QFont::operator QVariant() const
1705 {
1706     return QVariant(QVariant::Font, this);
1707 }
1708
1709 /*!
1710     Returns true if this font and \a f are copies of each other, i.e.
1711     one of them was created as a copy of the other and neither has
1712     been modified since. This is much stricter than equality.
1713
1714     \sa operator=(), operator==()
1715 */
1716 bool QFont::isCopyOf(const QFont & f) const
1717 {
1718     return d == f.d;
1719 }
1720
1721 /*!
1722     Returns true if raw mode is used for font name matching; otherwise
1723     returns false.
1724
1725     \sa setRawMode(), rawName()
1726 */
1727 bool QFont::rawMode() const
1728 {
1729     return d->rawMode;
1730 }
1731
1732 /*!
1733     Returns a new QFont that has attributes copied from \a other that
1734     have not been previously set on this font.
1735 */
1736 QFont QFont::resolve(const QFont &other) const
1737 {
1738     if (*this == other
1739         && (resolve_mask == other.resolve_mask || resolve_mask == 0)
1740         && d->dpi == other.d->dpi) {
1741         QFont o = other;
1742         o.resolve_mask = resolve_mask;
1743         return o;
1744     }
1745
1746     QFont font(*this);
1747     font.detach();
1748     font.d->resolve(resolve_mask, other.d.data());
1749
1750     return font;
1751 }
1752
1753 /*!
1754     \fn uint QFont::resolve() const
1755     \internal
1756 */
1757
1758 /*!
1759     \fn void QFont::resolve(uint mask)
1760     \internal
1761 */
1762
1763
1764 /*****************************************************************************
1765   QFont substitution management
1766  *****************************************************************************/
1767
1768 typedef QHash<QString, QStringList> QFontSubst;
1769 Q_GLOBAL_STATIC(QFontSubst, globalFontSubst)
1770
1771 /*!
1772     Returns the first family name to be used whenever \a familyName is
1773     specified. The lookup is case insensitive.
1774
1775     If there is no substitution for \a familyName, \a familyName is
1776     returned.
1777
1778     To obtain a list of substitutions use substitutes().
1779
1780     \sa setFamily(), insertSubstitutions(), insertSubstitution(), removeSubstitutions()
1781 */
1782 QString QFont::substitute(const QString &familyName)
1783 {
1784     QFontSubst *fontSubst = globalFontSubst();
1785     Q_ASSERT(fontSubst != 0);
1786     QFontSubst::ConstIterator it = fontSubst->constFind(familyName.toLower());
1787     if (it != fontSubst->constEnd() && !(*it).isEmpty())
1788         return (*it).first();
1789
1790     return familyName;
1791 }
1792
1793
1794 /*!
1795     Returns a list of family names to be used whenever \a familyName
1796     is specified. The lookup is case insensitive.
1797
1798     If there is no substitution for \a familyName, an empty list is
1799     returned.
1800
1801     \sa substitute(), insertSubstitutions(), insertSubstitution(), removeSubstitutions()
1802  */
1803 QStringList QFont::substitutes(const QString &familyName)
1804 {
1805     QFontSubst *fontSubst = globalFontSubst();
1806     Q_ASSERT(fontSubst != 0);
1807     return fontSubst->value(familyName.toLower(), QStringList());
1808 }
1809
1810
1811 /*!
1812     Inserts \a substituteName into the substitution
1813     table for the family \a familyName.
1814
1815     \sa insertSubstitutions(), removeSubstitutions(), substitutions(), substitute(), substitutes()
1816 */
1817 void QFont::insertSubstitution(const QString &familyName,
1818                                const QString &substituteName)
1819 {
1820     QFontSubst *fontSubst = globalFontSubst();
1821     Q_ASSERT(fontSubst != 0);
1822     QStringList &list = (*fontSubst)[familyName.toLower()];
1823     QString s = substituteName.toLower();
1824     if (!list.contains(s))
1825         list.append(s);
1826 }
1827
1828
1829 /*!
1830     Inserts the list of families \a substituteNames into the
1831     substitution list for \a familyName.
1832
1833     \sa insertSubstitution(), removeSubstitutions(), substitutions(), substitute()
1834 */
1835 void QFont::insertSubstitutions(const QString &familyName,
1836                                 const QStringList &substituteNames)
1837 {
1838     QFontSubst *fontSubst = globalFontSubst();
1839     Q_ASSERT(fontSubst != 0);
1840     QStringList &list = (*fontSubst)[familyName.toLower()];
1841     foreach (const QString &substituteName, substituteNames) {
1842         const QString lowerSubstituteName = substituteName.toLower();
1843         if (!list.contains(lowerSubstituteName))
1844             list.append(lowerSubstituteName);
1845     }
1846 }
1847
1848 /*! \fn void QFont::initialize()
1849   \internal
1850
1851   Internal function that initializes the font system.  The font cache
1852   and font dict do not alloc the keys. The key is a QString which is
1853   shared between QFontPrivate and QXFontName.
1854 */
1855
1856 /*! \fn void QFont::cleanup()
1857   \internal
1858
1859   Internal function that cleans up the font system.
1860 */
1861
1862 /*!
1863     Removes all the substitutions for \a familyName.
1864
1865     \sa insertSubstitutions(), insertSubstitution(), substitutions(), substitute()
1866     \since 5.0
1867 */
1868 void QFont::removeSubstitutions(const QString &familyName)
1869 {
1870     QFontSubst *fontSubst = globalFontSubst();
1871     Q_ASSERT(fontSubst != 0);
1872     fontSubst->remove(familyName.toLower());
1873 }
1874
1875 /*!
1876     \fn void QFont::removeSubstitution(const QString &familyName)
1877
1878     \obsolete
1879
1880     This function is deprecated. Use removeSubstitutions() instead.
1881 */
1882
1883 /*!
1884     Returns a sorted list of substituted family names.
1885
1886     \sa insertSubstitution(), removeSubstitution(), substitute()
1887 */
1888 QStringList QFont::substitutions()
1889 {
1890     typedef QFontSubst::const_iterator QFontSubstConstIterator;
1891
1892     QFontSubst *fontSubst = globalFontSubst();
1893     Q_ASSERT(fontSubst != 0);
1894     QStringList ret;
1895     const QFontSubstConstIterator cend = fontSubst->constEnd();
1896     for (QFontSubstConstIterator it = fontSubst->constBegin(); it != cend; ++it)
1897         ret.append(it.key());
1898
1899     ret.sort();
1900     return ret;
1901 }
1902
1903
1904 /*  \internal
1905     Internal function. Converts boolean font settings to an unsigned
1906     8-bit number. Used for serialization etc.
1907 */
1908 static quint8 get_font_bits(int version, const QFontPrivate *f)
1909 {
1910     Q_ASSERT(f != 0);
1911     quint8 bits = 0;
1912     if (f->request.style)
1913         bits |= 0x01;
1914     if (f->underline)
1915         bits |= 0x02;
1916     if (f->overline)
1917         bits |= 0x40;
1918     if (f->strikeOut)
1919         bits |= 0x04;
1920     if (f->request.fixedPitch)
1921         bits |= 0x08;
1922     // if (f.hintSetByUser)
1923     // bits |= 0x10;
1924     if (f->rawMode)
1925         bits |= 0x20;
1926     if (version >= QDataStream::Qt_4_0) {
1927         if (f->kerning)
1928             bits |= 0x10;
1929     }
1930     if (f->request.style == QFont::StyleOblique)
1931         bits |= 0x80;
1932     return bits;
1933 }
1934
1935 static quint8 get_extended_font_bits(const QFontPrivate *f)
1936 {
1937     Q_ASSERT(f != 0);
1938     quint8 bits = 0;
1939     if (f->request.ignorePitch)
1940         bits |= 0x01;
1941     if (f->letterSpacingIsAbsolute)
1942         bits |= 0x02;
1943     return bits;
1944 }
1945
1946 #ifndef QT_NO_DATASTREAM
1947
1948 /*  \internal
1949     Internal function. Sets boolean font settings from an unsigned
1950     8-bit number. Used for serialization etc.
1951 */
1952 static void set_font_bits(int version, quint8 bits, QFontPrivate *f)
1953 {
1954     Q_ASSERT(f != 0);
1955     f->request.style         = (bits & 0x01) != 0 ? QFont::StyleItalic : QFont::StyleNormal;
1956     f->underline             = (bits & 0x02) != 0;
1957     f->overline              = (bits & 0x40) != 0;
1958     f->strikeOut             = (bits & 0x04) != 0;
1959     f->request.fixedPitch    = (bits & 0x08) != 0;
1960     // f->hintSetByUser      = (bits & 0x10) != 0;
1961     f->rawMode               = (bits & 0x20) != 0;
1962     if (version >= QDataStream::Qt_4_0)
1963         f->kerning               = (bits & 0x10) != 0;
1964     if ((bits & 0x80) != 0)
1965         f->request.style         = QFont::StyleOblique;
1966 }
1967
1968 static void set_extended_font_bits(quint8 bits, QFontPrivate *f)
1969 {
1970     Q_ASSERT(f != 0);
1971     f->request.ignorePitch = (bits & 0x01) != 0;
1972     f->letterSpacingIsAbsolute = (bits & 0x02) != 0;
1973 }
1974 #endif
1975
1976
1977 /*!
1978     Returns the font's key, a textual representation of a font. It is
1979     typically used as the key for a cache or dictionary of fonts.
1980
1981     \sa QMap
1982 */
1983 QString QFont::key() const
1984 {
1985     return toString();
1986 }
1987
1988 /*!
1989     Returns a description of the font. The description is a
1990     comma-separated list of the attributes, perfectly suited for use
1991     in QSettings.
1992
1993     \sa fromString()
1994  */
1995 QString QFont::toString() const
1996 {
1997     const QChar comma(QLatin1Char(','));
1998     return family() + comma +
1999         QString::number(     pointSizeF()) + comma +
2000         QString::number(      pixelSize()) + comma +
2001         QString::number((int) styleHint()) + comma +
2002         QString::number(         weight()) + comma +
2003         QString::number((int)     style()) + comma +
2004         QString::number((int) underline()) + comma +
2005         QString::number((int) strikeOut()) + comma +
2006         QString::number((int)fixedPitch()) + comma +
2007         QString::number((int)   rawMode());
2008 }
2009
2010
2011 /*!
2012     Sets this font to match the description \a descrip. The description
2013     is a comma-separated list of the font attributes, as returned by
2014     toString().
2015
2016     \sa toString()
2017  */
2018 bool QFont::fromString(const QString &descrip)
2019 {
2020     QStringList l(descrip.split(QLatin1Char(',')));
2021
2022     int count = l.count();
2023     if (!count || (count > 2 && count < 9) || count > 11) {
2024         qWarning("QFont::fromString: Invalid description '%s'",
2025                  descrip.isEmpty() ? "(empty)" : descrip.toLatin1().data());
2026         return false;
2027     }
2028
2029     setFamily(l[0]);
2030     if (count > 1 && l[1].toDouble() > 0.0)
2031         setPointSizeF(l[1].toDouble());
2032     if (count == 9) {
2033         setStyleHint((StyleHint) l[2].toInt());
2034         setWeight(qMax(qMin(99, l[3].toInt()), 0));
2035         setItalic(l[4].toInt());
2036         setUnderline(l[5].toInt());
2037         setStrikeOut(l[6].toInt());
2038         setFixedPitch(l[7].toInt());
2039         setRawMode(l[8].toInt());
2040     } else if (count == 10) {
2041         if (l[2].toInt() > 0)
2042             setPixelSize(l[2].toInt());
2043         setStyleHint((StyleHint) l[3].toInt());
2044         setWeight(qMax(qMin(99, l[4].toInt()), 0));
2045         setStyle((QFont::Style)l[5].toInt());
2046         setUnderline(l[6].toInt());
2047         setStrikeOut(l[7].toInt());
2048         setFixedPitch(l[8].toInt());
2049         setRawMode(l[9].toInt());
2050     }
2051     if (count >= 9 && !d->request.fixedPitch) // assume 'false' fixedPitch equals default
2052         d->request.ignorePitch = true;
2053
2054     return true;
2055 }
2056
2057 /*! \internal
2058
2059   Internal function that dumps font cache statistics.
2060 */
2061 void QFont::cacheStatistics()
2062 {
2063
2064
2065 }
2066
2067
2068
2069 /*****************************************************************************
2070   QFont stream functions
2071  *****************************************************************************/
2072 #ifndef QT_NO_DATASTREAM
2073
2074 /*!
2075     \relates QFont
2076
2077     Writes the font \a font to the data stream \a s. (toString()
2078     writes to a text stream.)
2079
2080     \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2081 */
2082 QDataStream &operator<<(QDataStream &s, const QFont &font)
2083 {
2084     if (s.version() == 1) {
2085         s << font.d->request.family.toLatin1();
2086     } else {
2087         s << font.d->request.family;
2088     }
2089
2090     if (s.version() >= QDataStream::Qt_4_0) {
2091         // 4.0
2092         double pointSize = font.d->request.pointSize;
2093         qint32 pixelSize = font.d->request.pixelSize;
2094         s << pointSize;
2095         s << pixelSize;
2096     } else if (s.version() <= 3) {
2097         qint16 pointSize = (qint16) (font.d->request.pointSize * 10);
2098         if (pointSize < 0) {
2099             pointSize = (qint16)QFontInfo(font).pointSize() * 10;
2100         }
2101         s << pointSize;
2102     } else {
2103         s << (qint16) (font.d->request.pointSize * 10);
2104         s << (qint16) font.d->request.pixelSize;
2105     }
2106
2107     s << (quint8) font.d->request.styleHint;
2108     if (s.version() >= QDataStream::Qt_3_1)
2109         s << (quint8) font.d->request.styleStrategy;
2110     s << (quint8) 0
2111       << (quint8) font.d->request.weight
2112       << get_font_bits(s.version(), font.d.data());
2113     if (s.version() >= QDataStream::Qt_4_3)
2114         s << (quint16)font.d->request.stretch;
2115     if (s.version() >= QDataStream::Qt_4_4)
2116         s << get_extended_font_bits(font.d.data());
2117     if (s.version() >= QDataStream::Qt_4_5) {
2118         s << font.d->letterSpacing.value();
2119         s << font.d->wordSpacing.value();
2120     }
2121     return s;
2122 }
2123
2124
2125 /*!
2126     \relates QFont
2127
2128     Reads the font \a font from the data stream \a s. (fromString()
2129     reads from a text stream.)
2130
2131     \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2132 */
2133 QDataStream &operator>>(QDataStream &s, QFont &font)
2134 {
2135     font.d = new QFontPrivate;
2136     font.resolve_mask = QFont::AllPropertiesResolved;
2137
2138     quint8 styleHint, styleStrategy = QFont::PreferDefault, charSet, weight, bits;
2139
2140     if (s.version() == 1) {
2141         QByteArray fam;
2142         s >> fam;
2143         font.d->request.family = QString::fromLatin1(fam);
2144     } else {
2145         s >> font.d->request.family;
2146     }
2147
2148     if (s.version() >= QDataStream::Qt_4_0) {
2149         // 4.0
2150         double pointSize;
2151         qint32 pixelSize;
2152         s >> pointSize;
2153         s >> pixelSize;
2154         font.d->request.pointSize = qreal(pointSize);
2155         font.d->request.pixelSize = pixelSize;
2156     } else {
2157         qint16 pointSize, pixelSize = -1;
2158         s >> pointSize;
2159         if (s.version() >= 4)
2160             s >> pixelSize;
2161         font.d->request.pointSize = qreal(pointSize / 10.);
2162         font.d->request.pixelSize = pixelSize;
2163     }
2164     s >> styleHint;
2165     if (s.version() >= QDataStream::Qt_3_1)
2166         s >> styleStrategy;
2167
2168     s >> charSet;
2169     s >> weight;
2170     s >> bits;
2171
2172     font.d->request.styleHint = styleHint;
2173     font.d->request.styleStrategy = styleStrategy;
2174     font.d->request.weight = weight;
2175
2176     set_font_bits(s.version(), bits, font.d.data());
2177
2178     if (s.version() >= QDataStream::Qt_4_3) {
2179         quint16 stretch;
2180         s >> stretch;
2181         font.d->request.stretch = stretch;
2182     }
2183
2184     if (s.version() >= QDataStream::Qt_4_4) {
2185         quint8 extendedBits;
2186         s >> extendedBits;
2187         set_extended_font_bits(extendedBits, font.d.data());
2188     }
2189     if (s.version() >= QDataStream::Qt_4_5) {
2190         int value;
2191         s >> value;
2192         font.d->letterSpacing.setValue(value);
2193         s >> value;
2194         font.d->wordSpacing.setValue(value);
2195     }
2196
2197     return s;
2198 }
2199
2200 #endif // QT_NO_DATASTREAM
2201
2202
2203 /*****************************************************************************
2204   QFontInfo member functions
2205  *****************************************************************************/
2206
2207 /*!
2208     \class QFontInfo
2209     \reentrant
2210
2211     \brief The QFontInfo class provides general information about fonts.
2212     \inmodule QtGui
2213
2214     \ingroup appearance
2215     \ingroup shared
2216
2217     The QFontInfo class provides the same access functions as QFont,
2218     e.g. family(), pointSize(), italic(), weight(), fixedPitch(),
2219     styleHint() etc. But whilst the QFont access functions return the
2220     values that were set, a QFontInfo object returns the values that
2221     apply to the font that will actually be used to draw the text.
2222
2223     For example, when the program asks for a 25pt Courier font on a
2224     machine that has a non-scalable 24pt Courier font, QFont will
2225     (normally) use the 24pt Courier for rendering. In this case,
2226     QFont::pointSize() returns 25 and QFontInfo::pointSize() returns
2227     24.
2228
2229     There are three ways to create a QFontInfo object.
2230     \list 1
2231     \li Calling the QFontInfo constructor with a QFont creates a font
2232     info object for a screen-compatible font, i.e. the font cannot be
2233     a printer font. If the font is changed later, the font
2234     info object is \e not updated.
2235
2236     (Note: If you use a printer font the values returned may be
2237     inaccurate. Printer fonts are not always accessible so the nearest
2238     screen font is used if a printer font is supplied.)
2239
2240     \li QWidget::fontInfo() returns the font info for a widget's font.
2241     This is equivalent to calling QFontInfo(widget->font()). If the
2242     widget's font is changed later, the font info object is \e not
2243     updated.
2244
2245     \li QPainter::fontInfo() returns the font info for a painter's
2246     current font. If the painter's font is changed later, the font
2247     info object is \e not updated.
2248     \endlist
2249
2250     \sa QFont, QFontMetrics, QFontDatabase
2251 */
2252
2253 /*!
2254     Constructs a font info object for \a font.
2255
2256     The font must be screen-compatible, i.e. a font you use when
2257     drawing text in \l{QWidget}{widgets} or \l{QPixmap}{pixmaps}, not QPicture or QPrinter.
2258
2259     The font info object holds the information for the font that is
2260     passed in the constructor at the time it is created, and is not
2261     updated if the font's attributes are changed later.
2262
2263     Use QPainter::fontInfo() to get the font info when painting.
2264     This will give correct results also when painting on paint device
2265     that is not screen-compatible.
2266 */
2267 QFontInfo::QFontInfo(const QFont &font)
2268     : d(font.d.data())
2269 {
2270 }
2271
2272 /*!
2273     Constructs a copy of \a fi.
2274 */
2275 QFontInfo::QFontInfo(const QFontInfo &fi)
2276     : d(fi.d.data())
2277 {
2278 }
2279
2280 /*!
2281     Destroys the font info object.
2282 */
2283 QFontInfo::~QFontInfo()
2284 {
2285 }
2286
2287 /*!
2288     Assigns the font info in \a fi.
2289 */
2290 QFontInfo &QFontInfo::operator=(const QFontInfo &fi)
2291 {
2292     d = fi.d.data();
2293     return *this;
2294 }
2295
2296 /*!
2297     Returns the family name of the matched window system font.
2298
2299     \sa QFont::family()
2300 */
2301 QString QFontInfo::family() const
2302 {
2303     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2304     Q_ASSERT(engine != 0);
2305     return engine->fontDef.family;
2306 }
2307
2308 /*!
2309     \since 4.8
2310
2311     Returns the style name of the matched window system font on
2312     system that supports it.
2313
2314     \sa QFont::styleName()
2315 */
2316 QString QFontInfo::styleName() const
2317 {
2318     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2319     Q_ASSERT(engine != 0);
2320     return engine->fontDef.styleName;
2321 }
2322
2323 /*!
2324     Returns the point size of the matched window system font.
2325
2326     \sa pointSizeF(), QFont::pointSize()
2327 */
2328 int QFontInfo::pointSize() const
2329 {
2330     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2331     Q_ASSERT(engine != 0);
2332     return qRound(engine->fontDef.pointSize);
2333 }
2334
2335 /*!
2336     Returns the point size of the matched window system font.
2337
2338     \sa QFont::pointSizeF()
2339 */
2340 qreal QFontInfo::pointSizeF() const
2341 {
2342     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2343     Q_ASSERT(engine != 0);
2344     return engine->fontDef.pointSize;
2345 }
2346
2347 /*!
2348     Returns the pixel size of the matched window system font.
2349
2350     \sa QFont::pointSize()
2351 */
2352 int QFontInfo::pixelSize() const
2353 {
2354     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2355     Q_ASSERT(engine != 0);
2356     return engine->fontDef.pixelSize;
2357 }
2358
2359 /*!
2360     Returns the italic value of the matched window system font.
2361
2362     \sa QFont::italic()
2363 */
2364 bool QFontInfo::italic() const
2365 {
2366     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2367     Q_ASSERT(engine != 0);
2368     return engine->fontDef.style != QFont::StyleNormal;
2369 }
2370
2371 /*!
2372     Returns the style value of the matched window system font.
2373
2374     \sa QFont::style()
2375 */
2376 QFont::Style QFontInfo::style() const
2377 {
2378     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2379     Q_ASSERT(engine != 0);
2380     return (QFont::Style)engine->fontDef.style;
2381 }
2382
2383 /*!
2384     Returns the weight of the matched window system font.
2385
2386     \sa QFont::weight(), bold()
2387 */
2388 int QFontInfo::weight() const
2389 {
2390     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2391     Q_ASSERT(engine != 0);
2392     return engine->fontDef.weight;
2393
2394 }
2395
2396 /*!
2397     \fn bool QFontInfo::bold() const
2398
2399     Returns true if weight() would return a value greater than
2400     QFont::Normal; otherwise returns false.
2401
2402     \sa weight(), QFont::bold()
2403 */
2404
2405 /*!
2406     Returns the underline value of the matched window system font.
2407
2408   \sa QFont::underline()
2409
2410   \internal
2411
2412   Here we read the underline flag directly from the QFont.
2413   This is OK for X11 and for Windows because we always get what we want.
2414 */
2415 bool QFontInfo::underline() const
2416 {
2417     return d->underline;
2418 }
2419
2420 /*!
2421     Returns the overline value of the matched window system font.
2422
2423     \sa QFont::overline()
2424
2425     \internal
2426
2427     Here we read the overline flag directly from the QFont.
2428     This is OK for X11 and for Windows because we always get what we want.
2429 */
2430 bool QFontInfo::overline() const
2431 {
2432     return d->overline;
2433 }
2434
2435 /*!
2436     Returns the strikeout value of the matched window system font.
2437
2438   \sa QFont::strikeOut()
2439
2440   \internal Here we read the strikeOut flag directly from the QFont.
2441   This is OK for X11 and for Windows because we always get what we want.
2442 */
2443 bool QFontInfo::strikeOut() const
2444 {
2445     return d->strikeOut;
2446 }
2447
2448 /*!
2449     Returns the fixed pitch value of the matched window system font.
2450
2451     \sa QFont::fixedPitch()
2452 */
2453 bool QFontInfo::fixedPitch() const
2454 {
2455     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2456     Q_ASSERT(engine != 0);
2457 #ifdef Q_OS_MAC
2458     if (!engine->fontDef.fixedPitchComputed) {
2459         QChar ch[2] = { QLatin1Char('i'), QLatin1Char('m') };
2460         QGlyphLayoutArray<2> g;
2461         int l = 2;
2462         engine->stringToCMap(ch, 2, &g, &l, 0);
2463         engine->fontDef.fixedPitch = g.advances_x[0] == g.advances_x[1];
2464         engine->fontDef.fixedPitchComputed = true;
2465     }
2466 #endif
2467     return engine->fontDef.fixedPitch;
2468 }
2469
2470 /*!
2471     Returns the style of the matched window system font.
2472
2473     Currently only returns the style hint set in QFont.
2474
2475     \sa QFont::styleHint(), QFont::StyleHint
2476 */
2477 QFont::StyleHint QFontInfo::styleHint() const
2478 {
2479     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2480     Q_ASSERT(engine != 0);
2481     return (QFont::StyleHint) engine->fontDef.styleHint;
2482 }
2483
2484 /*!
2485     Returns true if the font is a raw mode font; otherwise returns
2486     false.
2487
2488     If it is a raw mode font, all other functions in QFontInfo will
2489     return the same values set in the QFont, regardless of the font
2490     actually used.
2491
2492     \sa QFont::rawMode()
2493 */
2494 bool QFontInfo::rawMode() const
2495 {
2496     return d->rawMode;
2497 }
2498
2499 /*!
2500     Returns true if the matched window system font is exactly the same
2501     as the one specified by the font; otherwise returns false.
2502
2503     \sa QFont::exactMatch()
2504 */
2505 bool QFontInfo::exactMatch() const
2506 {
2507     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2508     Q_ASSERT(engine != 0);
2509     return (d->rawMode
2510             ? engine->type() != QFontEngine::Box
2511             : d->request.exactMatch(engine->fontDef));
2512 }
2513
2514
2515
2516
2517 // **********************************************************************
2518 // QFontCache
2519 // **********************************************************************
2520
2521 #ifdef QFONTCACHE_DEBUG
2522 // fast timeouts for debugging
2523 static const int fast_timeout =   1000;  // 1s
2524 static const int slow_timeout =   5000;  // 5s
2525 #else
2526 static const int fast_timeout =  10000; // 10s
2527 static const int slow_timeout = 300000; //  5m
2528 #endif // QFONTCACHE_DEBUG
2529
2530 const uint QFontCache::min_cost = 4*1024; // 4mb
2531
2532 #ifdef QT_NO_THREAD
2533 Q_GLOBAL_STATIC(QFontCache, theFontCache)
2534
2535 QFontCache *QFontCache::instance()
2536 {
2537     return theFontCache();
2538 }
2539
2540 void QFontCache::cleanup()
2541 {
2542 }
2543 #else
2544 Q_GLOBAL_STATIC(QThreadStorage<QFontCache *>, theFontCache)
2545
2546 QFontCache *QFontCache::instance()
2547 {
2548     QFontCache *&fontCache = theFontCache()->localData();
2549     if (!fontCache)
2550         fontCache = new QFontCache;
2551     return fontCache;
2552 }
2553
2554 void QFontCache::cleanup()
2555 {
2556     QThreadStorage<QFontCache *> *cache = 0;
2557     QT_TRY {
2558         cache = theFontCache();
2559     } QT_CATCH (const std::bad_alloc &) {
2560         // no cache - just ignore
2561     }
2562     if (cache && cache->hasLocalData())
2563         cache->setLocalData(0);
2564 }
2565 #endif // QT_NO_THREAD
2566
2567 QFontCache::QFontCache()
2568     : QObject(), total_cost(0), max_cost(min_cost),
2569       current_timestamp(0), fast(false), timer_id(-1)
2570 {
2571 }
2572
2573 QFontCache::~QFontCache()
2574 {
2575     clear();
2576     {
2577         EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
2578                                  end = engineDataCache.constEnd();
2579         while (it != end) {
2580             if (it.value()->ref.load() == 0)
2581                 delete it.value();
2582             else
2583                 FC_DEBUG("QFontCache::~QFontCache: engineData %p still has refcount %d",
2584                          it.value(), it.value()->ref.load());
2585             ++it;
2586         }
2587     }
2588     EngineCache::ConstIterator it = engineCache.constBegin(),
2589                          end = engineCache.constEnd();
2590     while (it != end) {
2591         if (--it.value().data->cache_count == 0) {
2592             if (it.value().data->ref.load() == 0) {
2593                 FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %g %d %d %d)",
2594                          it.value().data, it.key().script, it.key().def.pointSize,
2595                          it.key().def.pixelSize, it.key().def.weight, it.key().def.style,
2596                          it.key().def.fixedPitch);
2597
2598                 delete it.value().data;
2599             } else {
2600                 FC_DEBUG("QFontCache::~QFontCache: engine = %p still has refcount %d",
2601                          it.value().data, it.value().data->ref.load());
2602             }
2603         }
2604         ++it;
2605     }
2606 }
2607
2608 void QFontCache::clear()
2609 {
2610     {
2611         EngineDataCache::Iterator it = engineDataCache.begin(),
2612                                  end = engineDataCache.end();
2613         while (it != end) {
2614             QFontEngineData *data = it.value();
2615             for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
2616                 if (data->engines[i]) {
2617                     data->engines[i]->ref.deref();
2618                     data->engines[i] = 0;
2619                 }
2620             }
2621             ++it;
2622         }
2623     }
2624
2625     for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
2626          it != end; ++it) {
2627         if (it->data->ref.load() == 0) {
2628             delete it->data;
2629             it->data = 0;
2630         }
2631     }
2632
2633     for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
2634          it != end; ++it) {
2635         if (it->data && it->data->ref.load() == 0) {
2636             delete it->data;
2637             it->data = 0;
2638         }
2639     }
2640
2641     engineCache.clear();
2642 }
2643
2644
2645 QFontEngineData *QFontCache::findEngineData(const QFontDef &def) const
2646 {
2647     EngineDataCache::ConstIterator it = engineDataCache.find(def),
2648                                   end = engineDataCache.end();
2649     if (it == end) return 0;
2650
2651     // found
2652     return it.value();
2653 }
2654
2655 void QFontCache::insertEngineData(const QFontDef &def, QFontEngineData *engineData)
2656 {
2657     FC_DEBUG("QFontCache: inserting new engine data %p", engineData);
2658
2659     engineDataCache.insert(def, engineData);
2660     increaseCost(sizeof(QFontEngineData));
2661 }
2662
2663 QFontEngine *QFontCache::findEngine(const Key &key)
2664 {
2665     EngineCache::Iterator it = engineCache.find(key),
2666                          end = engineCache.end();
2667     if (it == end) return 0;
2668     // found... update the hitcount and timestamp
2669     updateHitCountAndTimeStamp(it.value());
2670
2671     return it.value().data;
2672 }
2673
2674 void QFontCache::updateHitCountAndTimeStamp(Engine &value)
2675 {
2676     value.hits++;
2677     value.timestamp = ++current_timestamp;
2678
2679     FC_DEBUG("QFontCache: found font engine\n"
2680              "  %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'",
2681              value.data, value.timestamp, value.hits,
2682              value.data->ref.load(), value.data->cache_count,
2683              value.data->name());
2684 }
2685
2686 void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti)
2687 {
2688     FC_DEBUG("QFontCache: inserting new engine %p", engine);
2689
2690     Engine data(engine);
2691     data.timestamp = ++current_timestamp;
2692
2693     if (insertMulti)
2694         engineCache.insertMulti(key, data);
2695     else
2696         engineCache.insert(key, data);
2697
2698     // only increase the cost if this is the first time we insert the engine
2699     if (engine->cache_count == 0)
2700         increaseCost(engine->cache_cost);
2701
2702     ++engine->cache_count;
2703 }
2704
2705 void QFontCache::increaseCost(uint cost)
2706 {
2707     cost = (cost + 512) / 1024; // store cost in kb
2708     cost = cost > 0 ? cost : 1;
2709     total_cost += cost;
2710
2711     FC_DEBUG("  COST: increased %u kb, total_cost %u kb, max_cost %u kb",
2712             cost, total_cost, max_cost);
2713
2714     if (total_cost > max_cost) {
2715         max_cost = total_cost;
2716
2717         if (timer_id == -1 || ! fast) {
2718             FC_DEBUG("  TIMER: starting fast timer (%d ms)", fast_timeout);
2719
2720             if (timer_id != -1) killTimer(timer_id);
2721             timer_id = startTimer(fast_timeout);
2722             fast = true;
2723         }
2724     }
2725 }
2726
2727 void QFontCache::decreaseCost(uint cost)
2728 {
2729     cost = (cost + 512) / 1024; // cost is stored in kb
2730     cost = cost > 0 ? cost : 1;
2731     Q_ASSERT(cost <= total_cost);
2732     total_cost -= cost;
2733
2734     FC_DEBUG("  COST: decreased %u kb, total_cost %u kb, max_cost %u kb",
2735             cost, total_cost, max_cost);
2736 }
2737
2738 void QFontCache::timerEvent(QTimerEvent *)
2739 {
2740     FC_DEBUG("QFontCache::timerEvent: performing cache maintenance (timestamp %u)",
2741               current_timestamp);
2742
2743     if (total_cost <= max_cost && max_cost <= min_cost) {
2744         FC_DEBUG("  cache redused sufficiently, stopping timer");
2745
2746         killTimer(timer_id);
2747         timer_id = -1;
2748         fast = false;
2749
2750         return;
2751     }
2752
2753     // go through the cache and count up everything in use
2754     uint in_use_cost = 0;
2755
2756     {
2757         FC_DEBUG("  SWEEP engine data:");
2758
2759         // make sure the cost of each engine data is at least 1kb
2760         const uint engine_data_cost =
2761             sizeof(QFontEngineData) > 1024 ? sizeof(QFontEngineData) : 1024;
2762
2763         EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
2764                                       end = engineDataCache.constEnd();
2765         for (; it != end; ++it) {
2766 #ifdef QFONTCACHE_DEBUG
2767             FC_DEBUG("    %p: ref %2d", it.value(), int(it.value()->ref));
2768
2769 #endif // QFONTCACHE_DEBUG
2770
2771             if (it.value()->ref.load() != 0)
2772                 in_use_cost += engine_data_cost;
2773         }
2774     }
2775
2776     {
2777         FC_DEBUG("  SWEEP engine:");
2778
2779         EngineCache::ConstIterator it = engineCache.constBegin(),
2780                                   end = engineCache.constEnd();
2781         for (; it != end; ++it) {
2782             FC_DEBUG("    %p: timestamp %4u hits %2u ref %2d/%2d, cost %u bytes",
2783                      it.value().data, it.value().timestamp, it.value().hits,
2784                      it.value().data->ref.load(), it.value().data->cache_count,
2785                      it.value().data->cache_cost);
2786
2787             if (it.value().data->ref.load() != 0)
2788                 in_use_cost += it.value().data->cache_cost / it.value().data->cache_count;
2789         }
2790
2791         // attempt to make up for rounding errors
2792         in_use_cost += engineCache.size();
2793     }
2794
2795     in_use_cost = (in_use_cost + 512) / 1024; // cost is stored in kb
2796
2797     /*
2798       calculate the new maximum cost for the cache
2799
2800       NOTE: in_use_cost is *not* correct due to rounding errors in the
2801       above algorithm.  instead of worrying about getting the
2802       calculation correct, we are more interested in speed, and use
2803       in_use_cost as a floor for new_max_cost
2804     */
2805     uint new_max_cost = qMax(qMax(max_cost / 2, in_use_cost), min_cost);
2806
2807     FC_DEBUG("  after sweep, in use %u kb, total %u kb, max %u kb, new max %u kb",
2808               in_use_cost, total_cost, max_cost, new_max_cost);
2809
2810     if (new_max_cost == max_cost) {
2811         if (fast) {
2812             FC_DEBUG("  cannot shrink cache, slowing timer");
2813
2814             killTimer(timer_id);
2815             timer_id = startTimer(slow_timeout);
2816             fast = false;
2817         }
2818
2819         return;
2820     } else if (! fast) {
2821         FC_DEBUG("  dropping into passing gear");
2822
2823         killTimer(timer_id);
2824         timer_id = startTimer(fast_timeout);
2825         fast = true;
2826     }
2827
2828     max_cost = new_max_cost;
2829
2830     {
2831         FC_DEBUG("  CLEAN engine data:");
2832
2833         // clean out all unused engine data
2834         EngineDataCache::Iterator it = engineDataCache.begin(),
2835                                  end = engineDataCache.end();
2836         while (it != end) {
2837             if (it.value()->ref.load() != 0) {
2838                 ++it;
2839                 continue;
2840             }
2841
2842             EngineDataCache::Iterator rem = it++;
2843
2844             decreaseCost(sizeof(QFontEngineData));
2845
2846             FC_DEBUG("    %p", rem.value());
2847
2848             delete rem.value();
2849             engineDataCache.erase(rem);
2850         }
2851     }
2852
2853     // clean out the engine cache just enough to get below our new max cost
2854     uint current_cost;
2855     do {
2856         current_cost = total_cost;
2857
2858         EngineCache::Iterator it = engineCache.begin(),
2859                              end = engineCache.end();
2860         // determine the oldest and least popular of the unused engines
2861         uint oldest = ~0u;
2862         uint least_popular = ~0u;
2863
2864         for (; it != end; ++it) {
2865             if (it.value().data->ref.load() != 0)
2866                 continue;
2867
2868             if (it.value().timestamp < oldest &&
2869                  it.value().hits <= least_popular) {
2870                 oldest = it.value().timestamp;
2871                 least_popular = it.value().hits;
2872             }
2873         }
2874
2875         FC_DEBUG("    oldest %u least popular %u", oldest, least_popular);
2876
2877         for (it = engineCache.begin(); it != end; ++it) {
2878             if (it.value().data->ref.load() == 0 &&
2879                  it.value().timestamp == oldest &&
2880                  it.value().hits == least_popular)
2881                 break;
2882         }
2883
2884         if (it != end) {
2885             FC_DEBUG("    %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'",
2886                      it.value().data, it.value().timestamp, it.value().hits,
2887                      it.value().data->ref.load(), it.value().data->cache_count,
2888                      it.value().data->name());
2889
2890             if (--it.value().data->cache_count == 0) {
2891                 FC_DEBUG("    DELETE: last occurrence in cache");
2892
2893                 decreaseCost(it.value().data->cache_cost);
2894                 delete it.value().data;
2895             } else {
2896                 /*
2897                   this particular font engine is in the cache multiple
2898                   times...  set current_cost to zero, so that we can
2899                   keep looping to get rid of all occurrences
2900                 */
2901                 current_cost = 0;
2902             }
2903
2904             engineCache.erase(it);
2905         }
2906     } while (current_cost != total_cost && total_cost > max_cost);
2907 }
2908
2909
2910 #ifndef QT_NO_DEBUG_STREAM
2911 QDebug operator<<(QDebug stream, const QFont &font)
2912 {
2913     return stream << "QFont(" << font.toString() << ')';
2914 }
2915 #endif
2916
2917 QT_END_NAMESPACE