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