Compile with clang when C++11 support is enabled
[profile/ivi/qtbase.git] / src / gui / text / qfont.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qfont.h"
43 #include "qdebug.h"
44 #include "qpaintdevice.h"
45 #include "qfontdatabase.h"
46 #include "qfontmetrics.h"
47 #include "qfontinfo.h"
48 #include "qpainter.h"
49 #include "qhash.h"
50 #include "qdatastream.h"
51 #include "qguiapplication.h"
52 #include "qstringlist.h"
53 #include "qscreen.h"
54
55 #include "qthread.h"
56 #include "qthreadstorage.h"
57
58 #include <private/qunicodetables_p.h>
59 #include "qfont_p.h"
60 #include <private/qfontengine_p.h>
61 #include <private/qpainter_p.h>
62 #include <private/qtextengine_p.h>
63 #include <limits.h>
64
65 #include <qpa/qplatformscreen.h>
66 #include <QtGui/private/qguiapplication_p.h>
67
68 #include <QtCore/QMutexLocker>
69 #include <QtCore/QMutex>
70
71 // #define QFONTCACHE_DEBUG
72 #ifdef QFONTCACHE_DEBUG
73 #  define FC_DEBUG qDebug
74 #else
75 #  define FC_DEBUG if (false) qDebug
76 #endif
77
78 QT_BEGIN_NAMESPACE
79
80
81
82 bool QFontDef::exactMatch(const QFontDef &other) const
83 {
84     /*
85       QFontDef comparison is more complicated than just simple
86       per-member comparisons.
87
88       When comparing point/pixel sizes, either point or pixelsize
89       could be -1.  in This case we have to compare the non negative
90       size value.
91
92       This test will fail if the point-sizes differ by 1/2 point or
93       more or they do not round to the same value.  We have to do this
94       since our API still uses 'int' point-sizes in the API, but store
95       deci-point-sizes internally.
96
97       To compare the family members, we need to parse the font names
98       and compare the family/foundry strings separately.  This allows
99       us to compare e.g. "Helvetica" and "Helvetica [Adobe]" with
100       positive results.
101     */
102     if (pixelSize != -1 && other.pixelSize != -1) {
103         if (pixelSize != other.pixelSize)
104             return false;
105     } else if (pointSize != -1 && other.pointSize != -1) {
106         if (pointSize != other.pointSize)
107             return false;
108     } else {
109         return false;
110     }
111
112     if (!ignorePitch && !other.ignorePitch && fixedPitch != other.fixedPitch)
113         return false;
114
115     if (stretch != 0 && other.stretch != 0 && stretch != other.stretch)
116         return false;
117
118     QString this_family, this_foundry, other_family, other_foundry;
119     QFontDatabase::parseFontName(family, this_foundry, this_family);
120     QFontDatabase::parseFontName(other.family, other_foundry, other_family);
121
122     this_family = QFontDatabase::resolveFontFamilyAlias(this_family);
123     other_family = QFontDatabase::resolveFontFamilyAlias(other_family);
124
125     return (styleHint     == other.styleHint
126             && styleStrategy == other.styleStrategy
127             && weight        == other.weight
128             && style        == other.style
129             && this_family   == other_family
130             && (styleName.isEmpty() || other.styleName.isEmpty() || styleName == other.styleName)
131             && (this_foundry.isEmpty()
132                 || other_foundry.isEmpty()
133                 || this_foundry == other_foundry)
134        );
135 }
136
137 extern bool qt_is_gui_used;
138
139 Q_GUI_EXPORT int qt_defaultDpiX()
140 {
141     if (qApp->testAttribute(Qt::AA_Use96Dpi))
142         return 96;
143
144     if (!qt_is_gui_used)
145         return 75;
146
147     if (const QScreen *screen = QGuiApplication::primaryScreen())
148         return qRound(screen->logicalDotsPerInchX());
149
150     //PI has not been initialised, or it is being initialised. Give a default dpi
151     return 100;
152 }
153
154 Q_GUI_EXPORT int qt_defaultDpiY()
155 {
156     if (qApp->testAttribute(Qt::AA_Use96Dpi))
157         return 96;
158
159     if (!qt_is_gui_used)
160         return 75;
161
162     if (const QScreen *screen = QGuiApplication::primaryScreen())
163         return qRound(screen->logicalDotsPerInchY());
164
165     //PI has not been initialised, or it is being initialised. Give a default dpi
166     return 100;
167 }
168
169 Q_GUI_EXPORT int qt_defaultDpi()
170 {
171     return qt_defaultDpiY();
172 }
173
174 QFontPrivate::QFontPrivate()
175     : engineData(0), dpi(qt_defaultDpi()), screen(0),
176       rawMode(false), underline(false), overline(false), strikeOut(false), kerning(true),
177       capital(0), letterSpacingIsAbsolute(false), scFont(0)
178 {
179 }
180
181 QFontPrivate::QFontPrivate(const QFontPrivate &other)
182     : request(other.request), engineData(0), dpi(other.dpi), screen(other.screen),
183       rawMode(other.rawMode), underline(other.underline), overline(other.overline),
184       strikeOut(other.strikeOut), kerning(other.kerning),
185       capital(other.capital), letterSpacingIsAbsolute(other.letterSpacingIsAbsolute),
186       letterSpacing(other.letterSpacing), wordSpacing(other.wordSpacing),
187       scFont(other.scFont)
188 {
189     if (scFont && scFont != this)
190         scFont->ref.ref();
191 }
192
193 QFontPrivate::~QFontPrivate()
194 {
195     if (engineData)
196         engineData->ref.deref();
197     engineData = 0;
198     if (scFont && scFont != this)
199         scFont->ref.deref();
200     scFont = 0;
201 }
202
203 extern QMutex *qt_fontdatabase_mutex();
204
205 #define QT_FONT_ENGINE_FROM_DATA(data, script) data->engines[script]
206
207 QFontEngine *QFontPrivate::engineForScript(int script) const
208 {
209     QMutexLocker locker(qt_fontdatabase_mutex());
210     if (script >= QUnicodeTables::Inherited)
211         script = QUnicodeTables::Common;
212     if (engineData && engineData->fontCache != QFontCache::instance()) {
213         // throw out engineData that came from a different thread
214         engineData->ref.deref();
215         engineData = 0;
216     }
217     if (!engineData || !QT_FONT_ENGINE_FROM_DATA(engineData, script))
218         QFontDatabase::load(this, script);
219     return QT_FONT_ENGINE_FROM_DATA(engineData, script);
220 }
221
222 void QFontPrivate::alterCharForCapitalization(QChar &c) const {
223     switch (capital) {
224     case QFont::AllUppercase:
225     case QFont::SmallCaps:
226         c = c.toUpper();
227         break;
228     case QFont::AllLowercase:
229         c = c.toLower();
230         break;
231     case QFont::MixedCase:
232         break;
233     }
234 }
235
236 QFontPrivate *QFontPrivate::smallCapsFontPrivate() const
237 {
238     if (scFont)
239         return scFont;
240     QFont font(const_cast<QFontPrivate *>(this));
241     qreal pointSize = font.pointSizeF();
242     if (pointSize > 0)
243         font.setPointSizeF(pointSize * .7);
244     else
245         font.setPixelSize((font.pixelSize() * 7 + 5) / 10);
246     scFont = font.d.data();
247     if (scFont != this)
248         scFont->ref.ref();
249     return scFont;
250 }
251
252
253 void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
254 {
255     Q_ASSERT(other != 0);
256
257     dpi = other->dpi;
258
259     if ((mask & QFont::AllPropertiesResolved) == QFont::AllPropertiesResolved) return;
260
261     // assign the unset-bits with the set-bits of the other font def
262     if (! (mask & QFont::FamilyResolved))
263         request.family = other->request.family;
264
265     if (! (mask & QFont::StyleNameResolved))
266         request.styleName = other->request.styleName;
267
268     if (! (mask & QFont::SizeResolved)) {
269         request.pointSize = other->request.pointSize;
270         request.pixelSize = other->request.pixelSize;
271     }
272
273     if (! (mask & QFont::StyleHintResolved))
274         request.styleHint = other->request.styleHint;
275
276     if (! (mask & QFont::StyleStrategyResolved))
277         request.styleStrategy = other->request.styleStrategy;
278
279     if (! (mask & QFont::WeightResolved))
280         request.weight = other->request.weight;
281
282     if (! (mask & QFont::StyleResolved))
283         request.style = other->request.style;
284
285     if (! (mask & QFont::FixedPitchResolved))
286         request.fixedPitch = other->request.fixedPitch;
287
288     if (! (mask & QFont::StretchResolved))
289         request.stretch = other->request.stretch;
290
291     if (! (mask & QFont::HintingPreferenceResolved))
292         request.hintingPreference = other->request.hintingPreference;
293
294     if (! (mask & QFont::UnderlineResolved))
295         underline = other->underline;
296
297     if (! (mask & QFont::OverlineResolved))
298         overline = other->overline;
299
300     if (! (mask & QFont::StrikeOutResolved))
301         strikeOut = other->strikeOut;
302
303     if (! (mask & QFont::KerningResolved))
304         kerning = other->kerning;
305
306     if (! (mask & QFont::LetterSpacingResolved)) {
307         letterSpacing = other->letterSpacing;
308         letterSpacingIsAbsolute = other->letterSpacingIsAbsolute;
309     }
310     if (! (mask & QFont::WordSpacingResolved))
311         wordSpacing = other->wordSpacing;
312     if (! (mask & QFont::CapitalizationResolved))
313         capital = other->capital;
314 }
315
316
317
318
319 QFontEngineData::QFontEngineData()
320     : ref(1), fontCache(QFontCache::instance())
321 {
322     memset(engines, 0, QUnicodeTables::ScriptCount * sizeof(QFontEngine *));
323 }
324
325 QFontEngineData::~QFontEngineData()
326 {
327     for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
328         if (engines[i])
329             engines[i]->ref.deref();
330         engines[i] = 0;
331     }
332 }
333
334
335
336
337 /*!
338     \class QFont
339     \reentrant
340
341     \brief The QFont class specifies a font used for drawing text.
342
343     \ingroup painting
344     \ingroup appearance
345     \ingroup shared
346     \ingroup richtext-processing
347
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 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     \l{#fontmatching}{font matching algorithm} by choosing a
386     particular \l{QFont::StyleHint} and \l{QFont::StyleStrategy} with
387     setStyleHint(). The default family (corresponding to the current
388     style hint) is returned by defaultFamily().
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 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 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 code/src_gui_text_qfont.cpp 3
481
482     To find out font metrics use a QFontMetrics object, e.g.
483
484     \snippet code/src_gui_text_qfont.cpp 4
485
486     For more general information on fonts, see the
487     \l{comp.fonts FAQ}{comp.fonts FAQ}.
488     Information on encodings can be found from
489     \l{Roman Czyborra's} page.
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 \l{bughowto.html}{report it as a bug} 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
1110    \l{Weight}{QFont::Normal}; 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
1119     \l{Weight}{QFont::Bold};
1120     otherwise sets the weight to \l{Weight}{QFont::Normal}.
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{Serializing Qt Data Types}{Format of the QDataStream operators}
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{Serializing Qt Data Types}{Format of the QDataStream operators}
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 \l{QWidget}{widgets} or \l{QPixmap}{pixmaps}, not QPicture or QPrinter.
2277
2278     The font info object holds the information for the font that is
2279     passed in the constructor at the time it is created, and is not
2280     updated if the font's attributes are changed later.
2281
2282     Use QPainter::fontInfo() to get the font info when painting.
2283     This will give correct results also when painting on paint device
2284     that is not screen-compatible.
2285 */
2286 QFontInfo::QFontInfo(const QFont &font)
2287     : d(font.d.data())
2288 {
2289 }
2290
2291 /*!
2292     Constructs a copy of \a fi.
2293 */
2294 QFontInfo::QFontInfo(const QFontInfo &fi)
2295     : d(fi.d.data())
2296 {
2297 }
2298
2299 /*!
2300     Destroys the font info object.
2301 */
2302 QFontInfo::~QFontInfo()
2303 {
2304 }
2305
2306 /*!
2307     Assigns the font info in \a fi.
2308 */
2309 QFontInfo &QFontInfo::operator=(const QFontInfo &fi)
2310 {
2311     d = fi.d.data();
2312     return *this;
2313 }
2314
2315 /*!
2316     Returns the family name of the matched window system font.
2317
2318     \sa QFont::family()
2319 */
2320 QString QFontInfo::family() const
2321 {
2322     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2323     Q_ASSERT(engine != 0);
2324     return engine->fontDef.family;
2325 }
2326
2327 /*!
2328     \since 4.8
2329
2330     Returns the style name of the matched window system font on
2331     system that supports it.
2332
2333     \sa QFont::styleName()
2334 */
2335 QString QFontInfo::styleName() const
2336 {
2337     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2338     Q_ASSERT(engine != 0);
2339     return engine->fontDef.styleName;
2340 }
2341
2342 /*!
2343     Returns the point size of the matched window system font.
2344
2345     \sa pointSizeF(), QFont::pointSize()
2346 */
2347 int QFontInfo::pointSize() const
2348 {
2349     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2350     Q_ASSERT(engine != 0);
2351     return qRound(engine->fontDef.pointSize);
2352 }
2353
2354 /*!
2355     Returns the point size of the matched window system font.
2356
2357     \sa QFont::pointSizeF()
2358 */
2359 qreal QFontInfo::pointSizeF() const
2360 {
2361     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2362     Q_ASSERT(engine != 0);
2363     return engine->fontDef.pointSize;
2364 }
2365
2366 /*!
2367     Returns the pixel size of the matched window system font.
2368
2369     \sa QFont::pointSize()
2370 */
2371 int QFontInfo::pixelSize() const
2372 {
2373     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2374     Q_ASSERT(engine != 0);
2375     return engine->fontDef.pixelSize;
2376 }
2377
2378 /*!
2379     Returns the italic value of the matched window system font.
2380
2381     \sa QFont::italic()
2382 */
2383 bool QFontInfo::italic() const
2384 {
2385     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2386     Q_ASSERT(engine != 0);
2387     return engine->fontDef.style != QFont::StyleNormal;
2388 }
2389
2390 /*!
2391     Returns the style value of the matched window system font.
2392
2393     \sa QFont::style()
2394 */
2395 QFont::Style QFontInfo::style() const
2396 {
2397     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2398     Q_ASSERT(engine != 0);
2399     return (QFont::Style)engine->fontDef.style;
2400 }
2401
2402 /*!
2403     Returns the weight of the matched window system font.
2404
2405     \sa QFont::weight(), bold()
2406 */
2407 int QFontInfo::weight() const
2408 {
2409     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2410     Q_ASSERT(engine != 0);
2411     return engine->fontDef.weight;
2412
2413 }
2414
2415 /*!
2416     \fn bool QFontInfo::bold() const
2417
2418     Returns true if weight() would return a value greater than
2419     QFont::Normal; otherwise returns false.
2420
2421     \sa weight(), QFont::bold()
2422 */
2423
2424 /*!
2425     Returns the underline value of the matched window system font.
2426
2427   \sa QFont::underline()
2428
2429   \internal
2430
2431   Here we read the underline flag directly from the QFont.
2432   This is OK for X11 and for Windows because we always get what we want.
2433 */
2434 bool QFontInfo::underline() const
2435 {
2436     return d->underline;
2437 }
2438
2439 /*!
2440     Returns the overline value of the matched window system font.
2441
2442     \sa QFont::overline()
2443
2444     \internal
2445
2446     Here we read the overline flag directly from the QFont.
2447     This is OK for X11 and for Windows because we always get what we want.
2448 */
2449 bool QFontInfo::overline() const
2450 {
2451     return d->overline;
2452 }
2453
2454 /*!
2455     Returns the strikeout value of the matched window system font.
2456
2457   \sa QFont::strikeOut()
2458
2459   \internal Here we read the strikeOut flag directly from the QFont.
2460   This is OK for X11 and for Windows because we always get what we want.
2461 */
2462 bool QFontInfo::strikeOut() const
2463 {
2464     return d->strikeOut;
2465 }
2466
2467 /*!
2468     Returns the fixed pitch value of the matched window system font.
2469
2470     \sa QFont::fixedPitch()
2471 */
2472 bool QFontInfo::fixedPitch() const
2473 {
2474     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2475     Q_ASSERT(engine != 0);
2476 #ifdef Q_OS_MAC
2477     if (!engine->fontDef.fixedPitchComputed) {
2478         QChar ch[2] = { QLatin1Char('i'), QLatin1Char('m') };
2479         QGlyphLayoutArray<2> g;
2480         int l = 2;
2481         engine->stringToCMap(ch, 2, &g, &l, 0);
2482         engine->fontDef.fixedPitch = g.advances_x[0] == g.advances_x[1];
2483         engine->fontDef.fixedPitchComputed = true;
2484     }
2485 #endif
2486     return engine->fontDef.fixedPitch;
2487 }
2488
2489 /*!
2490     Returns the style of the matched window system font.
2491
2492     Currently only returns the style hint set in QFont.
2493
2494     \sa QFont::styleHint(), QFont::StyleHint
2495 */
2496 QFont::StyleHint QFontInfo::styleHint() const
2497 {
2498     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2499     Q_ASSERT(engine != 0);
2500     return (QFont::StyleHint) engine->fontDef.styleHint;
2501 }
2502
2503 /*!
2504     Returns true if the font is a raw mode font; otherwise returns
2505     false.
2506
2507     If it is a raw mode font, all other functions in QFontInfo will
2508     return the same values set in the QFont, regardless of the font
2509     actually used.
2510
2511     \sa QFont::rawMode()
2512 */
2513 bool QFontInfo::rawMode() const
2514 {
2515     return d->rawMode;
2516 }
2517
2518 /*!
2519     Returns true if the matched window system font is exactly the same
2520     as the one specified by the font; otherwise returns false.
2521
2522     \sa QFont::exactMatch()
2523 */
2524 bool QFontInfo::exactMatch() const
2525 {
2526     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
2527     Q_ASSERT(engine != 0);
2528     return (d->rawMode
2529             ? engine->type() != QFontEngine::Box
2530             : d->request.exactMatch(engine->fontDef));
2531 }
2532
2533
2534
2535
2536 // **********************************************************************
2537 // QFontCache
2538 // **********************************************************************
2539
2540 #ifdef QFONTCACHE_DEBUG
2541 // fast timeouts for debugging
2542 static const int fast_timeout =   1000;  // 1s
2543 static const int slow_timeout =   5000;  // 5s
2544 #else
2545 static const int fast_timeout =  10000; // 10s
2546 static const int slow_timeout = 300000; //  5m
2547 #endif // QFONTCACHE_DEBUG
2548
2549 const uint QFontCache::min_cost = 4*1024; // 4mb
2550
2551 #ifdef QT_NO_THREAD
2552 Q_GLOBAL_STATIC(QFontCache, theFontCache)
2553
2554 QFontCache *QFontCache::instance()
2555 {
2556     return theFontCache();
2557 }
2558
2559 void QFontCache::cleanup()
2560 {
2561 }
2562 #else
2563 Q_GLOBAL_STATIC(QThreadStorage<QFontCache *>, theFontCache)
2564
2565 QFontCache *QFontCache::instance()
2566 {
2567     QFontCache *&fontCache = theFontCache()->localData();
2568     if (!fontCache)
2569         fontCache = new QFontCache;
2570     return fontCache;
2571 }
2572
2573 void QFontCache::cleanup()
2574 {
2575     QThreadStorage<QFontCache *> *cache = 0;
2576     QT_TRY {
2577         cache = theFontCache();
2578     } QT_CATCH (const std::bad_alloc &) {
2579         // no cache - just ignore
2580     }
2581     if (cache && cache->hasLocalData())
2582         cache->setLocalData(0);
2583 }
2584 #endif // QT_NO_THREAD
2585
2586 QFontCache::QFontCache()
2587     : QObject(), total_cost(0), max_cost(min_cost),
2588       current_timestamp(0), fast(false), timer_id(-1)
2589 {
2590 }
2591
2592 QFontCache::~QFontCache()
2593 {
2594     clear();
2595     {
2596         EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
2597                                  end = engineDataCache.constEnd();
2598         while (it != end) {
2599             if (it.value()->ref.load() == 0)
2600                 delete it.value();
2601             else
2602                 FC_DEBUG("QFontCache::~QFontCache: engineData %p still has refcount %d",
2603                          it.value(), it.value()->ref.load());
2604             ++it;
2605         }
2606     }
2607     EngineCache::ConstIterator it = engineCache.constBegin(),
2608                          end = engineCache.constEnd();
2609     while (it != end) {
2610         if (--it.value().data->cache_count == 0) {
2611             if (it.value().data->ref.load() == 0) {
2612                 FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %g %d %d %d)",
2613                          it.value().data, it.key().script, it.key().def.pointSize,
2614                          it.key().def.pixelSize, it.key().def.weight, it.key().def.style,
2615                          it.key().def.fixedPitch);
2616
2617                 delete it.value().data;
2618             } else {
2619                 FC_DEBUG("QFontCache::~QFontCache: engine = %p still has refcount %d",
2620                          it.value().data, it.value().data->ref.load());
2621             }
2622         }
2623         ++it;
2624     }
2625 }
2626
2627 void QFontCache::clear()
2628 {
2629     {
2630         EngineDataCache::Iterator it = engineDataCache.begin(),
2631                                  end = engineDataCache.end();
2632         while (it != end) {
2633             QFontEngineData *data = it.value();
2634             for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
2635                 if (data->engines[i]) {
2636                     data->engines[i]->ref.deref();
2637                     data->engines[i] = 0;
2638                 }
2639             }
2640             ++it;
2641         }
2642     }
2643
2644     for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
2645          it != end; ++it) {
2646         if (it->data->ref.load() == 0) {
2647             delete it->data;
2648             it->data = 0;
2649         }
2650     }
2651
2652     for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
2653          it != end; ++it) {
2654         if (it->data && it->data->ref.load() == 0) {
2655             delete it->data;
2656             it->data = 0;
2657         }
2658     }
2659
2660     engineCache.clear();
2661 }
2662
2663
2664 QFontEngineData *QFontCache::findEngineData(const QFontDef &def) const
2665 {
2666     EngineDataCache::ConstIterator it = engineDataCache.find(def),
2667                                   end = engineDataCache.end();
2668     if (it == end) return 0;
2669
2670     // found
2671     return it.value();
2672 }
2673
2674 void QFontCache::insertEngineData(const QFontDef &def, QFontEngineData *engineData)
2675 {
2676     FC_DEBUG("QFontCache: inserting new engine data %p", engineData);
2677
2678     engineDataCache.insert(def, engineData);
2679     increaseCost(sizeof(QFontEngineData));
2680 }
2681
2682 QFontEngine *QFontCache::findEngine(const Key &key)
2683 {
2684     EngineCache::Iterator it = engineCache.find(key),
2685                          end = engineCache.end();
2686     if (it == end) return 0;
2687     // found... update the hitcount and timestamp
2688     updateHitCountAndTimeStamp(it.value());
2689
2690     return it.value().data;
2691 }
2692
2693 void QFontCache::updateHitCountAndTimeStamp(Engine &value)
2694 {
2695     value.hits++;
2696     value.timestamp = ++current_timestamp;
2697
2698     FC_DEBUG("QFontCache: found font engine\n"
2699              "  %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'",
2700              value.data, value.timestamp, value.hits,
2701              value.data->ref.load(), value.data->cache_count,
2702              value.data->name());
2703 }
2704
2705 void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti)
2706 {
2707     FC_DEBUG("QFontCache: inserting new engine %p", engine);
2708
2709     Engine data(engine);
2710     data.timestamp = ++current_timestamp;
2711
2712     if (insertMulti)
2713         engineCache.insertMulti(key, data);
2714     else
2715         engineCache.insert(key, data);
2716
2717     // only increase the cost if this is the first time we insert the engine
2718     if (engine->cache_count == 0)
2719         increaseCost(engine->cache_cost);
2720
2721     ++engine->cache_count;
2722 }
2723
2724 void QFontCache::increaseCost(uint cost)
2725 {
2726     cost = (cost + 512) / 1024; // store cost in kb
2727     cost = cost > 0 ? cost : 1;
2728     total_cost += cost;
2729
2730     FC_DEBUG("  COST: increased %u kb, total_cost %u kb, max_cost %u kb",
2731             cost, total_cost, max_cost);
2732
2733     if (total_cost > max_cost) {
2734         max_cost = total_cost;
2735
2736         if (timer_id == -1 || ! fast) {
2737             FC_DEBUG("  TIMER: starting fast timer (%d ms)", fast_timeout);
2738
2739             if (timer_id != -1) killTimer(timer_id);
2740             timer_id = startTimer(fast_timeout);
2741             fast = true;
2742         }
2743     }
2744 }
2745
2746 void QFontCache::decreaseCost(uint cost)
2747 {
2748     cost = (cost + 512) / 1024; // cost is stored in kb
2749     cost = cost > 0 ? cost : 1;
2750     Q_ASSERT(cost <= total_cost);
2751     total_cost -= cost;
2752
2753     FC_DEBUG("  COST: decreased %u kb, total_cost %u kb, max_cost %u kb",
2754             cost, total_cost, max_cost);
2755 }
2756
2757 void QFontCache::timerEvent(QTimerEvent *)
2758 {
2759     FC_DEBUG("QFontCache::timerEvent: performing cache maintenance (timestamp %u)",
2760               current_timestamp);
2761
2762     if (total_cost <= max_cost && max_cost <= min_cost) {
2763         FC_DEBUG("  cache redused sufficiently, stopping timer");
2764
2765         killTimer(timer_id);
2766         timer_id = -1;
2767         fast = false;
2768
2769         return;
2770     }
2771
2772     // go through the cache and count up everything in use
2773     uint in_use_cost = 0;
2774
2775     {
2776         FC_DEBUG("  SWEEP engine data:");
2777
2778         // make sure the cost of each engine data is at least 1kb
2779         const uint engine_data_cost =
2780             sizeof(QFontEngineData) > 1024 ? sizeof(QFontEngineData) : 1024;
2781
2782         EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
2783                                       end = engineDataCache.constEnd();
2784         for (; it != end; ++it) {
2785 #ifdef QFONTCACHE_DEBUG
2786             FC_DEBUG("    %p: ref %2d", it.value(), int(it.value()->ref));
2787
2788 #endif // QFONTCACHE_DEBUG
2789
2790             if (it.value()->ref.load() != 0)
2791                 in_use_cost += engine_data_cost;
2792         }
2793     }
2794
2795     {
2796         FC_DEBUG("  SWEEP engine:");
2797
2798         EngineCache::ConstIterator it = engineCache.constBegin(),
2799                                   end = engineCache.constEnd();
2800         for (; it != end; ++it) {
2801             FC_DEBUG("    %p: timestamp %4u hits %2u ref %2d/%2d, cost %u bytes",
2802                      it.value().data, it.value().timestamp, it.value().hits,
2803                      it.value().data->ref.load(), it.value().data->cache_count,
2804                      it.value().data->cache_cost);
2805
2806             if (it.value().data->ref.load() != 0)
2807                 in_use_cost += it.value().data->cache_cost / it.value().data->cache_count;
2808         }
2809
2810         // attempt to make up for rounding errors
2811         in_use_cost += engineCache.size();
2812     }
2813
2814     in_use_cost = (in_use_cost + 512) / 1024; // cost is stored in kb
2815
2816     /*
2817       calculate the new maximum cost for the cache
2818
2819       NOTE: in_use_cost is *not* correct due to rounding errors in the
2820       above algorithm.  instead of worrying about getting the
2821       calculation correct, we are more interested in speed, and use
2822       in_use_cost as a floor for new_max_cost
2823     */
2824     uint new_max_cost = qMax(qMax(max_cost / 2, in_use_cost), min_cost);
2825
2826     FC_DEBUG("  after sweep, in use %u kb, total %u kb, max %u kb, new max %u kb",
2827               in_use_cost, total_cost, max_cost, new_max_cost);
2828
2829     if (new_max_cost == max_cost) {
2830         if (fast) {
2831             FC_DEBUG("  cannot shrink cache, slowing timer");
2832
2833             killTimer(timer_id);
2834             timer_id = startTimer(slow_timeout);
2835             fast = false;
2836         }
2837
2838         return;
2839     } else if (! fast) {
2840         FC_DEBUG("  dropping into passing gear");
2841
2842         killTimer(timer_id);
2843         timer_id = startTimer(fast_timeout);
2844         fast = true;
2845     }
2846
2847     max_cost = new_max_cost;
2848
2849     {
2850         FC_DEBUG("  CLEAN engine data:");
2851
2852         // clean out all unused engine data
2853         EngineDataCache::Iterator it = engineDataCache.begin(),
2854                                  end = engineDataCache.end();
2855         while (it != end) {
2856             if (it.value()->ref.load() != 0) {
2857                 ++it;
2858                 continue;
2859             }
2860
2861             EngineDataCache::Iterator rem = it++;
2862
2863             decreaseCost(sizeof(QFontEngineData));
2864
2865             FC_DEBUG("    %p", rem.value());
2866
2867             delete rem.value();
2868             engineDataCache.erase(rem);
2869         }
2870     }
2871
2872     // clean out the engine cache just enough to get below our new max cost
2873     uint current_cost;
2874     do {
2875         current_cost = total_cost;
2876
2877         EngineCache::Iterator it = engineCache.begin(),
2878                              end = engineCache.end();
2879         // determine the oldest and least popular of the unused engines
2880         uint oldest = ~0u;
2881         uint least_popular = ~0u;
2882
2883         for (; it != end; ++it) {
2884             if (it.value().data->ref.load() != 0)
2885                 continue;
2886
2887             if (it.value().timestamp < oldest &&
2888                  it.value().hits <= least_popular) {
2889                 oldest = it.value().timestamp;
2890                 least_popular = it.value().hits;
2891             }
2892         }
2893
2894         FC_DEBUG("    oldest %u least popular %u", oldest, least_popular);
2895
2896         for (it = engineCache.begin(); it != end; ++it) {
2897             if (it.value().data->ref.load() == 0 &&
2898                  it.value().timestamp == oldest &&
2899                  it.value().hits == least_popular)
2900                 break;
2901         }
2902
2903         if (it != end) {
2904             FC_DEBUG("    %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'",
2905                      it.value().data, it.value().timestamp, it.value().hits,
2906                      it.value().data->ref.load(), it.value().data->cache_count,
2907                      it.value().data->name());
2908
2909             if (--it.value().data->cache_count == 0) {
2910                 FC_DEBUG("    DELETE: last occurrence in cache");
2911
2912                 decreaseCost(it.value().data->cache_cost);
2913                 delete it.value().data;
2914             } else {
2915                 /*
2916                   this particular font engine is in the cache multiple
2917                   times...  set current_cost to zero, so that we can
2918                   keep looping to get rid of all occurrences
2919                 */
2920                 current_cost = 0;
2921             }
2922
2923             engineCache.erase(it);
2924         }
2925     } while (current_cost != total_cost && total_cost > max_cost);
2926 }
2927
2928
2929 #ifndef QT_NO_DEBUG_STREAM
2930 QDebug operator<<(QDebug stream, const QFont &font)
2931 {
2932     return stream << "QFont(" << font.toString() << ')';
2933 }
2934 #endif
2935
2936 QT_END_NAMESPACE