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