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