[2] | 1 | /****************************************************************************
|
---|
| 2 | ** $Id: qfont.cpp 80 2006-04-06 19:32:24Z dmik $
|
---|
| 3 | **
|
---|
| 4 | ** Implementation of QFont, QFontMetrics and QFontInfo classes
|
---|
| 5 | **
|
---|
| 6 | ** Created : 941207
|
---|
| 7 | **
|
---|
| 8 | ** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
|
---|
| 9 | **
|
---|
| 10 | ** This file is part of the kernel module of the Qt GUI Toolkit.
|
---|
| 11 | **
|
---|
| 12 | ** This file may be distributed under the terms of the Q Public License
|
---|
| 13 | ** as defined by Trolltech AS of Norway and appearing in the file
|
---|
| 14 | ** LICENSE.QPL included in the packaging of this file.
|
---|
| 15 | **
|
---|
| 16 | ** This file may be distributed and/or modified under the terms of the
|
---|
| 17 | ** GNU General Public License version 2 as published by the Free Software
|
---|
| 18 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
| 19 | ** packaging of this file.
|
---|
| 20 | **
|
---|
| 21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
|
---|
| 22 | ** licenses may use this file in accordance with the Qt Commercial License
|
---|
| 23 | ** Agreement provided with the Software.
|
---|
| 24 | **
|
---|
| 25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
---|
| 26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
---|
| 27 | **
|
---|
| 28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
|
---|
| 29 | ** information about Qt Commercial License Agreements.
|
---|
| 30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information.
|
---|
| 31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information.
|
---|
| 32 | **
|
---|
| 33 | ** Contact info@trolltech.com if any conditions of this licensing are
|
---|
| 34 | ** not clear to you.
|
---|
| 35 | **
|
---|
| 36 | **********************************************************************/
|
---|
| 37 |
|
---|
| 38 | #define QT_FATAL_ASSERT
|
---|
| 39 |
|
---|
| 40 | #include "qfont.h"
|
---|
| 41 | #include "qfontdatabase.h"
|
---|
| 42 | #include "qfontmetrics.h"
|
---|
| 43 | #include "qfontinfo.h"
|
---|
| 44 | #include "qpainter.h"
|
---|
| 45 | #include "qdict.h"
|
---|
| 46 | #include "qcache.h"
|
---|
| 47 | #include "qdatastream.h"
|
---|
| 48 | #include "qapplication.h"
|
---|
| 49 | #include "qcleanuphandler.h"
|
---|
| 50 | #include "qstringlist.h"
|
---|
| 51 | #ifdef Q_WS_MAC
|
---|
| 52 | #include "qpaintdevicemetrics.h"
|
---|
| 53 | #endif
|
---|
| 54 |
|
---|
| 55 | #include <private/qunicodetables_p.h>
|
---|
| 56 | #include "qfontdata_p.h"
|
---|
| 57 | #include "qfontengine_p.h"
|
---|
| 58 | #include "qpainter_p.h"
|
---|
| 59 | #include "qtextengine_p.h"
|
---|
| 60 |
|
---|
| 61 | // #define QFONTCACHE_DEBUG
|
---|
| 62 | #ifdef QFONTCACHE_DEBUG
|
---|
| 63 | # define FC_DEBUG qDebug
|
---|
| 64 | #else
|
---|
| 65 | # define FC_DEBUG if (FALSE) qDebug
|
---|
| 66 | #endif
|
---|
| 67 |
|
---|
| 68 |
|
---|
| 69 |
|
---|
| 70 |
|
---|
| 71 | bool QFontDef::operator==( const QFontDef &other ) const
|
---|
| 72 | {
|
---|
| 73 | /*
|
---|
| 74 | QFontDef comparison is more complicated than just simple
|
---|
| 75 | per-member comparisons.
|
---|
| 76 |
|
---|
| 77 | When comparing point/pixel sizes, either point or pixelsize
|
---|
| 78 | could be -1. in This case we have to compare the non negative
|
---|
| 79 | size value.
|
---|
| 80 |
|
---|
| 81 | This test will fail if the point-sizes differ by 1/2 point or
|
---|
| 82 | more or they do not round to the same value. We have to do this
|
---|
| 83 | since our API still uses 'int' point-sizes in the API, but store
|
---|
| 84 | deci-point-sizes internally.
|
---|
| 85 |
|
---|
| 86 | To compare the family members, we need to parse the font names
|
---|
| 87 | and compare the family/foundry strings separately. This allows
|
---|
| 88 | us to compare e.g. "Helvetica" and "Helvetica [Adobe]" with
|
---|
| 89 | positive results.
|
---|
| 90 | */
|
---|
| 91 | if (pixelSize != -1 && other.pixelSize != -1) {
|
---|
| 92 | if (pixelSize != other.pixelSize)
|
---|
| 93 | return FALSE;
|
---|
| 94 | } else if (pointSize != -1 && other.pointSize != -1) {
|
---|
| 95 | if (pointSize != other.pointSize
|
---|
| 96 | && (QABS(pointSize - other.pointSize) >= 5
|
---|
| 97 | || qRound(pointSize/10.) != qRound(other.pointSize/10.)))
|
---|
| 98 | return FALSE;
|
---|
| 99 | } else {
|
---|
| 100 | return FALSE;
|
---|
| 101 | }
|
---|
| 102 |
|
---|
| 103 | if (!ignorePitch && !other.ignorePitch && fixedPitch != other.fixedPitch)
|
---|
| 104 | return FALSE;
|
---|
| 105 |
|
---|
| 106 | if (stretch != 0 && other.stretch != 0 && stretch != other.stretch)
|
---|
| 107 | return FALSE;
|
---|
| 108 |
|
---|
| 109 | QString this_family, this_foundry, other_family, other_foundry;
|
---|
| 110 | QFontDatabase::parseFontName(family, this_foundry, this_family);
|
---|
| 111 | QFontDatabase::parseFontName(other.family, other_foundry, other_family);
|
---|
| 112 |
|
---|
| 113 | return ( styleHint == other.styleHint
|
---|
| 114 | && styleStrategy == other.styleStrategy
|
---|
| 115 | && weight == other.weight
|
---|
| 116 | && italic == other.italic
|
---|
| 117 | && this_family == other_family
|
---|
| 118 | && (this_foundry.isEmpty()
|
---|
| 119 | || other_foundry.isEmpty()
|
---|
| 120 | || this_foundry == other_foundry)
|
---|
| 121 | #ifdef Q_WS_X11
|
---|
| 122 | && addStyle == other.addStyle
|
---|
| 123 | #endif // Q_WS_X11
|
---|
| 124 | );
|
---|
| 125 | }
|
---|
| 126 |
|
---|
| 127 |
|
---|
| 128 |
|
---|
| 129 |
|
---|
| 130 | QFontPrivate::QFontPrivate()
|
---|
| 131 | : engineData( 0 ), paintdevice( 0 ),
|
---|
| 132 | rawMode( FALSE ), underline( FALSE ), overline( FALSE ), strikeOut( FALSE ),
|
---|
| 133 | mask( 0 )
|
---|
| 134 | {
|
---|
| 135 | #ifdef Q_WS_X11
|
---|
| 136 | screen = QPaintDevice::x11AppScreen();
|
---|
| 137 | #else
|
---|
| 138 | screen = 0;
|
---|
| 139 | #endif // Q_WS_X11
|
---|
| 140 | }
|
---|
| 141 |
|
---|
| 142 | QFontPrivate::QFontPrivate( const QFontPrivate &other )
|
---|
| 143 | : QShared(), request( other.request ), engineData( 0 ),
|
---|
| 144 | paintdevice( other.paintdevice ), screen( other.screen ),
|
---|
| 145 | rawMode( other.rawMode ), underline( other.underline ), overline( other.overline ),
|
---|
| 146 | strikeOut( other.strikeOut ), mask( other.mask )
|
---|
| 147 | {
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | QFontPrivate::~QFontPrivate()
|
---|
| 151 | {
|
---|
| 152 | if ( engineData )
|
---|
| 153 | engineData->deref();
|
---|
| 154 | engineData = 0;
|
---|
| 155 | }
|
---|
| 156 |
|
---|
| 157 | void QFontPrivate::resolve( const QFontPrivate *other )
|
---|
| 158 | {
|
---|
| 159 | #ifdef QT_CHECK_STATE
|
---|
| 160 | Q_ASSERT( other != 0 );
|
---|
| 161 | #endif
|
---|
| 162 |
|
---|
| 163 | if ( ( mask & Complete ) == Complete ) return;
|
---|
| 164 |
|
---|
| 165 | // assign the unset-bits with the set-bits of the other font def
|
---|
| 166 | if ( ! ( mask & Family ) )
|
---|
| 167 | request.family = other->request.family;
|
---|
| 168 |
|
---|
| 169 | if ( ! ( mask & Size ) ) {
|
---|
| 170 | request.pointSize = other->request.pointSize;
|
---|
| 171 | request.pixelSize = other->request.pixelSize;
|
---|
| 172 | }
|
---|
| 173 |
|
---|
| 174 | if ( ! ( mask & StyleHint ) )
|
---|
| 175 | request.styleHint = other->request.styleHint;
|
---|
| 176 |
|
---|
| 177 | if ( ! ( mask & StyleStrategy ) )
|
---|
| 178 | request.styleStrategy = other->request.styleStrategy;
|
---|
| 179 |
|
---|
| 180 | if ( ! ( mask & Weight ) )
|
---|
| 181 | request.weight = other->request.weight;
|
---|
| 182 |
|
---|
| 183 | if ( ! ( mask & Italic ) )
|
---|
| 184 | request.italic = other->request.italic;
|
---|
| 185 |
|
---|
| 186 | if ( ! ( mask & FixedPitch ) )
|
---|
| 187 | request.fixedPitch = other->request.fixedPitch;
|
---|
| 188 |
|
---|
| 189 | if ( ! ( mask & Stretch ) )
|
---|
| 190 | request.stretch = other->request.stretch;
|
---|
| 191 |
|
---|
| 192 | if ( ! ( mask & Underline ) )
|
---|
| 193 | underline = other->underline;
|
---|
| 194 |
|
---|
| 195 | if ( ! ( mask & Overline ) )
|
---|
| 196 | overline = other->overline;
|
---|
| 197 |
|
---|
| 198 | if ( ! ( mask & StrikeOut ) )
|
---|
| 199 | strikeOut = other->strikeOut;
|
---|
| 200 | }
|
---|
| 201 |
|
---|
| 202 |
|
---|
| 203 |
|
---|
| 204 |
|
---|
| 205 | QFontEngineData::QFontEngineData()
|
---|
| 206 | : lineWidth( 1 )
|
---|
| 207 | {
|
---|
| 208 | #if defined(Q_WS_X11) || defined(Q_WS_WIN)
|
---|
| 209 | memset( engines, 0, QFont::LastPrivateScript * sizeof( QFontEngine * ) );
|
---|
| 210 | #else
|
---|
| 211 | engine = 0;
|
---|
| 212 | #endif // Q_WS_X11 || Q_WS_WIN
|
---|
| 213 | #ifndef Q_WS_MAC
|
---|
| 214 | memset( widthCache, 0, widthCacheSize*sizeof( uchar ) );
|
---|
| 215 | #endif
|
---|
| 216 | }
|
---|
| 217 |
|
---|
| 218 | QFontEngineData::~QFontEngineData()
|
---|
| 219 | {
|
---|
| 220 | #if defined(Q_WS_X11) || defined(Q_WS_WIN)
|
---|
| 221 | for ( int i = 0; i < QFont::LastPrivateScript; i++ ) {
|
---|
| 222 | if ( engines[i] )
|
---|
| 223 | engines[i]->deref();
|
---|
| 224 | engines[i] = 0;
|
---|
| 225 | }
|
---|
| 226 | #else
|
---|
| 227 | if ( engine )
|
---|
| 228 | engine->deref();
|
---|
| 229 | engine = 0;
|
---|
| 230 | #endif // Q_WS_X11 || Q_WS_WIN
|
---|
| 231 | }
|
---|
| 232 |
|
---|
| 233 |
|
---|
| 234 |
|
---|
| 235 |
|
---|
| 236 | /*!
|
---|
| 237 | \class QFont qfont.h
|
---|
| 238 | \brief The QFont class specifies a font used for drawing text.
|
---|
| 239 |
|
---|
| 240 | \ingroup graphics
|
---|
| 241 | \ingroup appearance
|
---|
| 242 | \ingroup shared
|
---|
| 243 | \mainclass
|
---|
| 244 |
|
---|
| 245 | When you create a QFont object you specify various attributes that
|
---|
| 246 | you want the font to have. Qt will use the font with the specified
|
---|
| 247 | attributes, or if no matching font exists, Qt will use the closest
|
---|
| 248 | matching installed font. The attributes of the font that is
|
---|
| 249 | actually used are retrievable from a QFontInfo object. If the
|
---|
| 250 | window system provides an exact match exactMatch() returns TRUE.
|
---|
| 251 | Use QFontMetrics to get measurements, e.g. the pixel length of a
|
---|
| 252 | string using QFontMetrics::width().
|
---|
| 253 |
|
---|
| 254 | Use QApplication::setFont() to set the application's default font.
|
---|
| 255 |
|
---|
| 256 | If a choosen X11 font does not include all the characters that
|
---|
| 257 | need to be displayed, QFont will try to find the characters in the
|
---|
| 258 | nearest equivalent fonts. When a QPainter draws a character from a
|
---|
| 259 | font the QFont will report whether or not it has the character; if
|
---|
| 260 | it does not, QPainter will draw an unfilled square.
|
---|
| 261 |
|
---|
| 262 | Create QFonts like this:
|
---|
| 263 | \code
|
---|
| 264 | QFont serifFont( "Times", 10, Bold );
|
---|
| 265 | QFont sansFont( "Helvetica [Cronyx]", 12 );
|
---|
| 266 | \endcode
|
---|
| 267 |
|
---|
| 268 | The attributes set in the constructor can also be set later, e.g.
|
---|
| 269 | setFamily(), setPointSize(), setPointSizeFloat(), setWeight() and
|
---|
| 270 | setItalic(). The remaining attributes must be set after
|
---|
| 271 | contstruction, e.g. setBold(), setUnderline(), setOverline(),
|
---|
| 272 | setStrikeOut() and setFixedPitch(). QFontInfo objects should be
|
---|
| 273 | created \e after the font's attributes have been set. A QFontInfo
|
---|
| 274 | object will not change, even if you change the font's
|
---|
| 275 | attributes. The corresponding "get" functions, e.g. family(),
|
---|
| 276 | pointSize(), etc., return the values that were set, even though
|
---|
| 277 | the values used may differ. The actual values are available from a
|
---|
| 278 | QFontInfo object.
|
---|
| 279 |
|
---|
| 280 | If the requested font family is unavailable you can influence the
|
---|
| 281 | \link #fontmatching font matching algorithm\endlink by choosing a
|
---|
| 282 | particular \l{QFont::StyleHint} and \l{QFont::StyleStrategy} with
|
---|
| 283 | setStyleHint(). The default family (corresponding to the current
|
---|
| 284 | style hint) is returned by defaultFamily().
|
---|
| 285 |
|
---|
| 286 | The font-matching algorithm has a lastResortFamily() and
|
---|
| 287 | lastResortFont() in cases where a suitable match cannot be found.
|
---|
| 288 | You can provide substitutions for font family names using
|
---|
| 289 | insertSubstitution() and insertSubstitutions(). Substitutions can
|
---|
| 290 | be removed with removeSubstitution(). Use substitute() to retrieve
|
---|
| 291 | a family's first substitute, or the family name itself if it has
|
---|
| 292 | no substitutes. Use substitutes() to retrieve a list of a family's
|
---|
| 293 | substitutes (which may be empty).
|
---|
| 294 |
|
---|
| 295 | Every QFont has a key() which you can use, for example, as the key
|
---|
| 296 | in a cache or dictionary. If you want to store a user's font
|
---|
| 297 | preferences you could use QSettings, writing the font information
|
---|
| 298 | with toString() and reading it back with fromString(). The
|
---|
| 299 | operator<<() and operator>>() functions are also available, but
|
---|
| 300 | they work on a data stream.
|
---|
| 301 |
|
---|
| 302 | It is possible to set the height of characters shown on the screen
|
---|
| 303 | to a specified number of pixels with setPixelSize(); however using
|
---|
| 304 | setPointSize() has a similar effect and provides device
|
---|
| 305 | independence.
|
---|
| 306 |
|
---|
| 307 | Under the X Window System you can set a font using its system
|
---|
| 308 | specific name with setRawName().
|
---|
| 309 |
|
---|
| 310 | Loading fonts can be expensive, especially on X11. QFont contains
|
---|
| 311 | extensive optimizations to make the copying of QFont objects fast,
|
---|
| 312 | and to cache the results of the slow window system functions it
|
---|
| 313 | depends upon.
|
---|
| 314 |
|
---|
| 315 | \target fontmatching
|
---|
| 316 | The font matching algorithm works as follows:
|
---|
| 317 | \list 1
|
---|
| 318 | \i The specified font family is searched for.
|
---|
| 319 | \i If not found, the styleHint() is used to select a replacement
|
---|
| 320 | family.
|
---|
| 321 | \i Each replacement font family is searched for.
|
---|
| 322 | \i If none of these are found or there was no styleHint(), "helvetica"
|
---|
| 323 | will be searched for.
|
---|
| 324 | \i If "helvetica" isn't found Qt will try the lastResortFamily().
|
---|
| 325 | \i If the lastResortFamily() isn't found Qt will try the
|
---|
| 326 | lastResortFont() which will always return a name of some kind.
|
---|
| 327 | \endlist
|
---|
| 328 |
|
---|
| 329 | Once a font is found, the remaining attributes are matched in order of
|
---|
| 330 | priority:
|
---|
| 331 | \list 1
|
---|
| 332 | \i fixedPitch()
|
---|
| 333 | \i pointSize() (see below)
|
---|
| 334 | \i weight()
|
---|
| 335 | \i italic()
|
---|
| 336 | \endlist
|
---|
| 337 |
|
---|
| 338 | If you have a font which matches on family, even if none of the
|
---|
| 339 | other attributes match, this font will be chosen in preference to
|
---|
| 340 | a font which doesn't match on family but which does match on the
|
---|
| 341 | other attributes. This is because font family is the dominant
|
---|
| 342 | search criteria.
|
---|
| 343 |
|
---|
| 344 | The point size is defined to match if it is within 20% of the
|
---|
| 345 | requested point size. When several fonts match and are only
|
---|
| 346 | distinguished by point size, the font with the closest point size
|
---|
| 347 | to the one requested will be chosen.
|
---|
| 348 |
|
---|
| 349 | The actual family, font size, weight and other font attributes
|
---|
| 350 | used for drawing text will depend on what's available for the
|
---|
| 351 | chosen family under the window system. A QFontInfo object can be
|
---|
| 352 | used to determine the actual values used for drawing the text.
|
---|
| 353 |
|
---|
| 354 | Examples:
|
---|
| 355 |
|
---|
| 356 | \code
|
---|
| 357 | QFont f("Helvetica");
|
---|
| 358 | \endcode
|
---|
| 359 | If you had both an Adobe and a Cronyx Helvetica, you might get
|
---|
| 360 | either.
|
---|
| 361 |
|
---|
| 362 | \code
|
---|
| 363 | QFont f1( "Helvetica [Cronyx]" ); // Qt 3.x
|
---|
| 364 | QFont f2( "Cronyx-Helvetica" ); // Qt 2.x compatibility
|
---|
| 365 | \endcode
|
---|
| 366 | You can specify the foundry you want in the family name. Both fonts,
|
---|
| 367 | f1 and f2, in the above example will be set to "Helvetica
|
---|
| 368 | [Cronyx]".
|
---|
| 369 |
|
---|
| 370 | To determine the attributes of the font actually used in the window
|
---|
| 371 | system, use a QFontInfo object, e.g.
|
---|
| 372 | \code
|
---|
| 373 | QFontInfo info( f1 );
|
---|
| 374 | QString family = info.family();
|
---|
| 375 | \endcode
|
---|
| 376 |
|
---|
| 377 | To find out font metrics use a QFontMetrics object, e.g.
|
---|
| 378 | \code
|
---|
| 379 | QFontMetrics fm( f1 );
|
---|
| 380 | int pixelWidth = fm.width( "How many pixels wide is this text?" );
|
---|
| 381 | int pixelHeight = fm.height();
|
---|
| 382 | \endcode
|
---|
| 383 |
|
---|
| 384 | For more general information on fonts, see the
|
---|
| 385 | \link http://www.nwalsh.com/comp.fonts/FAQ/ comp.fonts FAQ.\endlink
|
---|
| 386 | Information on encodings can be found from
|
---|
| 387 | \link http://czyborra.com/ Roman Czyborra's\endlink page.
|
---|
| 388 |
|
---|
| 389 | \sa QFontMetrics QFontInfo QFontDatabase QApplication::setFont()
|
---|
| 390 | QWidget::setFont() QPainter::setFont() QFont::StyleHint
|
---|
| 391 | QFont::Weight
|
---|
| 392 | */
|
---|
| 393 |
|
---|
| 394 | /*!
|
---|
| 395 | \enum QFont::Script
|
---|
| 396 |
|
---|
| 397 | This enum represents \link unicode.html Unicode \endlink allocated
|
---|
| 398 | scripts. For exhaustive coverage see \link
|
---|
| 399 | http://www.amazon.com/exec/obidos/ASIN/0201616335/trolltech/t The
|
---|
| 400 | Unicode Standard Version 3.0 \endlink. The following scripts are
|
---|
| 401 | supported:
|
---|
| 402 |
|
---|
| 403 | Modern European alphabetic scripts (left to right):
|
---|
| 404 |
|
---|
| 405 | \value Latin consists of most alphabets based on the original Latin alphabet.
|
---|
| 406 | \value Greek covers ancient and modern Greek and Coptic.
|
---|
| 407 | \value Cyrillic covers the Slavic and non-Slavic languages using
|
---|
| 408 | cyrillic alphabets.
|
---|
| 409 | \value Armenian contains the Armenian alphabet used with the
|
---|
| 410 | Armenian language.
|
---|
| 411 | \value Georgian covers at least the language Georgian.
|
---|
| 412 | \value Runic covers the known constituents of the Runic alphabets used
|
---|
| 413 | by the early and medieval societies in the Germanic,
|
---|
| 414 | Scandinavian, and Anglo-Saxon areas.
|
---|
| 415 | \value Ogham is an alphabetical script used to write a very early
|
---|
| 416 | form of Irish.
|
---|
| 417 | \value SpacingModifiers are small signs indicating modifications
|
---|
| 418 | to the preceeding letter.
|
---|
| 419 | \value CombiningMarks consist of diacritical marks not specific to
|
---|
| 420 | a particular alphabet, diacritical marks used in
|
---|
| 421 | combination with mathematical and technical symbols, and
|
---|
| 422 | glyph encodings applied to multiple letterforms.
|
---|
| 423 |
|
---|
| 424 | Middle Eastern scripts (right to left):
|
---|
| 425 |
|
---|
| 426 | \value Hebrew is used for writing Hebrew, Yiddish, and some other languages.
|
---|
| 427 | \value Arabic covers the Arabic language as well as Persian, Urdu,
|
---|
| 428 | Kurdish and some others.
|
---|
| 429 | \value Syriac is used to write the active liturgical languages and
|
---|
| 430 | dialects of several Middle Eastern and Southeast Indian
|
---|
| 431 | communities.
|
---|
| 432 | \value Thaana is used to write the Maledivian Dhivehi language.
|
---|
| 433 |
|
---|
| 434 | South and Southeast Asian scripts (left to right with few historical exceptions):
|
---|
| 435 |
|
---|
| 436 | \value Devanagari covers classical Sanskrit and modern Hindi as
|
---|
| 437 | well as several other languages.
|
---|
| 438 | \value Bengali is a relative to Devanagari employed to write the
|
---|
| 439 | Bengali language used in West Bengal/India and Bangladesh
|
---|
| 440 | as well as several minority languages.
|
---|
| 441 | \value Gurmukhi is another Devanagari relative used to write Punjabi.
|
---|
| 442 | \value Gujarati is closely related to Devanagari and used to write
|
---|
| 443 | the Gujarati language of the Gujarat state in India.
|
---|
| 444 | \value Oriya is used to write the Oriya language of Orissa state/India.
|
---|
| 445 | \value Tamil is used to write the Tamil language of Tamil Nadu state/India,
|
---|
| 446 | Sri Lanka, Singapore and parts of Malaysia as well as some
|
---|
| 447 | minority languages.
|
---|
| 448 | \value Telugu is used to write the Telugu language of Andhra
|
---|
| 449 | Pradesh state/India and some minority languages.
|
---|
| 450 | \value Kannada is another South Indian script used to write the
|
---|
| 451 | Kannada language of Karnataka state/India and some minority
|
---|
| 452 | languages.
|
---|
| 453 | \value Malayalam is used to write the Malayalam language of Kerala
|
---|
| 454 | state/India.
|
---|
| 455 | \value Sinhala is used for Sri Lanka's majority language Sinhala
|
---|
| 456 | and is also employed to write Pali, Sanskrit, and Tamil.
|
---|
| 457 | \value Thai is used to write Thai and other Southeast Asian languages.
|
---|
| 458 | \value Lao is a language and script quite similar to Thai.
|
---|
| 459 | \value Tibetan is the script used to write Tibetan in several
|
---|
| 460 | countries like Tibet, the bordering Indian regions and
|
---|
| 461 | Nepal. It is also used in the Buddist philosophy and
|
---|
| 462 | liturgy of the Mongolian cultural area.
|
---|
| 463 | \value Myanmar is mainly used to write the Burmese language of
|
---|
| 464 | Myanmar (former Burma).
|
---|
| 465 | \value Khmer is the official language of Kampuchea.
|
---|
| 466 |
|
---|
| 467 | East Asian scripts (traditionally top-down, right to left, modern
|
---|
| 468 | often horizontal left to right):
|
---|
| 469 |
|
---|
| 470 | \value Han consists of the CJK (Chinese, Japanese, Korean)
|
---|
| 471 | idiographic characters.
|
---|
| 472 | \value Hiragana is a cursive syllabary used to indicate phonetics
|
---|
| 473 | and pronounciation of Japanese words.
|
---|
| 474 | \value Katakana is a non-cursive syllabic script used to write
|
---|
| 475 | Japanese words with visual emphasis and non-Japanese words
|
---|
| 476 | in a phonetical manner.
|
---|
| 477 | \value Hangul is a Korean script consisting of alphabetic components.
|
---|
| 478 | \value Bopomofo is a phonetic alphabet for Chinese (mainly Mandarin).
|
---|
| 479 | \value Yi (also called Cuan or Wei) is a syllabary used to write
|
---|
| 480 | the Yi language of Southwestern China, Myanmar, Laos, and Vietnam.
|
---|
| 481 |
|
---|
| 482 | Additional scripts that do not fit well into the script categories above:
|
---|
| 483 |
|
---|
| 484 | \value Ethiopic is a syllabary used by several Central East African languages.
|
---|
| 485 | \value Cherokee is a left-to-right syllabic script used to write
|
---|
| 486 | the Cherokee language.
|
---|
| 487 | \value CanadianAboriginal consists of the syllabics used by some
|
---|
| 488 | Canadian aboriginal societies.
|
---|
| 489 | \value Mongolian is the traditional (and recently reintroduced)
|
---|
| 490 | script used to write Mongolian.
|
---|
| 491 |
|
---|
| 492 | Symbols:
|
---|
| 493 |
|
---|
| 494 | \value CurrencySymbols contains currency symbols not encoded in other scripts.
|
---|
| 495 | \value LetterlikeSymbols consists of symbols derived from
|
---|
| 496 | ordinary letters of an alphabetical script.
|
---|
| 497 | \value NumberForms are provided for compatibility with other
|
---|
| 498 | existing character sets.
|
---|
| 499 | \value MathematicalOperators consists of encodings for operators,
|
---|
| 500 | relations and other symbols like arrows used in a mathematical context.
|
---|
| 501 | \value TechnicalSymbols contains representations for control
|
---|
| 502 | codes, the space symbol, APL symbols and other symbols
|
---|
| 503 | mainly used in the context of electronic data processing.
|
---|
| 504 | \value GeometricSymbols covers block elements and geometric shapes.
|
---|
| 505 | \value MiscellaneousSymbols consists of a heterogeneous collection
|
---|
| 506 | of symbols that do not fit any other Unicode character
|
---|
| 507 | block, e.g. Dingbats.
|
---|
| 508 | \value EnclosedAndSquare is provided for compatibility with some
|
---|
| 509 | East Asian standards.
|
---|
| 510 | \value Braille is an international writing system used by blind
|
---|
| 511 | people. This script encodes the 256 eight-dot patterns with
|
---|
| 512 | the 64 six-dot patterns as a subset.
|
---|
| 513 |
|
---|
| 514 | \value Tagalog
|
---|
| 515 | \value Hanunoo
|
---|
| 516 | \value Buhid
|
---|
| 517 | \value Tagbanwa
|
---|
| 518 |
|
---|
| 519 | \value KatakanaHalfWidth
|
---|
| 520 |
|
---|
| 521 | \value Limbu (Unicode 4.0)
|
---|
| 522 | \value TaiLe (Unicode 4.0)
|
---|
| 523 |
|
---|
| 524 | \value Unicode includes all the above scripts.
|
---|
| 525 | */
|
---|
| 526 |
|
---|
| 527 | /*! \internal
|
---|
| 528 |
|
---|
| 529 | Constructs a font for use on the paint device \a pd using the
|
---|
| 530 | specified font \a data.
|
---|
| 531 | */
|
---|
| 532 | QFont::QFont( QFontPrivate *data, QPaintDevice *pd )
|
---|
| 533 | {
|
---|
| 534 | d = new QFontPrivate( *data );
|
---|
| 535 | Q_CHECK_PTR( d );
|
---|
| 536 | d->paintdevice = pd;
|
---|
| 537 |
|
---|
| 538 | // now a single reference
|
---|
| 539 | d->count = 1;
|
---|
| 540 | }
|
---|
| 541 |
|
---|
| 542 | /*! \internal
|
---|
| 543 | Detaches the font object from common font data.
|
---|
| 544 | */
|
---|
| 545 | void QFont::detach()
|
---|
| 546 | {
|
---|
| 547 | if (d->count == 1) {
|
---|
| 548 | if ( d->engineData )
|
---|
| 549 | d->engineData->deref();
|
---|
| 550 | d->engineData = 0;
|
---|
| 551 |
|
---|
| 552 | return;
|
---|
| 553 | }
|
---|
| 554 |
|
---|
| 555 | QFontPrivate *old_d = d;
|
---|
| 556 | d = new QFontPrivate( *old_d );
|
---|
| 557 |
|
---|
| 558 | /*
|
---|
| 559 | if this font is a copy of the application default font, set the
|
---|
| 560 | fontdef mask to zero to indicate that *nothing* has been
|
---|
| 561 | explicitly set by the programmer.
|
---|
| 562 | */
|
---|
| 563 | const QFont appfont = QApplication::font();
|
---|
| 564 | if ( old_d == appfont.d )
|
---|
| 565 | d->mask = 0;
|
---|
| 566 |
|
---|
| 567 | if ( old_d->deref() )
|
---|
| 568 | delete old_d;
|
---|
| 569 | }
|
---|
| 570 |
|
---|
| 571 | /*!
|
---|
| 572 | Constructs a font object that uses the application's default font.
|
---|
| 573 |
|
---|
| 574 | \sa QApplication::setFont(), QApplication::font()
|
---|
| 575 | */
|
---|
| 576 | QFont::QFont()
|
---|
| 577 | {
|
---|
| 578 | const QFont appfont = QApplication::font();
|
---|
| 579 | d = appfont.d;
|
---|
| 580 | d->ref();
|
---|
| 581 | }
|
---|
| 582 |
|
---|
| 583 | /*!
|
---|
| 584 | Constructs a font object with the specified \a family, \a
|
---|
| 585 | pointSize, \a weight and \a italic settings.
|
---|
| 586 |
|
---|
| 587 | If \a pointSize is <= 0 it is set to 1.
|
---|
| 588 |
|
---|
| 589 | The \a family name may optionally also include a foundry name,
|
---|
| 590 | e.g. "Helvetica [Cronyx]". (The Qt 2.x syntax, i.e.
|
---|
| 591 | "Cronyx-Helvetica", is also supported.) If the \a family is
|
---|
| 592 | available from more than one foundry and the foundry isn't
|
---|
| 593 | specified, an arbitrary foundry is chosen. If the family isn't
|
---|
| 594 | available a family will be set using the \link #fontmatching font
|
---|
| 595 | matching\endlink algorithm.
|
---|
| 596 |
|
---|
| 597 | \sa Weight, setFamily(), setPointSize(), setWeight(), setItalic(),
|
---|
| 598 | setStyleHint() QApplication::font()
|
---|
| 599 | */
|
---|
| 600 | QFont::QFont( const QString &family, int pointSize, int weight, bool italic )
|
---|
| 601 | {
|
---|
| 602 |
|
---|
| 603 | d = new QFontPrivate;
|
---|
| 604 | Q_CHECK_PTR( d );
|
---|
| 605 |
|
---|
| 606 | d->mask = QFontPrivate::Family;
|
---|
| 607 |
|
---|
| 608 | if (pointSize <= 0) {
|
---|
| 609 | pointSize = 12;
|
---|
| 610 | } else {
|
---|
| 611 | d->mask |= QFontPrivate::Size;
|
---|
| 612 | }
|
---|
| 613 |
|
---|
| 614 | if (weight < 0) {
|
---|
| 615 | weight = Normal;
|
---|
| 616 | } else {
|
---|
| 617 | d->mask |= QFontPrivate::Weight | QFontPrivate::Italic;
|
---|
| 618 | }
|
---|
| 619 |
|
---|
| 620 | d->request.family = family;
|
---|
| 621 | d->request.pointSize = pointSize * 10;
|
---|
| 622 | d->request.pixelSize = -1;
|
---|
| 623 | d->request.weight = weight;
|
---|
| 624 | d->request.italic = italic;
|
---|
| 625 | }
|
---|
| 626 |
|
---|
| 627 | /*!
|
---|
| 628 | Constructs a font that is a copy of \a font.
|
---|
| 629 | */
|
---|
| 630 | QFont::QFont( const QFont &font )
|
---|
| 631 | {
|
---|
| 632 | d = font.d;
|
---|
| 633 | d->ref();
|
---|
| 634 | }
|
---|
| 635 |
|
---|
| 636 | /*!
|
---|
| 637 | Destroys the font object and frees all allocated resources.
|
---|
| 638 | */
|
---|
| 639 | QFont::~QFont()
|
---|
| 640 | {
|
---|
| 641 | if ( d->deref() )
|
---|
| 642 | delete d;
|
---|
| 643 | d = 0;
|
---|
| 644 | }
|
---|
| 645 |
|
---|
| 646 | /*!
|
---|
| 647 | Assigns \a font to this font and returns a reference to it.
|
---|
| 648 | */
|
---|
| 649 | QFont &QFont::operator=( const QFont &font )
|
---|
| 650 | {
|
---|
| 651 | if ( font.d != d ) {
|
---|
| 652 | if ( d->deref() )
|
---|
| 653 | delete d;
|
---|
| 654 | d = font.d;
|
---|
| 655 | d->ref();
|
---|
| 656 | }
|
---|
| 657 |
|
---|
| 658 | return *this;
|
---|
| 659 | }
|
---|
| 660 |
|
---|
| 661 | /*!
|
---|
| 662 | Returns the requested font family name, i.e. the name set in the
|
---|
| 663 | constructor or the last setFont() call.
|
---|
| 664 |
|
---|
| 665 | \sa setFamily() substitutes() substitute()
|
---|
| 666 | */
|
---|
| 667 | QString QFont::family() const
|
---|
| 668 | {
|
---|
| 669 | return d->request.family;
|
---|
| 670 | }
|
---|
| 671 |
|
---|
| 672 | /*!
|
---|
| 673 | Sets the family name of the font. The name is case insensitive and
|
---|
| 674 | may include a foundry name.
|
---|
| 675 |
|
---|
| 676 | The \a family name may optionally also include a foundry name,
|
---|
| 677 | e.g. "Helvetica [Cronyx]". (The Qt 2.x syntax, i.e.
|
---|
| 678 | "Cronyx-Helvetica", is also supported.) If the \a family is
|
---|
| 679 | available from more than one foundry and the foundry isn't
|
---|
| 680 | specified, an arbitrary foundry is chosen. If the family isn't
|
---|
| 681 | available a family will be set using the \link #fontmatching font
|
---|
| 682 | matching\endlink algorithm.
|
---|
| 683 |
|
---|
| 684 | \sa family(), setStyleHint(), QFontInfo
|
---|
| 685 | */
|
---|
| 686 | void QFont::setFamily( const QString &family )
|
---|
| 687 | {
|
---|
| 688 | detach();
|
---|
| 689 |
|
---|
| 690 | d->request.family = family;
|
---|
| 691 | #if defined(Q_WS_X11)
|
---|
| 692 | d->request.addStyle = QString::null;
|
---|
| 693 | #endif // Q_WS_X11
|
---|
| 694 |
|
---|
| 695 | d->mask |= QFontPrivate::Family;
|
---|
| 696 | }
|
---|
| 697 |
|
---|
| 698 | /*!
|
---|
| 699 | Returns the point size in 1/10ths of a point.
|
---|
| 700 |
|
---|
| 701 | The returned value will be -1 if the font size has been specified
|
---|
| 702 | in pixels.
|
---|
| 703 |
|
---|
| 704 | \sa pointSize() pointSizeFloat()
|
---|
| 705 | */
|
---|
| 706 | int QFont::deciPointSize() const
|
---|
| 707 | {
|
---|
| 708 | return d->request.pointSize;
|
---|
| 709 | }
|
---|
| 710 |
|
---|
| 711 | /*!
|
---|
| 712 | Returns the point size of the font. Returns -1 if the font size
|
---|
| 713 | was specified in pixels.
|
---|
| 714 |
|
---|
| 715 | \sa setPointSize() deciPointSize() pointSizeFloat()
|
---|
| 716 | */
|
---|
| 717 | int QFont::pointSize() const
|
---|
| 718 | {
|
---|
| 719 | return d->request.pointSize == -1 ? -1 : (d->request.pointSize + 5) / 10;
|
---|
| 720 | }
|
---|
| 721 |
|
---|
| 722 | /*!
|
---|
| 723 | Sets the point size to \a pointSize. The point size must be
|
---|
| 724 | greater than zero.
|
---|
| 725 |
|
---|
| 726 | \sa pointSize() setPointSizeFloat()
|
---|
| 727 | */
|
---|
| 728 | void QFont::setPointSize( int pointSize )
|
---|
| 729 | {
|
---|
| 730 | if ( pointSize <= 0 ) {
|
---|
| 731 |
|
---|
| 732 | #if defined(QT_CHECK_RANGE)
|
---|
| 733 | qWarning( "QFont::setPointSize: Point size <= 0 (%d)", pointSize );
|
---|
| 734 | #endif
|
---|
| 735 |
|
---|
| 736 | return;
|
---|
| 737 | }
|
---|
| 738 |
|
---|
| 739 | detach();
|
---|
| 740 |
|
---|
| 741 | d->request.pointSize = pointSize * 10;
|
---|
| 742 | d->request.pixelSize = -1;
|
---|
| 743 |
|
---|
| 744 | d->mask |= QFontPrivate::Size;
|
---|
| 745 | }
|
---|
| 746 |
|
---|
| 747 | /*!
|
---|
| 748 | Sets the point size to \a pointSize. The point size must be
|
---|
| 749 | greater than zero. The requested precision may not be achieved on
|
---|
| 750 | all platforms.
|
---|
| 751 |
|
---|
| 752 | \sa pointSizeFloat() setPointSize() setPixelSize()
|
---|
| 753 | */
|
---|
| 754 | void QFont::setPointSizeFloat( float pointSize )
|
---|
| 755 | {
|
---|
| 756 | if ( pointSize <= 0.0 ) {
|
---|
| 757 | #if defined(QT_CHECK_RANGE)
|
---|
| 758 | qWarning( "QFont::setPointSize: Point size <= 0 (%f)", pointSize );
|
---|
| 759 | #endif
|
---|
| 760 | return;
|
---|
| 761 | }
|
---|
| 762 |
|
---|
| 763 | detach();
|
---|
| 764 |
|
---|
| 765 | d->request.pointSize = qRound(pointSize * 10.0);
|
---|
| 766 | d->request.pixelSize = -1;
|
---|
| 767 |
|
---|
| 768 | d->mask |= QFontPrivate::Size;
|
---|
| 769 | }
|
---|
| 770 |
|
---|
| 771 | /*!
|
---|
| 772 | Returns the point size of the font. Returns -1 if the font size was
|
---|
| 773 | specified in pixels.
|
---|
| 774 |
|
---|
| 775 | \sa pointSize() setPointSizeFloat() pixelSize() QFontInfo::pointSize() QFontInfo::pixelSize()
|
---|
| 776 | */
|
---|
| 777 | float QFont::pointSizeFloat() const
|
---|
| 778 | {
|
---|
| 779 | return float( d->request.pointSize == -1 ? -10 : d->request.pointSize ) / 10.0;
|
---|
| 780 | }
|
---|
| 781 |
|
---|
| 782 | /*!
|
---|
| 783 | Sets the font size to \a pixelSize pixels.
|
---|
| 784 |
|
---|
| 785 | Using this function makes the font device dependent. Use
|
---|
| 786 | setPointSize() or setPointSizeFloat() to set the size of the font
|
---|
| 787 | in a device independent manner.
|
---|
| 788 |
|
---|
| 789 | \sa pixelSize()
|
---|
| 790 | */
|
---|
| 791 | void QFont::setPixelSize( int pixelSize )
|
---|
| 792 | {
|
---|
| 793 | if ( pixelSize <= 0 ) {
|
---|
| 794 | #if defined(QT_CHECK_RANGE)
|
---|
| 795 | qWarning( "QFont::setPixelSize: Pixel size <= 0 (%d)", pixelSize );
|
---|
| 796 | #endif
|
---|
| 797 | return;
|
---|
| 798 | }
|
---|
| 799 |
|
---|
| 800 | detach();
|
---|
| 801 |
|
---|
| 802 | d->request.pixelSize = pixelSize;
|
---|
| 803 | d->request.pointSize = -1;
|
---|
| 804 |
|
---|
| 805 | d->mask |= QFontPrivate::Size;
|
---|
| 806 | }
|
---|
| 807 |
|
---|
| 808 | /*!
|
---|
| 809 | Returns the pixel size of the font if it was set with
|
---|
| 810 | setPixelSize(). Returns -1 if the size was set with setPointSize()
|
---|
| 811 | or setPointSizeFloat().
|
---|
| 812 |
|
---|
| 813 | \sa setPixelSize() pointSize() QFontInfo::pointSize() QFontInfo::pixelSize()
|
---|
| 814 | */
|
---|
| 815 | int QFont::pixelSize() const
|
---|
| 816 | {
|
---|
| 817 | return d->request.pixelSize;
|
---|
| 818 | }
|
---|
| 819 |
|
---|
| 820 | /*! \obsolete
|
---|
| 821 |
|
---|
| 822 | Sets the logical pixel height of font characters when shown on
|
---|
| 823 | the screen to \a pixelSize.
|
---|
| 824 | */
|
---|
| 825 | void QFont::setPixelSizeFloat( float pixelSize )
|
---|
| 826 | {
|
---|
| 827 | setPixelSize( (int)pixelSize );
|
---|
| 828 | }
|
---|
| 829 |
|
---|
| 830 | /*!
|
---|
| 831 | Returns TRUE if italic has been set; otherwise returns FALSE.
|
---|
| 832 |
|
---|
| 833 | \sa setItalic()
|
---|
| 834 | */
|
---|
| 835 | bool QFont::italic() const
|
---|
| 836 | {
|
---|
| 837 | return d->request.italic;
|
---|
| 838 | }
|
---|
| 839 |
|
---|
| 840 | /*!
|
---|
| 841 | If \a enable is TRUE, italic is set on; otherwise italic is set
|
---|
| 842 | off.
|
---|
| 843 |
|
---|
| 844 | \sa italic(), QFontInfo
|
---|
| 845 | */
|
---|
| 846 | void QFont::setItalic( bool enable )
|
---|
| 847 | {
|
---|
| 848 | detach();
|
---|
| 849 |
|
---|
| 850 | d->request.italic = enable;
|
---|
| 851 | d->mask |= QFontPrivate::Italic;
|
---|
| 852 | }
|
---|
| 853 |
|
---|
| 854 | /*!
|
---|
| 855 | Returns the weight of the font which is one of the enumerated
|
---|
| 856 | values from \l{QFont::Weight}.
|
---|
| 857 |
|
---|
| 858 | \sa setWeight(), Weight, QFontInfo
|
---|
| 859 | */
|
---|
| 860 | int QFont::weight() const
|
---|
| 861 | {
|
---|
| 862 | return d->request.weight;
|
---|
| 863 | }
|
---|
| 864 |
|
---|
| 865 | /*!
|
---|
| 866 | \enum QFont::Weight
|
---|
| 867 |
|
---|
| 868 | Qt uses a weighting scale from 0 to 99 similar to, but not the
|
---|
| 869 | same as, the scales used in Windows or CSS. A weight of 0 is
|
---|
| 870 | ultralight, whilst 99 will be an extremely black.
|
---|
| 871 |
|
---|
| 872 | This enum contains the predefined font weights:
|
---|
| 873 |
|
---|
| 874 | \value Light 25
|
---|
| 875 | \value Normal 50
|
---|
| 876 | \value DemiBold 63
|
---|
| 877 | \value Bold 75
|
---|
| 878 | \value Black 87
|
---|
| 879 | */
|
---|
| 880 |
|
---|
| 881 | /*!
|
---|
| 882 | Sets the weight the font to \a weight, which should be a value
|
---|
| 883 | from the \l QFont::Weight enumeration.
|
---|
| 884 |
|
---|
| 885 | \sa weight(), QFontInfo
|
---|
| 886 | */
|
---|
| 887 | void QFont::setWeight( int weight )
|
---|
| 888 | {
|
---|
| 889 | if ( weight < 0 || weight > 99 ) {
|
---|
| 890 |
|
---|
| 891 | #if defined(QT_CHECK_RANGE)
|
---|
| 892 | qWarning( "QFont::setWeight: Value out of range (%d)", weight );
|
---|
| 893 | #endif
|
---|
| 894 |
|
---|
| 895 | return;
|
---|
| 896 | }
|
---|
| 897 |
|
---|
| 898 | detach();
|
---|
| 899 |
|
---|
| 900 | d->request.weight = weight;
|
---|
| 901 | d->mask |= QFontPrivate::Weight;
|
---|
| 902 | }
|
---|
| 903 |
|
---|
| 904 | /*!
|
---|
| 905 | \fn bool QFont::bold() const
|
---|
| 906 |
|
---|
| 907 | Returns TRUE if weight() is a value greater than \link Weight
|
---|
| 908 | QFont::Normal \endlink; otherwise returns FALSE.
|
---|
| 909 |
|
---|
| 910 | \sa weight(), setBold(), QFontInfo::bold()
|
---|
| 911 | */
|
---|
| 912 |
|
---|
| 913 | /*!
|
---|
| 914 | \fn void QFont::setBold( bool enable )
|
---|
| 915 |
|
---|
| 916 | If \a enable is true sets the font's weight to \link Weight
|
---|
| 917 | QFont::Bold \endlink; otherwise sets the weight to \link Weight
|
---|
| 918 | QFont::Normal\endlink.
|
---|
| 919 |
|
---|
| 920 | For finer boldness control use setWeight().
|
---|
| 921 |
|
---|
| 922 | \sa bold(), setWeight()
|
---|
| 923 | */
|
---|
| 924 |
|
---|
| 925 | /*!
|
---|
| 926 | Returns TRUE if underline has been set; otherwise returns FALSE.
|
---|
| 927 |
|
---|
| 928 | \sa setUnderline()
|
---|
| 929 | */
|
---|
| 930 | bool QFont::underline() const
|
---|
| 931 | {
|
---|
| 932 | return d->underline;
|
---|
| 933 | }
|
---|
| 934 |
|
---|
| 935 | /*!
|
---|
| 936 | If \a enable is TRUE, sets underline on; otherwise sets underline
|
---|
| 937 | off.
|
---|
| 938 |
|
---|
| 939 | \sa underline(), QFontInfo
|
---|
| 940 | */
|
---|
| 941 | void QFont::setUnderline( bool enable )
|
---|
| 942 | {
|
---|
| 943 | detach();
|
---|
| 944 |
|
---|
| 945 | d->underline = enable;
|
---|
| 946 | d->mask |= QFontPrivate::Underline;
|
---|
| 947 | }
|
---|
| 948 |
|
---|
| 949 | /*!
|
---|
| 950 | Returns TRUE if overline has been set; otherwise returns FALSE.
|
---|
| 951 |
|
---|
| 952 | \sa setOverline()
|
---|
| 953 | */
|
---|
| 954 | bool QFont::overline() const
|
---|
| 955 | {
|
---|
| 956 | return d->overline;
|
---|
| 957 | }
|
---|
| 958 |
|
---|
| 959 | /*!
|
---|
| 960 | If \a enable is TRUE, sets overline on; otherwise sets overline off.
|
---|
| 961 |
|
---|
| 962 | \sa overline(), QFontInfo
|
---|
| 963 | */
|
---|
| 964 | void QFont::setOverline( bool enable )
|
---|
| 965 | {
|
---|
| 966 | detach();
|
---|
| 967 |
|
---|
| 968 | d->overline = enable;
|
---|
| 969 | d->mask |= QFontPrivate::Overline;
|
---|
| 970 | }
|
---|
| 971 |
|
---|
| 972 | /*!
|
---|
| 973 | Returns TRUE if strikeout has been set; otherwise returns FALSE.
|
---|
| 974 |
|
---|
| 975 | \sa setStrikeOut()
|
---|
| 976 | */
|
---|
| 977 | bool QFont::strikeOut() const
|
---|
| 978 | {
|
---|
| 979 | return d->strikeOut;
|
---|
| 980 | }
|
---|
| 981 |
|
---|
| 982 | /*!
|
---|
| 983 | If \a enable is TRUE, sets strikeout on; otherwise sets strikeout
|
---|
| 984 | off.
|
---|
| 985 |
|
---|
| 986 | \sa strikeOut(), QFontInfo
|
---|
| 987 | */
|
---|
| 988 | void QFont::setStrikeOut( bool enable )
|
---|
| 989 | {
|
---|
| 990 | detach();
|
---|
| 991 |
|
---|
| 992 | d->strikeOut = enable;
|
---|
| 993 | d->mask |= QFontPrivate::StrikeOut;
|
---|
| 994 | }
|
---|
| 995 |
|
---|
| 996 | /*!
|
---|
| 997 | Returns TRUE if fixed pitch has been set; otherwise returns FALSE.
|
---|
| 998 |
|
---|
| 999 | \sa setFixedPitch(), QFontInfo::fixedPitch()
|
---|
| 1000 | */
|
---|
| 1001 | bool QFont::fixedPitch() const
|
---|
| 1002 | {
|
---|
| 1003 | return d->request.fixedPitch;
|
---|
| 1004 | }
|
---|
| 1005 |
|
---|
| 1006 | /*!
|
---|
| 1007 | If \a enable is TRUE, sets fixed pitch on; otherwise sets fixed
|
---|
| 1008 | pitch off.
|
---|
| 1009 |
|
---|
| 1010 | \sa fixedPitch(), QFontInfo
|
---|
| 1011 | */
|
---|
| 1012 | void QFont::setFixedPitch( bool enable )
|
---|
| 1013 | {
|
---|
| 1014 | detach();
|
---|
| 1015 |
|
---|
| 1016 | d->request.fixedPitch = enable;
|
---|
| 1017 | d->request.ignorePitch = FALSE;
|
---|
| 1018 | d->mask |= QFontPrivate::FixedPitch;
|
---|
| 1019 | }
|
---|
| 1020 |
|
---|
| 1021 | /*!
|
---|
| 1022 | Returns the StyleStrategy.
|
---|
| 1023 |
|
---|
| 1024 | The style strategy affects the \link #fontmatching font
|
---|
| 1025 | matching\endlink algorithm. See \l QFont::StyleStrategy for the
|
---|
| 1026 | list of strategies.
|
---|
| 1027 |
|
---|
| 1028 | \sa setStyleHint() QFont::StyleHint
|
---|
| 1029 | */
|
---|
| 1030 | QFont::StyleStrategy QFont::styleStrategy() const
|
---|
| 1031 | {
|
---|
| 1032 | return (StyleStrategy) d->request.styleStrategy;
|
---|
| 1033 | }
|
---|
| 1034 |
|
---|
| 1035 | /*!
|
---|
| 1036 | Returns the StyleHint.
|
---|
| 1037 |
|
---|
| 1038 | The style hint affects the \link #fontmatching font
|
---|
| 1039 | matching\endlink algorithm. See \l QFont::StyleHint for the list
|
---|
| 1040 | of strategies.
|
---|
| 1041 |
|
---|
| 1042 | \sa setStyleHint(), QFont::StyleStrategy QFontInfo::styleHint()
|
---|
| 1043 | */
|
---|
| 1044 | QFont::StyleHint QFont::styleHint() const
|
---|
| 1045 | {
|
---|
| 1046 | return (StyleHint) d->request.styleHint;
|
---|
| 1047 | }
|
---|
| 1048 |
|
---|
| 1049 | /*!
|
---|
| 1050 | \enum QFont::StyleHint
|
---|
| 1051 |
|
---|
| 1052 | Style hints are used by the \link #fontmatching font
|
---|
| 1053 | matching\endlink algorithm to find an appropriate default family
|
---|
| 1054 | if a selected font family is not available.
|
---|
| 1055 |
|
---|
| 1056 | \value AnyStyle leaves the font matching algorithm to choose the
|
---|
| 1057 | family. This is the default.
|
---|
| 1058 |
|
---|
| 1059 | \value SansSerif the font matcher prefer sans serif fonts.
|
---|
| 1060 | \value Helvetica is a synonym for \c SansSerif.
|
---|
| 1061 |
|
---|
| 1062 | \value Serif the font matcher prefers serif fonts.
|
---|
| 1063 | \value Times is a synonym for \c Serif.
|
---|
| 1064 |
|
---|
| 1065 | \value TypeWriter the font matcher prefers fixed pitch fonts.
|
---|
| 1066 | \value Courier a synonym for \c TypeWriter.
|
---|
| 1067 |
|
---|
| 1068 | \value OldEnglish the font matcher prefers decorative fonts.
|
---|
| 1069 | \value Decorative is a synonym for \c OldEnglish.
|
---|
| 1070 |
|
---|
| 1071 | \value System the font matcher prefers system fonts.
|
---|
| 1072 | */
|
---|
| 1073 |
|
---|
| 1074 | /*!
|
---|
| 1075 | \enum QFont::StyleStrategy
|
---|
| 1076 |
|
---|
| 1077 | The style strategy tells the \link #fontmatching font
|
---|
| 1078 | matching\endlink algorithm what type of fonts should be used to
|
---|
| 1079 | find an appropriate default family.
|
---|
| 1080 |
|
---|
| 1081 | The following strategies are available:
|
---|
| 1082 |
|
---|
| 1083 | \value PreferDefault the default style strategy. It does not prefer
|
---|
| 1084 | any type of font.
|
---|
| 1085 | \value PreferBitmap prefers bitmap fonts (as opposed to outline
|
---|
| 1086 | fonts). On X11, this will cause Qt to disregard fonts from
|
---|
| 1087 | the Xft font extension.
|
---|
| 1088 | \value PreferDevice prefers device fonts.
|
---|
| 1089 | \value PreferOutline prefers outline fonts (as opposed to bitmap fonts).
|
---|
| 1090 | \value ForceOutline forces the use of outline fonts.
|
---|
| 1091 | \value NoAntialias don't antialias the fonts.
|
---|
| 1092 | \value PreferAntialias antialias if possible.
|
---|
| 1093 | \value OpenGLCompatible forces the use of OpenGL compatible
|
---|
| 1094 | fonts. On X11, this will cause Qt to disregard fonts from
|
---|
| 1095 | the Xft font extension.
|
---|
| 1096 |
|
---|
| 1097 | Any of these may be OR-ed with one of these flags:
|
---|
| 1098 |
|
---|
| 1099 | \value PreferMatch prefer an exact match. The font matcher will try to
|
---|
| 1100 | use the exact font size that has been specified.
|
---|
| 1101 | \value PreferQuality prefer the best quality font. The font matcher
|
---|
| 1102 | will use the nearest standard point size that the font
|
---|
| 1103 | supports.
|
---|
| 1104 | */
|
---|
| 1105 |
|
---|
| 1106 | /*!
|
---|
| 1107 | Sets the style hint and strategy to \a hint and \a strategy,
|
---|
| 1108 | respectively.
|
---|
| 1109 |
|
---|
| 1110 | If these aren't set explicitly the style hint will default to
|
---|
| 1111 | \c AnyStyle and the style strategy to \c PreferDefault.
|
---|
| 1112 |
|
---|
| 1113 | Qt does not support style hints on X11 since this information
|
---|
| 1114 | is not provided by the window system.
|
---|
| 1115 |
|
---|
| 1116 | \sa StyleHint, styleHint(), StyleStrategy, styleStrategy(), QFontInfo
|
---|
| 1117 | */
|
---|
| 1118 | void QFont::setStyleHint( StyleHint hint, StyleStrategy strategy )
|
---|
| 1119 | {
|
---|
| 1120 | detach();
|
---|
| 1121 |
|
---|
| 1122 | if ( ( d->mask & ( QFontPrivate::StyleHint | QFontPrivate::StyleStrategy ) ) &&
|
---|
| 1123 | (StyleHint) d->request.styleHint == hint &&
|
---|
| 1124 | (StyleStrategy) d->request.styleStrategy == strategy )
|
---|
| 1125 | return;
|
---|
| 1126 |
|
---|
| 1127 | d->request.styleHint = hint;
|
---|
| 1128 | d->request.styleStrategy = strategy;
|
---|
| 1129 | d->mask |= QFontPrivate::StyleHint;
|
---|
| 1130 | d->mask |= QFontPrivate::StyleStrategy;
|
---|
| 1131 |
|
---|
| 1132 | #if defined(Q_WS_X11)
|
---|
| 1133 | d->request.addStyle = QString::null;
|
---|
| 1134 | #endif // Q_WS_X11
|
---|
| 1135 | }
|
---|
| 1136 |
|
---|
| 1137 | /*!
|
---|
| 1138 | Sets the style strategy for the font to \a s.
|
---|
| 1139 |
|
---|
| 1140 | \sa QFont::StyleStrategy
|
---|
| 1141 | */
|
---|
| 1142 | void QFont::setStyleStrategy( StyleStrategy s )
|
---|
| 1143 | {
|
---|
| 1144 | detach();
|
---|
| 1145 |
|
---|
| 1146 | if ( ( d->mask & QFontPrivate::StyleStrategy ) &&
|
---|
| 1147 | s == (StyleStrategy)d->request.styleStrategy )
|
---|
| 1148 | return;
|
---|
| 1149 |
|
---|
| 1150 | d->request.styleStrategy = s;
|
---|
| 1151 | d->mask |= QFontPrivate::StyleStrategy;
|
---|
| 1152 | }
|
---|
| 1153 |
|
---|
| 1154 |
|
---|
| 1155 | /*!
|
---|
| 1156 | \enum QFont::Stretch
|
---|
| 1157 |
|
---|
| 1158 | Predefined stretch values that follow the CSS naming convention.
|
---|
| 1159 |
|
---|
| 1160 | \value UltraCondensed 50
|
---|
| 1161 | \value ExtraCondensed 62
|
---|
| 1162 | \value Condensed 75
|
---|
| 1163 | \value SemiCondensed 87
|
---|
| 1164 | \value Unstretched 100
|
---|
| 1165 | \value SemiExpanded 112
|
---|
| 1166 | \value Expanded 125
|
---|
| 1167 | \value ExtraExpanded 150
|
---|
| 1168 | \value UltraExpanded 200
|
---|
| 1169 |
|
---|
| 1170 | \sa setStretch() stretch()
|
---|
| 1171 | */
|
---|
| 1172 |
|
---|
| 1173 | /*!
|
---|
| 1174 | Returns the stretch factor for the font.
|
---|
| 1175 |
|
---|
| 1176 | \sa setStretch()
|
---|
| 1177 | */
|
---|
| 1178 | int QFont::stretch() const
|
---|
| 1179 | {
|
---|
| 1180 | return d->request.stretch;
|
---|
| 1181 | }
|
---|
| 1182 |
|
---|
| 1183 | /*!
|
---|
| 1184 | Sets the stretch factor for the font.
|
---|
| 1185 |
|
---|
| 1186 | The stretch factor changes the width of all characters in the font
|
---|
| 1187 | by \a factor percent. For example, setting \a factor to 150
|
---|
| 1188 | results in all characters in the font being 1.5 times ( ie. 150% )
|
---|
| 1189 | wider. The default stretch factor is 100. The minimum stretch
|
---|
| 1190 | factor is 1, and the maximum stretch factor is 4000.
|
---|
| 1191 |
|
---|
| 1192 | The stretch factor is only applied to outline fonts. The stretch
|
---|
| 1193 | factor is ignored for bitmap fonts.
|
---|
| 1194 |
|
---|
| 1195 | NOTE: QFont cannot stretch XLFD fonts. When loading XLFD fonts on
|
---|
| 1196 | X11, the stretch factor is matched against a predefined set of
|
---|
| 1197 | values for the SETWIDTH_NAME field of the XLFD.
|
---|
| 1198 |
|
---|
| 1199 | \sa stretch() QFont::StyleStrategy
|
---|
| 1200 | */
|
---|
| 1201 | void QFont::setStretch( int factor )
|
---|
| 1202 | {
|
---|
| 1203 | if ( factor < 1 || factor > 4000 ) {
|
---|
| 1204 | #ifdef QT_CHECK_RANGE
|
---|
| 1205 | qWarning( "QFont::setStretch(): parameter '%d' out of range", factor );
|
---|
| 1206 | #endif // QT_CHECK_RANGE
|
---|
| 1207 |
|
---|
| 1208 | return;
|
---|
| 1209 | }
|
---|
| 1210 |
|
---|
| 1211 | detach();
|
---|
| 1212 |
|
---|
| 1213 | if ( ( d->mask & QFontPrivate::Stretch ) &&
|
---|
| 1214 | d->request.stretch == (uint)factor )
|
---|
| 1215 | return;
|
---|
| 1216 |
|
---|
| 1217 | d->request.stretch = (uint)factor;
|
---|
| 1218 | d->mask |= QFontPrivate::Stretch;
|
---|
| 1219 | }
|
---|
| 1220 |
|
---|
| 1221 | /*!
|
---|
| 1222 | If \a enable is TRUE, turns raw mode on; otherwise turns raw mode
|
---|
| 1223 | off. This function only has an effect under X11.
|
---|
| 1224 |
|
---|
| 1225 | If raw mode is enabled, Qt will search for an X font with a
|
---|
| 1226 | complete font name matching the family name, ignoring all other
|
---|
| 1227 | values set for the QFont. If the font name matches several fonts,
|
---|
| 1228 | Qt will use the first font returned by X. QFontInfo \e cannot be
|
---|
| 1229 | used to fetch information about a QFont using raw mode (it will
|
---|
| 1230 | return the values set in the QFont for all parameters, including
|
---|
| 1231 | the family name).
|
---|
| 1232 |
|
---|
| 1233 | \warning Do not use raw mode unless you really, really need it! In
|
---|
| 1234 | most (if not all) cases, setRawName() is a much better choice.
|
---|
| 1235 |
|
---|
| 1236 | \sa rawMode(), setRawName()
|
---|
| 1237 | */
|
---|
| 1238 | void QFont::setRawMode( bool enable )
|
---|
| 1239 | {
|
---|
| 1240 | detach();
|
---|
| 1241 |
|
---|
| 1242 | if ( (bool) d->rawMode == enable ) return;
|
---|
| 1243 |
|
---|
| 1244 | d->rawMode = enable;
|
---|
| 1245 | }
|
---|
| 1246 |
|
---|
| 1247 | /*!
|
---|
| 1248 | Returns TRUE if a window system font exactly matching the settings
|
---|
| 1249 | of this font is available.
|
---|
| 1250 |
|
---|
| 1251 | \sa QFontInfo
|
---|
| 1252 | */
|
---|
| 1253 | bool QFont::exactMatch() const
|
---|
| 1254 | {
|
---|
| 1255 | QFontEngine *engine = d->engineForScript( QFont::NoScript );
|
---|
| 1256 | #ifdef QT_CHECK_STATE
|
---|
| 1257 | Q_ASSERT( engine != 0 );
|
---|
| 1258 | #endif // QT_CHECK_STATE
|
---|
| 1259 |
|
---|
| 1260 | return d->rawMode ? engine->type() != QFontEngine::Box
|
---|
| 1261 | : d->request == engine->fontDef;
|
---|
| 1262 | }
|
---|
| 1263 |
|
---|
| 1264 | /*!
|
---|
| 1265 | Returns TRUE if this font is equal to \a f; otherwise returns
|
---|
| 1266 | FALSE.
|
---|
| 1267 |
|
---|
| 1268 | Two QFonts are considered equal if their font attributes are
|
---|
| 1269 | equal. If rawMode() is enabled for both fonts, only the family
|
---|
| 1270 | fields are compared.
|
---|
| 1271 |
|
---|
| 1272 | \sa operator!=() isCopyOf()
|
---|
| 1273 | */
|
---|
| 1274 | bool QFont::operator==( const QFont &f ) const
|
---|
| 1275 | {
|
---|
| 1276 | return f.d == d || ( f.d->request == d->request &&
|
---|
| 1277 | f.d->underline == d->underline &&
|
---|
| 1278 | f.d->overline == d->overline &&
|
---|
| 1279 | f.d->strikeOut == d->strikeOut );
|
---|
| 1280 | }
|
---|
| 1281 |
|
---|
| 1282 | /*!
|
---|
| 1283 | Returns TRUE if this font is different from \a f; otherwise
|
---|
| 1284 | returns FALSE.
|
---|
| 1285 |
|
---|
| 1286 | Two QFonts are considered to be different if their font attributes
|
---|
| 1287 | are different. If rawMode() is enabled for both fonts, only the
|
---|
| 1288 | family fields are compared.
|
---|
| 1289 |
|
---|
| 1290 | \sa operator==()
|
---|
| 1291 | */
|
---|
| 1292 | bool QFont::operator!=( const QFont &f ) const
|
---|
| 1293 | {
|
---|
| 1294 | return !(operator==( f ));
|
---|
| 1295 | }
|
---|
| 1296 |
|
---|
| 1297 | /*!
|
---|
| 1298 | Returns TRUE if this font and \a f are copies of each other, i.e.
|
---|
| 1299 | one of them was created as a copy of the other and neither has
|
---|
| 1300 | been modified since. This is much stricter than equality.
|
---|
| 1301 |
|
---|
| 1302 | \sa operator=() operator==()
|
---|
| 1303 | */
|
---|
| 1304 | bool QFont::isCopyOf( const QFont & f ) const
|
---|
| 1305 | {
|
---|
| 1306 | return d == f.d;
|
---|
| 1307 | }
|
---|
| 1308 |
|
---|
| 1309 | /*!
|
---|
| 1310 | Returns TRUE if raw mode is used for font name matching; otherwise
|
---|
| 1311 | returns FALSE.
|
---|
| 1312 |
|
---|
| 1313 | \sa setRawMode() rawName()
|
---|
| 1314 | */
|
---|
| 1315 | bool QFont::rawMode() const
|
---|
| 1316 | {
|
---|
| 1317 | return d->rawMode;
|
---|
| 1318 | }
|
---|
| 1319 |
|
---|
| 1320 | /*!
|
---|
| 1321 | Returns a new QFont that has attributes copied from \a other.
|
---|
| 1322 | */
|
---|
| 1323 | QFont QFont::resolve( const QFont &other ) const
|
---|
| 1324 | {
|
---|
| 1325 | if ( *this == other && d->mask == other.d->mask )
|
---|
| 1326 | return *this;
|
---|
| 1327 |
|
---|
| 1328 | QFont font( *this );
|
---|
| 1329 | font.detach();
|
---|
| 1330 |
|
---|
| 1331 | /*
|
---|
| 1332 | if this font is a copy of the application default font, set the
|
---|
| 1333 | fontdef mask to zero to indicate that *nothing* has been
|
---|
| 1334 | explicitly set by the programmer.
|
---|
| 1335 | */
|
---|
| 1336 | const QFont appfont = QApplication::font();
|
---|
| 1337 | if ( d == appfont.d )
|
---|
| 1338 | font.d->mask = 0;
|
---|
| 1339 |
|
---|
| 1340 | font.d->resolve( other.d );
|
---|
| 1341 |
|
---|
| 1342 | return font;
|
---|
| 1343 | }
|
---|
| 1344 |
|
---|
| 1345 | #ifndef QT_NO_COMPAT
|
---|
| 1346 |
|
---|
| 1347 | /*! \obsolete
|
---|
| 1348 |
|
---|
| 1349 | Please use QApplication::font() instead.
|
---|
| 1350 | */
|
---|
| 1351 | QFont QFont::defaultFont()
|
---|
| 1352 | {
|
---|
| 1353 | return QApplication::font();
|
---|
| 1354 | }
|
---|
| 1355 |
|
---|
| 1356 | /*! \obsolete
|
---|
| 1357 |
|
---|
| 1358 | Please use QApplication::setFont() instead.
|
---|
| 1359 | */
|
---|
| 1360 | void QFont::setDefaultFont( const QFont &f )
|
---|
| 1361 | {
|
---|
| 1362 | QApplication::setFont( f );
|
---|
| 1363 | }
|
---|
| 1364 |
|
---|
| 1365 |
|
---|
| 1366 | #endif
|
---|
| 1367 |
|
---|
| 1368 |
|
---|
| 1369 |
|
---|
| 1370 |
|
---|
| 1371 | #ifndef QT_NO_STRINGLIST
|
---|
| 1372 |
|
---|
| 1373 | /*****************************************************************************
|
---|
| 1374 | QFont substitution management
|
---|
| 1375 | *****************************************************************************/
|
---|
| 1376 |
|
---|
| 1377 | typedef QDict<QStringList> QFontSubst;
|
---|
| 1378 | static QFontSubst *fontSubst = 0;
|
---|
| 1379 | static QSingleCleanupHandler<QFontSubst> qfont_cleanup_fontsubst;
|
---|
| 1380 |
|
---|
| 1381 |
|
---|
| 1382 | // create substitution dict
|
---|
| 1383 | static void initFontSubst()
|
---|
| 1384 | {
|
---|
| 1385 | // default substitutions
|
---|
| 1386 | static const char *initTbl[] = {
|
---|
| 1387 |
|
---|
| 1388 | #if defined(Q_WS_X11)
|
---|
| 1389 | "arial", "helvetica",
|
---|
| 1390 | "helv", "helvetica",
|
---|
| 1391 | "tms rmn", "times",
|
---|
| 1392 | #elif defined(Q_WS_WIN)
|
---|
| 1393 | "times", "Times New Roman",
|
---|
| 1394 | "courier", "Courier New",
|
---|
| 1395 | "helvetica", "Arial",
|
---|
[8] | 1396 | #elif defined(Q_WS_PM)
|
---|
| 1397 | "times", "Times New Roman",
|
---|
[2] | 1398 | #endif
|
---|
| 1399 | 0, 0
|
---|
| 1400 | };
|
---|
| 1401 |
|
---|
| 1402 | if (fontSubst)
|
---|
| 1403 | return;
|
---|
| 1404 |
|
---|
| 1405 | fontSubst = new QFontSubst(17, FALSE);
|
---|
| 1406 | Q_CHECK_PTR( fontSubst );
|
---|
| 1407 | fontSubst->setAutoDelete( TRUE );
|
---|
| 1408 | qfont_cleanup_fontsubst.set(&fontSubst);
|
---|
| 1409 |
|
---|
| 1410 | for ( int i=0; initTbl[i] != 0; i += 2 )
|
---|
| 1411 | QFont::insertSubstitution(QString::fromLatin1(initTbl[i]),
|
---|
| 1412 | QString::fromLatin1(initTbl[i+1]));
|
---|
| 1413 | }
|
---|
| 1414 |
|
---|
| 1415 |
|
---|
| 1416 | /*!
|
---|
| 1417 | Returns the first family name to be used whenever \a familyName is
|
---|
| 1418 | specified. The lookup is case insensitive.
|
---|
| 1419 |
|
---|
| 1420 | If there is no substitution for \a familyName, \a familyName is
|
---|
| 1421 | returned.
|
---|
| 1422 |
|
---|
| 1423 | To obtain a list of substitutions use substitutes().
|
---|
| 1424 |
|
---|
| 1425 | \sa setFamily() insertSubstitutions() insertSubstitution() removeSubstitution()
|
---|
| 1426 | */
|
---|
| 1427 | QString QFont::substitute( const QString &familyName )
|
---|
| 1428 | {
|
---|
| 1429 | initFontSubst();
|
---|
| 1430 |
|
---|
| 1431 | QStringList *list = fontSubst->find(familyName);
|
---|
| 1432 | if (list && list->count() > 0)
|
---|
| 1433 | return *(list->at(0));
|
---|
| 1434 |
|
---|
| 1435 | return familyName;
|
---|
| 1436 | }
|
---|
| 1437 |
|
---|
| 1438 |
|
---|
| 1439 | /*!
|
---|
| 1440 | Returns a list of family names to be used whenever \a familyName
|
---|
| 1441 | is specified. The lookup is case insensitive.
|
---|
| 1442 |
|
---|
| 1443 | If there is no substitution for \a familyName, an empty list is
|
---|
| 1444 | returned.
|
---|
| 1445 |
|
---|
| 1446 | \sa substitute() insertSubstitutions() insertSubstitution() removeSubstitution()
|
---|
| 1447 | */
|
---|
| 1448 | QStringList QFont::substitutes(const QString &familyName)
|
---|
| 1449 | {
|
---|
| 1450 | initFontSubst();
|
---|
| 1451 |
|
---|
| 1452 | QStringList ret, *list = fontSubst->find(familyName);
|
---|
| 1453 | if (list)
|
---|
| 1454 | ret += *list;
|
---|
| 1455 | return ret;
|
---|
| 1456 | }
|
---|
| 1457 |
|
---|
| 1458 |
|
---|
| 1459 | /*!
|
---|
| 1460 | Inserts the family name \a substituteName into the substitution
|
---|
| 1461 | table for \a familyName.
|
---|
| 1462 |
|
---|
| 1463 | \sa insertSubstitutions() removeSubstitution() substitutions() substitute() substitutes()
|
---|
| 1464 | */
|
---|
| 1465 | void QFont::insertSubstitution(const QString &familyName,
|
---|
| 1466 | const QString &substituteName)
|
---|
| 1467 | {
|
---|
| 1468 | initFontSubst();
|
---|
| 1469 |
|
---|
| 1470 | QStringList *list = fontSubst->find(familyName);
|
---|
| 1471 | if (! list) {
|
---|
| 1472 | list = new QStringList;
|
---|
| 1473 | fontSubst->insert(familyName, list);
|
---|
| 1474 | }
|
---|
| 1475 |
|
---|
| 1476 | if (! list->contains(substituteName))
|
---|
| 1477 | list->append(substituteName);
|
---|
| 1478 | }
|
---|
| 1479 |
|
---|
| 1480 |
|
---|
| 1481 | /*!
|
---|
| 1482 | Inserts the list of families \a substituteNames into the
|
---|
| 1483 | substitution list for \a familyName.
|
---|
| 1484 |
|
---|
| 1485 | \sa insertSubstitution(), removeSubstitution(), substitutions(), substitute()
|
---|
| 1486 | */
|
---|
| 1487 | void QFont::insertSubstitutions(const QString &familyName,
|
---|
| 1488 | const QStringList &substituteNames)
|
---|
| 1489 | {
|
---|
| 1490 | initFontSubst();
|
---|
| 1491 |
|
---|
| 1492 | QStringList *list = fontSubst->find(familyName);
|
---|
| 1493 | if (! list) {
|
---|
| 1494 | list = new QStringList;
|
---|
| 1495 | fontSubst->insert(familyName, list);
|
---|
| 1496 | }
|
---|
| 1497 |
|
---|
| 1498 | QStringList::ConstIterator it = substituteNames.begin();
|
---|
| 1499 | while (it != substituteNames.end()) {
|
---|
| 1500 | if (! list->contains(*it))
|
---|
| 1501 | list->append(*it);
|
---|
| 1502 | it++;
|
---|
| 1503 | }
|
---|
| 1504 | }
|
---|
| 1505 |
|
---|
| 1506 | // ### mark: should be called removeSubstitutions()
|
---|
| 1507 | /*!
|
---|
| 1508 | Removes all the substitutions for \a familyName.
|
---|
| 1509 |
|
---|
| 1510 | \sa insertSubstitutions(), insertSubstitution(), substitutions(), substitute()
|
---|
| 1511 | */
|
---|
| 1512 | void QFont::removeSubstitution( const QString &familyName )
|
---|
| 1513 | { // ### function name should be removeSubstitutions() or
|
---|
| 1514 | // ### removeSubstitutionList()
|
---|
| 1515 | initFontSubst();
|
---|
| 1516 |
|
---|
| 1517 | fontSubst->remove(familyName);
|
---|
| 1518 | }
|
---|
| 1519 |
|
---|
| 1520 |
|
---|
| 1521 | /*!
|
---|
| 1522 | Returns a sorted list of substituted family names.
|
---|
| 1523 |
|
---|
| 1524 | \sa insertSubstitution(), removeSubstitution(), substitute()
|
---|
| 1525 | */
|
---|
| 1526 | QStringList QFont::substitutions()
|
---|
| 1527 | {
|
---|
| 1528 | initFontSubst();
|
---|
| 1529 |
|
---|
| 1530 | QStringList ret;
|
---|
| 1531 | QDictIterator<QStringList> it(*fontSubst);
|
---|
| 1532 |
|
---|
| 1533 | while (it.current()) {
|
---|
| 1534 | ret.append(it.currentKey());
|
---|
| 1535 | ++it;
|
---|
| 1536 | }
|
---|
| 1537 |
|
---|
| 1538 | ret.sort();
|
---|
| 1539 |
|
---|
| 1540 | return ret;
|
---|
| 1541 | }
|
---|
| 1542 |
|
---|
| 1543 | #endif // QT_NO_STRINGLIST
|
---|
| 1544 |
|
---|
| 1545 |
|
---|
| 1546 | /* \internal
|
---|
| 1547 | Internal function. Converts boolean font settings to an unsigned
|
---|
| 1548 | 8-bit number. Used for serialization etc.
|
---|
| 1549 | */
|
---|
| 1550 | static Q_UINT8 get_font_bits( const QFontPrivate *f )
|
---|
| 1551 | {
|
---|
| 1552 | #ifdef QT_CHECK_STATE
|
---|
| 1553 | Q_ASSERT( f != 0 );
|
---|
| 1554 | #endif
|
---|
| 1555 |
|
---|
| 1556 | Q_UINT8 bits = 0;
|
---|
| 1557 | if ( f->request.italic )
|
---|
| 1558 | bits |= 0x01;
|
---|
| 1559 | if ( f->underline )
|
---|
| 1560 | bits |= 0x02;
|
---|
| 1561 | if ( f->overline )
|
---|
| 1562 | bits |= 0x40;
|
---|
| 1563 | if ( f->strikeOut )
|
---|
| 1564 | bits |= 0x04;
|
---|
| 1565 | if ( f->request.fixedPitch )
|
---|
| 1566 | bits |= 0x08;
|
---|
| 1567 | // if ( f.hintSetByUser )
|
---|
| 1568 | // bits |= 0x10;
|
---|
| 1569 | if ( f->rawMode )
|
---|
| 1570 | bits |= 0x20;
|
---|
| 1571 | return bits;
|
---|
| 1572 | }
|
---|
| 1573 |
|
---|
| 1574 |
|
---|
| 1575 | #ifndef QT_NO_DATASTREAM
|
---|
| 1576 |
|
---|
| 1577 | /* \internal
|
---|
| 1578 | Internal function. Sets boolean font settings from an unsigned
|
---|
| 1579 | 8-bit number. Used for serialization etc.
|
---|
| 1580 | */
|
---|
| 1581 | static void set_font_bits( Q_UINT8 bits, QFontPrivate *f )
|
---|
| 1582 | {
|
---|
| 1583 | #ifdef QT_CHECK_STATE
|
---|
| 1584 | Q_ASSERT( f != 0 );
|
---|
| 1585 | #endif
|
---|
| 1586 |
|
---|
| 1587 | f->request.italic = (bits & 0x01) != 0;
|
---|
| 1588 | f->underline = (bits & 0x02) != 0;
|
---|
| 1589 | f->overline = (bits & 0x40) != 0;
|
---|
| 1590 | f->strikeOut = (bits & 0x04) != 0;
|
---|
| 1591 | f->request.fixedPitch = (bits & 0x08) != 0;
|
---|
| 1592 | // f->hintSetByUser = (bits & 0x10) != 0;
|
---|
| 1593 | f->rawMode = (bits & 0x20) != 0;
|
---|
| 1594 | }
|
---|
| 1595 |
|
---|
| 1596 | #endif
|
---|
| 1597 |
|
---|
| 1598 |
|
---|
| 1599 | /*!
|
---|
| 1600 | Returns the font's key, a textual representation of a font. It is
|
---|
| 1601 | typically used as the key for a cache or dictionary of fonts.
|
---|
| 1602 |
|
---|
| 1603 | \sa QMap
|
---|
| 1604 | */
|
---|
| 1605 | QString QFont::key() const
|
---|
| 1606 | {
|
---|
| 1607 | return toString();
|
---|
| 1608 | }
|
---|
| 1609 |
|
---|
| 1610 | /*!
|
---|
| 1611 | Returns a description of the font. The description is a
|
---|
| 1612 | comma-separated list of the attributes, perfectly suited for use
|
---|
| 1613 | in QSettings.
|
---|
| 1614 |
|
---|
| 1615 | \sa fromString() operator<<()
|
---|
| 1616 | */
|
---|
| 1617 | QString QFont::toString() const
|
---|
| 1618 | {
|
---|
| 1619 | const QChar comma( ',' );
|
---|
| 1620 | return family() + comma +
|
---|
| 1621 | QString::number( pointSizeFloat() ) + comma +
|
---|
| 1622 | QString::number( pixelSize() ) + comma +
|
---|
| 1623 | QString::number( (int) styleHint() ) + comma +
|
---|
| 1624 | QString::number( weight() ) + comma +
|
---|
| 1625 | QString::number( (int) italic() ) + comma +
|
---|
| 1626 | QString::number( (int) underline() ) + comma +
|
---|
| 1627 | QString::number( (int) strikeOut() ) + comma +
|
---|
| 1628 | QString::number( (int)fixedPitch() ) + comma +
|
---|
| 1629 | QString::number( (int) rawMode() );
|
---|
| 1630 | }
|
---|
| 1631 |
|
---|
| 1632 |
|
---|
| 1633 | /*!
|
---|
| 1634 | Sets this font to match the description \a descrip. The description
|
---|
| 1635 | is a comma-separated list of the font attributes, as returned by
|
---|
| 1636 | toString().
|
---|
| 1637 |
|
---|
| 1638 | \sa toString() operator>>()
|
---|
| 1639 | */
|
---|
| 1640 | bool QFont::fromString(const QString &descrip)
|
---|
| 1641 | {
|
---|
| 1642 | #ifndef QT_NO_STRINGLIST
|
---|
| 1643 | QStringList l(QStringList::split(',', descrip));
|
---|
| 1644 |
|
---|
| 1645 | int count = l.count();
|
---|
| 1646 | #else
|
---|
| 1647 | int count = 0;
|
---|
| 1648 | QString l[11];
|
---|
| 1649 | int from = 0;
|
---|
| 1650 | int to = descrip.find( ',' );
|
---|
| 1651 | while ( to > 0 && count < 11 ) {
|
---|
| 1652 | l[count] = descrip.mid( from, to-from );
|
---|
| 1653 | count++;
|
---|
| 1654 | from = to+1;
|
---|
| 1655 | to = descrip.find( ',', from );
|
---|
| 1656 | }
|
---|
| 1657 | #endif // QT_NO_STRINGLIST
|
---|
| 1658 | if ( !count || ( count > 2 && count < 9 ) || count > 11 ) {
|
---|
| 1659 |
|
---|
| 1660 | #ifdef QT_CHECK_STATE
|
---|
| 1661 | qWarning("QFont::fromString: invalid description '%s'", descrip.latin1());
|
---|
| 1662 | #endif
|
---|
| 1663 |
|
---|
| 1664 | return FALSE;
|
---|
| 1665 | }
|
---|
| 1666 |
|
---|
| 1667 | setFamily(l[0]);
|
---|
| 1668 | if ( count > 1 && l[1].toDouble() > 0.0 )
|
---|
| 1669 | setPointSizeFloat(l[1].toDouble());
|
---|
| 1670 | if ( count == 9 ) {
|
---|
| 1671 | setStyleHint((StyleHint) l[2].toInt());
|
---|
| 1672 | setWeight(l[3].toInt());
|
---|
| 1673 | setItalic(l[4].toInt());
|
---|
| 1674 | setUnderline(l[5].toInt());
|
---|
| 1675 | setStrikeOut(l[6].toInt());
|
---|
| 1676 | setFixedPitch(l[7].toInt());
|
---|
| 1677 | setRawMode(l[8].toInt());
|
---|
| 1678 | } else if ( count == 10 ) {
|
---|
| 1679 | if ( l[2].toInt() > 0 )
|
---|
| 1680 | setPixelSize( l[2].toInt() );
|
---|
| 1681 | setStyleHint((StyleHint) l[3].toInt());
|
---|
| 1682 | setWeight(l[4].toInt());
|
---|
| 1683 | setItalic(l[5].toInt());
|
---|
| 1684 | setUnderline(l[6].toInt());
|
---|
| 1685 | setStrikeOut(l[7].toInt());
|
---|
| 1686 | setFixedPitch(l[8].toInt());
|
---|
| 1687 | setRawMode(l[9].toInt());
|
---|
| 1688 | }
|
---|
| 1689 |
|
---|
| 1690 | return TRUE;
|
---|
| 1691 | }
|
---|
| 1692 |
|
---|
| 1693 | #if !defined( Q_WS_QWS )
|
---|
| 1694 | /*! \internal
|
---|
| 1695 |
|
---|
| 1696 | Internal function that dumps font cache statistics.
|
---|
| 1697 | */
|
---|
| 1698 | void QFont::cacheStatistics()
|
---|
| 1699 | {
|
---|
| 1700 |
|
---|
| 1701 |
|
---|
| 1702 | }
|
---|
| 1703 | #endif // !Q_WS_QWS
|
---|
| 1704 |
|
---|
| 1705 |
|
---|
| 1706 |
|
---|
| 1707 | /*****************************************************************************
|
---|
| 1708 | QFont stream functions
|
---|
| 1709 | *****************************************************************************/
|
---|
| 1710 | #ifndef QT_NO_DATASTREAM
|
---|
| 1711 |
|
---|
| 1712 | /*!
|
---|
| 1713 | \relates QFont
|
---|
| 1714 |
|
---|
| 1715 | Writes the font \a font to the data stream \a s. (toString()
|
---|
| 1716 | writes to a text stream.)
|
---|
| 1717 |
|
---|
| 1718 | \sa \link datastreamformat.html Format of the QDataStream operators \endlink
|
---|
| 1719 | */
|
---|
| 1720 | QDataStream &operator<<( QDataStream &s, const QFont &font )
|
---|
| 1721 | {
|
---|
| 1722 | if ( s.version() == 1 ) {
|
---|
| 1723 | QCString fam( font.d->request.family.latin1() );
|
---|
| 1724 | s << fam;
|
---|
| 1725 | } else {
|
---|
| 1726 | s << font.d->request.family;
|
---|
| 1727 | }
|
---|
| 1728 |
|
---|
| 1729 | if ( s.version() <= 3 ) {
|
---|
| 1730 | Q_INT16 pointSize = (Q_INT16) font.d->request.pointSize;
|
---|
| 1731 | if ( pointSize == -1 ) {
|
---|
| 1732 | #ifdef Q_WS_X11
|
---|
| 1733 | pointSize = (Q_INT16)(font.d->request.pixelSize*720/QPaintDevice::x11AppDpiY());
|
---|
| 1734 | #else
|
---|
| 1735 | pointSize = (Q_INT16)QFontInfo( font ).pointSize() * 10;
|
---|
| 1736 | #endif
|
---|
| 1737 | }
|
---|
| 1738 | s << pointSize;
|
---|
| 1739 | } else {
|
---|
| 1740 | s << (Q_INT16) font.d->request.pointSize;
|
---|
| 1741 | s << (Q_INT16) font.d->request.pixelSize;
|
---|
| 1742 | }
|
---|
| 1743 |
|
---|
| 1744 | s << (Q_UINT8) font.d->request.styleHint;
|
---|
| 1745 | if ( s.version() >= 5 )
|
---|
| 1746 | s << (Q_UINT8 ) font.d->request.styleStrategy;
|
---|
| 1747 | return s << (Q_UINT8) 0
|
---|
| 1748 | << (Q_UINT8) font.d->request.weight
|
---|
| 1749 | << get_font_bits(font.d);
|
---|
| 1750 | }
|
---|
| 1751 |
|
---|
| 1752 |
|
---|
| 1753 | /*!
|
---|
| 1754 | \relates QFont
|
---|
| 1755 |
|
---|
| 1756 | Reads the font \a font from the data stream \a s. (fromString()
|
---|
| 1757 | reads from a text stream.)
|
---|
| 1758 |
|
---|
| 1759 | \sa \link datastreamformat.html Format of the QDataStream operators \endlink
|
---|
| 1760 | */
|
---|
| 1761 | QDataStream &operator>>( QDataStream &s, QFont &font )
|
---|
| 1762 | {
|
---|
| 1763 | if (font.d->deref()) delete font.d;
|
---|
| 1764 |
|
---|
| 1765 | font.d = new QFontPrivate;
|
---|
| 1766 | font.d->mask = QFontPrivate::Complete;
|
---|
| 1767 |
|
---|
| 1768 | Q_INT16 pointSize, pixelSize = -1;
|
---|
| 1769 | Q_UINT8 styleHint, styleStrategy = QFont::PreferDefault, charSet, weight, bits;
|
---|
| 1770 |
|
---|
| 1771 | if ( s.version() == 1 ) {
|
---|
| 1772 | QCString fam;
|
---|
| 1773 | s >> fam;
|
---|
| 1774 | font.d->request.family = QString( fam );
|
---|
| 1775 | } else {
|
---|
| 1776 | s >> font.d->request.family;
|
---|
| 1777 | }
|
---|
| 1778 |
|
---|
| 1779 | s >> pointSize;
|
---|
| 1780 | if ( s.version() >= 4 )
|
---|
| 1781 | s >> pixelSize;
|
---|
| 1782 | s >> styleHint;
|
---|
| 1783 | if ( s.version() >= 5 )
|
---|
| 1784 | s >> styleStrategy;
|
---|
| 1785 | s >> charSet;
|
---|
| 1786 | s >> weight;
|
---|
| 1787 | s >> bits;
|
---|
| 1788 |
|
---|
| 1789 | font.d->request.pointSize = pointSize;
|
---|
| 1790 | font.d->request.pixelSize = pixelSize;
|
---|
| 1791 | font.d->request.styleHint = styleHint;
|
---|
| 1792 | font.d->request.styleStrategy = styleStrategy;
|
---|
| 1793 | font.d->request.weight = weight;
|
---|
| 1794 |
|
---|
| 1795 | set_font_bits( bits, font.d );
|
---|
| 1796 |
|
---|
| 1797 | return s;
|
---|
| 1798 | }
|
---|
| 1799 |
|
---|
| 1800 | #endif // QT_NO_DATASTREAM
|
---|
| 1801 |
|
---|
| 1802 |
|
---|
| 1803 |
|
---|
| 1804 |
|
---|
| 1805 | /*****************************************************************************
|
---|
| 1806 | QFontMetrics member functions
|
---|
| 1807 | *****************************************************************************/
|
---|
| 1808 |
|
---|
| 1809 | /*!
|
---|
| 1810 | \class QFontMetrics qfontmetrics.h
|
---|
| 1811 | \brief The QFontMetrics class provides font metrics information.
|
---|
| 1812 |
|
---|
| 1813 | \ingroup graphics
|
---|
| 1814 | \ingroup shared
|
---|
| 1815 |
|
---|
| 1816 | QFontMetrics functions calculate the size of characters and
|
---|
| 1817 | strings for a given font. There are three ways you can create a
|
---|
| 1818 | QFontMetrics object:
|
---|
| 1819 |
|
---|
| 1820 | \list 1
|
---|
| 1821 | \i Calling the QFontMetrics constructor with a QFont creates a
|
---|
| 1822 | font metrics object for a screen-compatible font, i.e. the font
|
---|
| 1823 | cannot be a printer font<sup>*</sup>. If the font is changed
|
---|
| 1824 | later, the font metrics object is \e not updated.
|
---|
| 1825 |
|
---|
| 1826 | \i QWidget::fontMetrics() returns the font metrics for a widget's
|
---|
| 1827 | font. This is equivalent to QFontMetrics(widget->font()). If the
|
---|
| 1828 | widget's font is changed later, the font metrics object is \e not
|
---|
| 1829 | updated.
|
---|
| 1830 |
|
---|
| 1831 | \i QPainter::fontMetrics() returns the font metrics for a
|
---|
| 1832 | painter's current font. If the painter's font is changed later, the
|
---|
| 1833 | font metrics object is \e not updated.
|
---|
| 1834 | \endlist
|
---|
| 1835 |
|
---|
| 1836 | <sup>*</sup> If you use a printer font the values returned may be
|
---|
| 1837 | inaccurate. Printer fonts are not always accessible so the nearest
|
---|
| 1838 | screen font is used if a printer font is supplied.
|
---|
| 1839 |
|
---|
| 1840 | Once created, the object provides functions to access the
|
---|
| 1841 | individual metrics of the font, its characters, and for strings
|
---|
| 1842 | rendered in the font.
|
---|
| 1843 |
|
---|
| 1844 | There are several functions that operate on the font: ascent(),
|
---|
| 1845 | descent(), height(), leading() and lineSpacing() return the basic
|
---|
| 1846 | size properties of the font. The underlinePos(), overlinePos(),
|
---|
| 1847 | strikeOutPos() and lineWidth() functions, return the properties of
|
---|
| 1848 | the line that underlines, overlines or strikes out the
|
---|
| 1849 | characters. These functions are all fast.
|
---|
| 1850 |
|
---|
| 1851 | There are also some functions that operate on the set of glyphs in
|
---|
| 1852 | the font: minLeftBearing(), minRightBearing() and maxWidth().
|
---|
| 1853 | These are by necessity slow, and we recommend avoiding them if
|
---|
| 1854 | possible.
|
---|
| 1855 |
|
---|
| 1856 | For each character, you can get its width(), leftBearing() and
|
---|
| 1857 | rightBearing() and find out whether it is in the font using
|
---|
| 1858 | inFont(). You can also treat the character as a string, and use
|
---|
| 1859 | the string functions on it.
|
---|
| 1860 |
|
---|
| 1861 | The string functions include width(), to return the width of a
|
---|
| 1862 | string in pixels (or points, for a printer), boundingRect(), to
|
---|
| 1863 | return a rectangle large enough to contain the rendered string,
|
---|
| 1864 | and size(), to return the size of that rectangle.
|
---|
| 1865 |
|
---|
| 1866 | Example:
|
---|
| 1867 | \code
|
---|
| 1868 | QFont font( "times", 24 );
|
---|
| 1869 | QFontMetrics fm( font );
|
---|
| 1870 | int pixelsWide = fm.width( "What's the width of this text?" );
|
---|
| 1871 | int pixelsHigh = fm.height();
|
---|
| 1872 | \endcode
|
---|
| 1873 |
|
---|
| 1874 | \sa QFont QFontInfo QFontDatabase
|
---|
| 1875 | */
|
---|
| 1876 |
|
---|
| 1877 | /*!
|
---|
| 1878 | Constructs a font metrics object for \a font.
|
---|
| 1879 |
|
---|
| 1880 | The font must be screen-compatible, i.e. a font you use when
|
---|
| 1881 | drawing text in \link QWidget widgets\endlink or \link QPixmap
|
---|
| 1882 | pixmaps\endlink, not QPicture or QPrinter.
|
---|
| 1883 |
|
---|
| 1884 | The font metrics object holds the information for the font that is
|
---|
| 1885 | passed in the constructor at the time it is created, and is not
|
---|
| 1886 | updated if the font's attributes are changed later.
|
---|
| 1887 |
|
---|
| 1888 | Use QPainter::fontMetrics() to get the font metrics when painting.
|
---|
| 1889 | This will give correct results also when painting on paint device
|
---|
| 1890 | that is not screen-compatible.
|
---|
| 1891 | */
|
---|
| 1892 | QFontMetrics::QFontMetrics( const QFont &font )
|
---|
| 1893 | : d( font.d ), painter( 0 ), fscript( QFont::NoScript )
|
---|
| 1894 | {
|
---|
| 1895 | d->ref();
|
---|
| 1896 | }
|
---|
| 1897 |
|
---|
| 1898 | /*!
|
---|
| 1899 | \overload
|
---|
| 1900 |
|
---|
| 1901 | Constructs a font metrics object for \a font using the given \a
|
---|
| 1902 | script.
|
---|
| 1903 | */
|
---|
| 1904 | QFontMetrics::QFontMetrics( const QFont &font, QFont::Script script )
|
---|
| 1905 | : d( font.d ), painter( 0 ), fscript( script )
|
---|
| 1906 | {
|
---|
| 1907 | d->ref();
|
---|
| 1908 | }
|
---|
| 1909 |
|
---|
| 1910 | /*! \internal
|
---|
| 1911 |
|
---|
| 1912 | Constructs a font metrics object for the painter's font \a p.
|
---|
| 1913 | */
|
---|
| 1914 | QFontMetrics::QFontMetrics( const QPainter *p )
|
---|
| 1915 | : painter ( (QPainter *) p ), fscript( QFont::NoScript )
|
---|
| 1916 | {
|
---|
| 1917 | #if defined(CHECK_STATE)
|
---|
| 1918 | if ( !painter->isActive() )
|
---|
| 1919 | qWarning( "QFontMetrics: Get font metrics between QPainter::begin() "
|
---|
| 1920 | "and QPainter::end()" );
|
---|
| 1921 | #endif
|
---|
| 1922 |
|
---|
| 1923 | if ( painter->testf(QPainter::DirtyFont) )
|
---|
| 1924 | painter->updateFont();
|
---|
| 1925 |
|
---|
| 1926 | d = painter->pfont ? painter->pfont->d : painter->cfont.d;
|
---|
| 1927 |
|
---|
| 1928 | #if defined(Q_WS_X11)
|
---|
| 1929 | if ( d->screen != p->scrn ) {
|
---|
| 1930 | QFontPrivate *new_d = new QFontPrivate( *d );
|
---|
| 1931 | Q_CHECK_PTR( new_d );
|
---|
| 1932 | d = new_d;
|
---|
| 1933 | d->screen = p->scrn;
|
---|
| 1934 | d->count = 1;
|
---|
| 1935 | } else
|
---|
| 1936 | #endif // Q_WS_X11
|
---|
| 1937 | d->ref();
|
---|
| 1938 | }
|
---|
| 1939 |
|
---|
| 1940 | /*!
|
---|
| 1941 | Constructs a copy of \a fm.
|
---|
| 1942 | */
|
---|
| 1943 | QFontMetrics::QFontMetrics( const QFontMetrics &fm )
|
---|
| 1944 | : d( fm.d ), painter( 0 ), fscript( fm.fscript )
|
---|
| 1945 | {
|
---|
| 1946 | d->ref();
|
---|
| 1947 | }
|
---|
| 1948 |
|
---|
| 1949 | /*!
|
---|
| 1950 | Destroys the font metrics object and frees all allocated
|
---|
| 1951 | resources.
|
---|
| 1952 | */
|
---|
| 1953 | QFontMetrics::~QFontMetrics()
|
---|
| 1954 | {
|
---|
| 1955 | if ( d->deref() )
|
---|
| 1956 | delete d;
|
---|
| 1957 | }
|
---|
| 1958 |
|
---|
| 1959 | /*!
|
---|
| 1960 | Assigns the font metrics \a fm.
|
---|
| 1961 | */
|
---|
| 1962 | QFontMetrics &QFontMetrics::operator=( const QFontMetrics &fm )
|
---|
| 1963 | {
|
---|
| 1964 | if ( d != fm.d ) {
|
---|
| 1965 | if ( d->deref() )
|
---|
| 1966 | delete d;
|
---|
| 1967 | d = fm.d;
|
---|
| 1968 | d->ref();
|
---|
| 1969 | }
|
---|
| 1970 | painter = fm.painter;
|
---|
| 1971 | return *this;
|
---|
| 1972 | }
|
---|
| 1973 |
|
---|
| 1974 | /*!
|
---|
| 1975 | Returns the ascent of the font.
|
---|
| 1976 |
|
---|
| 1977 | The ascent of a font is the distance from the baseline to the
|
---|
| 1978 | highest position characters extend to. In practice, some font
|
---|
| 1979 | designers break this rule, e.g. when they put more than one accent
|
---|
| 1980 | on top of a character, or to accommodate an unusual character in
|
---|
| 1981 | an exotic language, so it is possible (though rare) that this
|
---|
| 1982 | value will be too small.
|
---|
| 1983 |
|
---|
| 1984 | \sa descent()
|
---|
| 1985 | */
|
---|
| 1986 | int QFontMetrics::ascent() const
|
---|
| 1987 | {
|
---|
| 1988 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 1989 | QFontEngine *latin_engine = d->engineForScript( QFont::Latin );
|
---|
| 1990 | #ifdef QT_CHECK_STATE
|
---|
| 1991 | Q_ASSERT( engine != 0 );
|
---|
| 1992 | Q_ASSERT( latin_engine != 0 );
|
---|
| 1993 | #endif // QT_CHECK_STATE
|
---|
| 1994 |
|
---|
| 1995 | return QMAX(engine->ascent(), latin_engine->ascent());
|
---|
| 1996 | }
|
---|
| 1997 |
|
---|
| 1998 |
|
---|
| 1999 | /*!
|
---|
| 2000 | Returns the descent of the font.
|
---|
| 2001 |
|
---|
| 2002 | The descent is the distance from the base line to the lowest point
|
---|
| 2003 | characters extend to. (Note that this is different from X, which
|
---|
| 2004 | adds 1 pixel.) In practice, some font designers break this rule,
|
---|
| 2005 | e.g. to accommodate an unusual character in an exotic language, so
|
---|
| 2006 | it is possible (though rare) that this value will be too small.
|
---|
| 2007 |
|
---|
| 2008 | \sa ascent()
|
---|
| 2009 | */
|
---|
| 2010 | int QFontMetrics::descent() const
|
---|
| 2011 | {
|
---|
| 2012 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2013 | QFontEngine *latin_engine = d->engineForScript( QFont::Latin );
|
---|
| 2014 | #ifdef QT_CHECK_STATE
|
---|
| 2015 | Q_ASSERT( engine != 0 );
|
---|
| 2016 | Q_ASSERT( latin_engine != 0 );
|
---|
| 2017 | #endif // QT_CHECK_STATE
|
---|
| 2018 |
|
---|
| 2019 | return QMAX(engine->descent(), latin_engine->descent());
|
---|
| 2020 | }
|
---|
| 2021 |
|
---|
| 2022 | /*!
|
---|
| 2023 | Returns the height of the font.
|
---|
| 2024 |
|
---|
| 2025 | This is always equal to ascent()+descent()+1 (the 1 is for the
|
---|
| 2026 | base line).
|
---|
| 2027 |
|
---|
| 2028 | \sa leading(), lineSpacing()
|
---|
| 2029 | */
|
---|
| 2030 | int QFontMetrics::height() const
|
---|
| 2031 | {
|
---|
| 2032 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2033 | QFontEngine *latin_engine = d->engineForScript( QFont::Latin );
|
---|
| 2034 | #ifdef QT_CHECK_STATE
|
---|
| 2035 | Q_ASSERT( engine != 0 );
|
---|
| 2036 | Q_ASSERT( latin_engine != 0 );
|
---|
| 2037 | #endif // QT_CHECK_STATE
|
---|
| 2038 |
|
---|
| 2039 | return (QMAX(engine->ascent(), latin_engine->ascent()) +
|
---|
| 2040 | QMAX(engine->descent(), latin_engine->descent()) + 1);
|
---|
| 2041 | }
|
---|
| 2042 |
|
---|
| 2043 | /*!
|
---|
| 2044 | Returns the leading of the font.
|
---|
| 2045 |
|
---|
| 2046 | This is the natural inter-line spacing.
|
---|
| 2047 |
|
---|
| 2048 | \sa height(), lineSpacing()
|
---|
| 2049 | */
|
---|
| 2050 | int QFontMetrics::leading() const
|
---|
| 2051 | {
|
---|
| 2052 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2053 | QFontEngine *latin_engine = d->engineForScript( QFont::Latin );
|
---|
| 2054 | #ifdef QT_CHECK_STATE
|
---|
| 2055 | Q_ASSERT( engine != 0 );
|
---|
| 2056 | Q_ASSERT( latin_engine != 0 );
|
---|
| 2057 | #endif // QT_CHECK_STATE
|
---|
| 2058 |
|
---|
| 2059 | return QMAX(engine->leading(), latin_engine->leading());
|
---|
| 2060 | }
|
---|
| 2061 |
|
---|
| 2062 | /*!
|
---|
| 2063 | Returns the distance from one base line to the next.
|
---|
| 2064 |
|
---|
| 2065 | This value is always equal to leading()+height().
|
---|
| 2066 |
|
---|
| 2067 | \sa height(), leading()
|
---|
| 2068 | */
|
---|
| 2069 | int QFontMetrics::lineSpacing() const
|
---|
| 2070 | {
|
---|
| 2071 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2072 | QFontEngine *latin_engine = d->engineForScript( QFont::Latin );
|
---|
| 2073 | #ifdef QT_CHECK_STATE
|
---|
| 2074 | Q_ASSERT( engine != 0 );
|
---|
| 2075 | Q_ASSERT( latin_engine != 0 );
|
---|
| 2076 | #endif // QT_CHECK_STATE
|
---|
| 2077 |
|
---|
| 2078 | return (QMAX(engine->leading(), latin_engine->leading()) +
|
---|
| 2079 | QMAX(engine->ascent(), latin_engine->ascent()) +
|
---|
| 2080 | QMAX(engine->descent(), latin_engine->descent()) + 1);
|
---|
| 2081 | }
|
---|
| 2082 |
|
---|
| 2083 | /*!
|
---|
| 2084 | Returns the minimum left bearing of the font.
|
---|
| 2085 |
|
---|
| 2086 | This is the smallest leftBearing(char) of all characters in the
|
---|
| 2087 | font.
|
---|
| 2088 |
|
---|
| 2089 | Note that this function can be very slow if the font is large.
|
---|
| 2090 |
|
---|
| 2091 | \sa minRightBearing(), leftBearing()
|
---|
| 2092 | */
|
---|
| 2093 | int QFontMetrics::minLeftBearing() const
|
---|
| 2094 | {
|
---|
| 2095 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2096 | QFontEngine *latin_engine = d->engineForScript( QFont::Latin );
|
---|
| 2097 | #ifdef QT_CHECK_STATE
|
---|
| 2098 | Q_ASSERT( engine != 0 );
|
---|
| 2099 | Q_ASSERT( latin_engine != 0 );
|
---|
| 2100 | #endif // QT_CHECK_STATE
|
---|
| 2101 |
|
---|
| 2102 | return QMIN(engine->minLeftBearing(), latin_engine->minLeftBearing());
|
---|
| 2103 | }
|
---|
| 2104 |
|
---|
| 2105 | /*!
|
---|
| 2106 | Returns the minimum right bearing of the font.
|
---|
| 2107 |
|
---|
| 2108 | This is the smallest rightBearing(char) of all characters in the
|
---|
| 2109 | font.
|
---|
| 2110 |
|
---|
| 2111 | Note that this function can be very slow if the font is large.
|
---|
| 2112 |
|
---|
| 2113 | \sa minLeftBearing(), rightBearing()
|
---|
| 2114 | */
|
---|
| 2115 | int QFontMetrics::minRightBearing() const
|
---|
| 2116 | {
|
---|
| 2117 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2118 | QFontEngine *latin_engine = d->engineForScript( QFont::Latin );
|
---|
| 2119 | #ifdef QT_CHECK_STATE
|
---|
| 2120 | Q_ASSERT( engine != 0 );
|
---|
| 2121 | Q_ASSERT( latin_engine != 0 );
|
---|
| 2122 | #endif // QT_CHECK_STATE
|
---|
| 2123 |
|
---|
| 2124 | return QMIN(engine->minRightBearing(), latin_engine->minRightBearing());
|
---|
| 2125 | }
|
---|
| 2126 |
|
---|
| 2127 | /*!
|
---|
| 2128 | Returns the width of the widest character in the font.
|
---|
| 2129 | */
|
---|
| 2130 | int QFontMetrics::maxWidth() const
|
---|
| 2131 | {
|
---|
| 2132 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2133 | QFontEngine *lengine = d->engineForScript( QFont::Latin );
|
---|
| 2134 | #ifdef QT_CHECK_STATE
|
---|
| 2135 | Q_ASSERT( engine != 0 );
|
---|
| 2136 | Q_ASSERT( lengine != 0 );
|
---|
| 2137 | #endif // QT_CHECK_STATE
|
---|
| 2138 |
|
---|
| 2139 | return QMAX(engine->maxCharWidth(), lengine->maxCharWidth());
|
---|
| 2140 | }
|
---|
| 2141 |
|
---|
| 2142 | /*!
|
---|
| 2143 | Returns TRUE if character \a ch is a valid character in the font;
|
---|
| 2144 | otherwise returns FALSE.
|
---|
| 2145 | */
|
---|
| 2146 | bool QFontMetrics::inFont(QChar ch) const
|
---|
| 2147 | {
|
---|
| 2148 | QFont::Script script;
|
---|
| 2149 | SCRIPT_FOR_CHAR( script, ch );
|
---|
| 2150 |
|
---|
| 2151 | QFontEngine *engine = d->engineForScript( script );
|
---|
| 2152 | #ifdef QT_CHECK_STATE
|
---|
| 2153 | Q_ASSERT( engine != 0 );
|
---|
| 2154 | #endif // QT_CHECK_STATE
|
---|
| 2155 |
|
---|
| 2156 | if ( engine->type() == QFontEngine::Box ) return FALSE;
|
---|
| 2157 | return engine->canRender( &ch, 1 );
|
---|
| 2158 | }
|
---|
| 2159 |
|
---|
| 2160 | /*! \fn int QFontMetrics::leftBearing( QChar ch ) const
|
---|
| 2161 | Returns the left bearing of character \a ch in the font.
|
---|
| 2162 |
|
---|
| 2163 | The left bearing is the right-ward distance of the left-most pixel
|
---|
| 2164 | of the character from the logical origin of the character. This
|
---|
| 2165 | value is negative if the pixels of the character extend to the
|
---|
| 2166 | left of the logical origin.
|
---|
| 2167 |
|
---|
| 2168 | See width(QChar) for a graphical description of this metric.
|
---|
| 2169 |
|
---|
| 2170 | \sa rightBearing(), minLeftBearing(), width()
|
---|
| 2171 | */
|
---|
| 2172 | #if !defined(Q_WS_WIN) && !defined(Q_WS_QWS)
|
---|
| 2173 | int QFontMetrics::leftBearing(QChar ch) const
|
---|
| 2174 | {
|
---|
| 2175 | QFont::Script script;
|
---|
| 2176 | SCRIPT_FOR_CHAR( script, ch );
|
---|
| 2177 |
|
---|
| 2178 | QFontEngine *engine = d->engineForScript( script );
|
---|
| 2179 | #ifdef QT_CHECK_STATE
|
---|
| 2180 | Q_ASSERT( engine != 0 );
|
---|
| 2181 | #endif // QT_CHECK_STATE
|
---|
| 2182 |
|
---|
| 2183 | if ( engine->type() == QFontEngine::Box ) return 0;
|
---|
| 2184 |
|
---|
| 2185 | glyph_t glyphs[10];
|
---|
| 2186 | int nglyphs = 9;
|
---|
| 2187 | engine->stringToCMap( &ch, 1, glyphs, 0, &nglyphs, FALSE );
|
---|
| 2188 | // ### can nglyphs != 1 happen at all? Not currently I think
|
---|
| 2189 | glyph_metrics_t gi = engine->boundingBox( glyphs[0] );
|
---|
| 2190 | return gi.x;
|
---|
| 2191 | }
|
---|
| 2192 | #endif // !Q_WS_WIN
|
---|
| 2193 |
|
---|
| 2194 | /*! \fn int QFontMetrics::rightBearing(QChar ch) const
|
---|
| 2195 | Returns the right bearing of character \a ch in the font.
|
---|
| 2196 |
|
---|
| 2197 | The right bearing is the left-ward distance of the right-most
|
---|
| 2198 | pixel of the character from the logical origin of a subsequent
|
---|
| 2199 | character. This value is negative if the pixels of the character
|
---|
| 2200 | extend to the right of the width() of the character.
|
---|
| 2201 |
|
---|
| 2202 | See width() for a graphical description of this metric.
|
---|
| 2203 |
|
---|
| 2204 | \sa leftBearing(), minRightBearing(), width()
|
---|
| 2205 | */
|
---|
| 2206 | #if !defined(Q_WS_WIN) && !defined(Q_WS_QWS)
|
---|
| 2207 | int QFontMetrics::rightBearing(QChar ch) const
|
---|
| 2208 | {
|
---|
| 2209 | QFont::Script script;
|
---|
| 2210 | SCRIPT_FOR_CHAR( script, ch );
|
---|
| 2211 |
|
---|
| 2212 | QFontEngine *engine = d->engineForScript( script );
|
---|
| 2213 | #ifdef QT_CHECK_STATE
|
---|
| 2214 | Q_ASSERT( engine != 0 );
|
---|
| 2215 | #endif // QT_CHECK_STATE
|
---|
| 2216 |
|
---|
| 2217 | if ( engine->type() == QFontEngine::Box ) return 0;
|
---|
| 2218 |
|
---|
| 2219 | glyph_t glyphs[10];
|
---|
| 2220 | int nglyphs = 9;
|
---|
| 2221 | engine->stringToCMap( &ch, 1, glyphs, 0, &nglyphs, FALSE );
|
---|
| 2222 | // ### can nglyphs != 1 happen at all? Not currently I think
|
---|
| 2223 | glyph_metrics_t gi = engine->boundingBox( glyphs[0] );
|
---|
| 2224 | return gi.xoff - gi.x - gi.width;
|
---|
| 2225 | }
|
---|
| 2226 | #endif // !Q_WS_WIN
|
---|
| 2227 |
|
---|
| 2228 |
|
---|
| 2229 | #ifndef Q_WS_QWS
|
---|
| 2230 | /*!
|
---|
| 2231 | Returns the width in pixels of the first \a len characters of \a
|
---|
| 2232 | str. If \a len is negative (the default), the entire string is
|
---|
| 2233 | used.
|
---|
| 2234 |
|
---|
| 2235 | Note that this value is \e not equal to boundingRect().width();
|
---|
| 2236 | boundingRect() returns a rectangle describing the pixels this
|
---|
| 2237 | string will cover whereas width() returns the distance to where
|
---|
| 2238 | the next string should be drawn.
|
---|
| 2239 |
|
---|
| 2240 | \sa boundingRect()
|
---|
| 2241 | */
|
---|
| 2242 | int QFontMetrics::width( const QString &str, int len ) const
|
---|
| 2243 | {
|
---|
| 2244 | if (len < 0)
|
---|
| 2245 | len = str.length();
|
---|
| 2246 | if (len == 0)
|
---|
| 2247 | return 0;
|
---|
| 2248 |
|
---|
| 2249 | int pos = 0;
|
---|
| 2250 | int width = 0;
|
---|
| 2251 | #ifndef Q_WS_MAC
|
---|
| 2252 | const QChar *ch = str.unicode();
|
---|
| 2253 |
|
---|
| 2254 | while (pos < len) {
|
---|
| 2255 | unsigned short uc = ch->unicode();
|
---|
| 2256 | if (uc < QFontEngineData::widthCacheSize && d->engineData && d->engineData->widthCache[uc])
|
---|
| 2257 | width += d->engineData->widthCache[uc];
|
---|
| 2258 | else if ( ::category( *ch ) != QChar::Mark_NonSpacing ) {
|
---|
| 2259 | QFont::Script script;
|
---|
| 2260 | SCRIPT_FOR_CHAR( script, *ch );
|
---|
| 2261 |
|
---|
| 2262 | if (script >= QFont::Arabic && script <= QFont::Khmer)
|
---|
| 2263 | break;
|
---|
| 2264 |
|
---|
| 2265 | QFontEngine *engine = d->engineForScript( script );
|
---|
| 2266 | #ifdef QT_CHECK_STATE
|
---|
| 2267 | Q_ASSERT( engine != 0 );
|
---|
| 2268 | #endif // QT_CHECK_STATE
|
---|
| 2269 |
|
---|
| 2270 | glyph_t glyphs[8];
|
---|
| 2271 | advance_t advances[8];
|
---|
| 2272 | int nglyphs = 7;
|
---|
| 2273 | engine->stringToCMap( ch, 1, glyphs, advances, &nglyphs, FALSE );
|
---|
| 2274 |
|
---|
| 2275 | // ### can nglyphs != 1 happen at all? Not currently I think
|
---|
| 2276 | if ( uc < QFontEngineData::widthCacheSize && advances[0] < 0x100 )
|
---|
| 2277 | d->engineData->widthCache[ uc ] = advances[0];
|
---|
| 2278 | width += advances[0];
|
---|
| 2279 | }
|
---|
| 2280 | ++pos;
|
---|
| 2281 | ++ch;
|
---|
| 2282 | }
|
---|
| 2283 | if ( pos < len ) {
|
---|
| 2284 | #endif
|
---|
| 2285 | QTextEngine layout( str, d );
|
---|
| 2286 | layout.itemize( QTextEngine::WidthOnly );
|
---|
| 2287 | width += layout.width( pos, len-pos );
|
---|
| 2288 | #ifndef Q_WS_MAC
|
---|
| 2289 | }
|
---|
| 2290 | #endif
|
---|
| 2291 | return width;
|
---|
| 2292 | }
|
---|
| 2293 | #endif
|
---|
| 2294 |
|
---|
| 2295 | /*! \fn int QFontMetrics::width( QChar ch ) const
|
---|
| 2296 |
|
---|
| 2297 | <img src="bearings.png" align=right>
|
---|
| 2298 |
|
---|
| 2299 | Returns the logical width of character \a ch in pixels. This is a
|
---|
| 2300 | distance appropriate for drawing a subsequent character after \a
|
---|
| 2301 | ch.
|
---|
| 2302 |
|
---|
| 2303 | Some of the metrics are described in the image to the right. The
|
---|
| 2304 | central dark rectangles cover the logical width() of each
|
---|
| 2305 | character. The outer pale rectangles cover the leftBearing() and
|
---|
| 2306 | rightBearing() of each character. Notice that the bearings of "f"
|
---|
| 2307 | in this particular font are both negative, while the bearings of
|
---|
| 2308 | "o" are both positive.
|
---|
| 2309 |
|
---|
| 2310 | \warning This function will produce incorrect results for Arabic
|
---|
| 2311 | characters or non spacing marks in the middle of a string, as the
|
---|
| 2312 | glyph shaping and positioning of marks that happens when
|
---|
| 2313 | processing strings cannot be taken into account. Use charWidth()
|
---|
| 2314 | instead if you aren't looking for the width of isolated
|
---|
| 2315 | characters.
|
---|
| 2316 |
|
---|
| 2317 | \sa boundingRect(), charWidth()
|
---|
| 2318 | */
|
---|
| 2319 |
|
---|
| 2320 | /*! \fn int QFontMetrics::width( char c ) const
|
---|
| 2321 |
|
---|
| 2322 | \overload
|
---|
| 2323 | \obsolete
|
---|
| 2324 |
|
---|
| 2325 | Provided to aid porting from Qt 1.x.
|
---|
| 2326 | */
|
---|
| 2327 |
|
---|
| 2328 | /*! \fn int QFontMetrics::charWidth( const QString &str, int pos ) const
|
---|
| 2329 | Returns the width of the character at position \a pos in the
|
---|
| 2330 | string \a str.
|
---|
| 2331 |
|
---|
| 2332 | The whole string is needed, as the glyph drawn may change
|
---|
| 2333 | depending on the context (the letter before and after the current
|
---|
| 2334 | one) for some languages (e.g. Arabic).
|
---|
| 2335 |
|
---|
| 2336 | This function also takes non spacing marks and ligatures into
|
---|
| 2337 | account.
|
---|
| 2338 | */
|
---|
| 2339 |
|
---|
| 2340 | #ifndef Q_WS_QWS
|
---|
| 2341 | /*!
|
---|
| 2342 | Returns the bounding rectangle of the first \a len characters of
|
---|
| 2343 | \a str, which is the set of pixels the text would cover if drawn
|
---|
| 2344 | at (0, 0).
|
---|
| 2345 |
|
---|
| 2346 | If \a len is negative (the default), the entire string is used.
|
---|
| 2347 |
|
---|
| 2348 | Note that the bounding rectangle may extend to the left of (0, 0),
|
---|
| 2349 | e.g. for italicized fonts, and that the text output may cover \e
|
---|
| 2350 | all pixels in the bounding rectangle.
|
---|
| 2351 |
|
---|
| 2352 | Newline characters are processed as normal characters, \e not as
|
---|
| 2353 | linebreaks.
|
---|
| 2354 |
|
---|
| 2355 | Due to the different actual character heights, the height of the
|
---|
| 2356 | bounding rectangle of e.g. "Yes" and "yes" may be different.
|
---|
| 2357 |
|
---|
| 2358 | \sa width(), QPainter::boundingRect()
|
---|
| 2359 | */
|
---|
| 2360 | QRect QFontMetrics::boundingRect( const QString &str, int len ) const
|
---|
| 2361 | {
|
---|
| 2362 | if (len < 0)
|
---|
| 2363 | len = str.length();
|
---|
| 2364 | if (len == 0)
|
---|
| 2365 | return QRect();
|
---|
| 2366 |
|
---|
| 2367 | QTextEngine layout( str, d );
|
---|
| 2368 | layout.itemize( QTextEngine::NoBidi|QTextEngine::SingleLine );
|
---|
| 2369 | glyph_metrics_t gm = layout.boundingBox( 0, len );
|
---|
| 2370 | return QRect( gm.x, gm.y, gm.width, gm.height );
|
---|
| 2371 | }
|
---|
| 2372 | #endif
|
---|
| 2373 |
|
---|
| 2374 | /*!
|
---|
| 2375 | Returns the bounding rectangle of the character \a ch relative to
|
---|
| 2376 | the left-most point on the base line.
|
---|
| 2377 |
|
---|
| 2378 | Note that the bounding rectangle may extend to the left of (0, 0),
|
---|
| 2379 | e.g. for italicized fonts, and that the text output may cover \e
|
---|
| 2380 | all pixels in the bounding rectangle.
|
---|
| 2381 |
|
---|
| 2382 | Note that the rectangle usually extends both above and below the
|
---|
| 2383 | base line.
|
---|
| 2384 |
|
---|
| 2385 | \sa width()
|
---|
| 2386 | */
|
---|
| 2387 | QRect QFontMetrics::boundingRect( QChar ch ) const
|
---|
| 2388 | {
|
---|
| 2389 | QFont::Script script;
|
---|
| 2390 | SCRIPT_FOR_CHAR( script, ch );
|
---|
| 2391 |
|
---|
| 2392 | QFontEngine *engine = d->engineForScript( script );
|
---|
| 2393 | #ifdef QT_CHECK_STATE
|
---|
| 2394 | Q_ASSERT( engine != 0 );
|
---|
| 2395 | #endif // QT_CHECK_STATE
|
---|
| 2396 |
|
---|
| 2397 | glyph_t glyphs[10];
|
---|
| 2398 | int nglyphs = 9;
|
---|
| 2399 | engine->stringToCMap( &ch, 1, glyphs, 0, &nglyphs, FALSE );
|
---|
| 2400 | glyph_metrics_t gi = engine->boundingBox( glyphs[0] );
|
---|
| 2401 | return QRect( gi.x, gi.y, gi.width, gi.height );
|
---|
| 2402 | }
|
---|
| 2403 |
|
---|
| 2404 | /*!
|
---|
| 2405 | \overload
|
---|
| 2406 |
|
---|
| 2407 | Returns the bounding rectangle of the first \a len characters of
|
---|
| 2408 | \a str, which is the set of pixels the text would cover if drawn
|
---|
| 2409 | at (0, 0). The drawing, and hence the bounding rectangle, is
|
---|
| 2410 | constrained to the rectangle (\a x, \a y, \a w, \a h).
|
---|
| 2411 |
|
---|
| 2412 | If \a len is negative (which is the default), the entire string is
|
---|
| 2413 | used.
|
---|
| 2414 |
|
---|
| 2415 | The \a flgs argument is the bitwise OR of the following flags:
|
---|
| 2416 | \list
|
---|
| 2417 | \i \c AlignAuto aligns to the left border for all languages except
|
---|
| 2418 | Arabic and Hebrew where it aligns to the right.
|
---|
| 2419 | \i \c AlignLeft aligns to the left border.
|
---|
| 2420 | \i \c AlignRight aligns to the right border.
|
---|
| 2421 | \i \c AlignJustify produces justified text.
|
---|
| 2422 | \i \c AlignHCenter aligns horizontally centered.
|
---|
| 2423 | \i \c AlignTop aligns to the top border.
|
---|
| 2424 | \i \c AlignBottom aligns to the bottom border.
|
---|
| 2425 | \i \c AlignVCenter aligns vertically centered
|
---|
| 2426 | \i \c AlignCenter (== \c{AlignHCenter | AlignVCenter})
|
---|
| 2427 | \i \c SingleLine ignores newline characters in the text.
|
---|
| 2428 | \i \c ExpandTabs expands tabs (see below)
|
---|
| 2429 | \i \c ShowPrefix interprets "&x" as "<u>x</u>", i.e. underlined.
|
---|
| 2430 | \i \c WordBreak breaks the text to fit the rectangle.
|
---|
| 2431 | \endlist
|
---|
| 2432 |
|
---|
| 2433 | Horizontal alignment defaults to \c AlignAuto and vertical
|
---|
| 2434 | alignment defaults to \c AlignTop.
|
---|
| 2435 |
|
---|
| 2436 | If several of the horizontal or several of the vertical alignment
|
---|
| 2437 | flags are set, the resulting alignment is undefined.
|
---|
| 2438 |
|
---|
| 2439 | These flags are defined in \c qnamespace.h.
|
---|
| 2440 |
|
---|
| 2441 | If \c ExpandTabs is set in \a flgs, then: if \a tabarray is
|
---|
| 2442 | non-null, it specifies a 0-terminated sequence of pixel-positions
|
---|
| 2443 | for tabs; otherwise if \a tabstops is non-zero, it is used as the
|
---|
| 2444 | tab spacing (in pixels).
|
---|
| 2445 |
|
---|
| 2446 | Note that the bounding rectangle may extend to the left of (0, 0),
|
---|
| 2447 | e.g. for italicized fonts, and that the text output may cover \e
|
---|
| 2448 | all pixels in the bounding rectangle.
|
---|
| 2449 |
|
---|
| 2450 | Newline characters are processed as linebreaks.
|
---|
| 2451 |
|
---|
| 2452 | Despite the different actual character heights, the heights of the
|
---|
| 2453 | bounding rectangles of "Yes" and "yes" are the same.
|
---|
| 2454 |
|
---|
| 2455 | The bounding rectangle given by this function is somewhat larger
|
---|
| 2456 | than that calculated by the simpler boundingRect() function. This
|
---|
| 2457 | function uses the \link minLeftBearing() maximum left \endlink and
|
---|
| 2458 | \link minRightBearing() right \endlink font bearings as is
|
---|
| 2459 | necessary for multi-line text to align correctly. Also,
|
---|
| 2460 | fontHeight() and lineSpacing() are used to calculate the height,
|
---|
| 2461 | rather than individual character heights.
|
---|
| 2462 |
|
---|
| 2463 | The \a intern argument should not be used.
|
---|
| 2464 |
|
---|
| 2465 | \sa width(), QPainter::boundingRect(), Qt::AlignmentFlags
|
---|
| 2466 | */
|
---|
| 2467 | QRect QFontMetrics::boundingRect( int x, int y, int w, int h, int flgs,
|
---|
| 2468 | const QString& str, int len, int tabstops,
|
---|
| 2469 | int *tabarray, QTextParag **intern ) const
|
---|
| 2470 | {
|
---|
| 2471 | if ( len < 0 )
|
---|
| 2472 | len = str.length();
|
---|
| 2473 |
|
---|
| 2474 | int tabarraylen=0;
|
---|
| 2475 | if (tabarray)
|
---|
| 2476 | while (tabarray[tabarraylen])
|
---|
| 2477 | tabarraylen++;
|
---|
| 2478 |
|
---|
| 2479 | QRect rb;
|
---|
| 2480 | QRect r(x, y, w, h);
|
---|
| 2481 | qt_format_text( QFont( d, d->paintdevice ), r, flgs|Qt::DontPrint, str, len, &rb,
|
---|
| 2482 | tabstops, tabarray, tabarraylen, intern, 0 );
|
---|
| 2483 |
|
---|
| 2484 | return rb;
|
---|
| 2485 | }
|
---|
| 2486 |
|
---|
| 2487 | /*!
|
---|
| 2488 | Returns the size in pixels of the first \a len characters of \a
|
---|
| 2489 | str.
|
---|
| 2490 |
|
---|
| 2491 | If \a len is negative (the default), the entire string is used.
|
---|
| 2492 |
|
---|
| 2493 | The \a flgs argument is the bitwise OR of the following flags:
|
---|
| 2494 | \list
|
---|
| 2495 | \i \c SingleLine ignores newline characters.
|
---|
| 2496 | \i \c ExpandTabs expands tabs (see below)
|
---|
| 2497 | \i \c ShowPrefix interprets "&x" as "<u>x</u>", i.e. underlined.
|
---|
| 2498 | \i \c WordBreak breaks the text to fit the rectangle.
|
---|
| 2499 | \endlist
|
---|
| 2500 |
|
---|
| 2501 | These flags are defined in \c qnamespace.h.
|
---|
| 2502 |
|
---|
| 2503 | If \c ExpandTabs is set in \a flgs, then: if \a tabarray is
|
---|
| 2504 | non-null, it specifies a 0-terminated sequence of pixel-positions
|
---|
| 2505 | for tabs; otherwise if \a tabstops is non-zero, it is used as the
|
---|
| 2506 | tab spacing (in pixels).
|
---|
| 2507 |
|
---|
| 2508 | Newline characters are processed as linebreaks.
|
---|
| 2509 |
|
---|
| 2510 | Despite the different actual character heights, the heights of the
|
---|
| 2511 | bounding rectangles of "Yes" and "yes" are the same.
|
---|
| 2512 |
|
---|
| 2513 | The \a intern argument should not be used.
|
---|
| 2514 |
|
---|
| 2515 | \sa boundingRect()
|
---|
| 2516 | */
|
---|
| 2517 | QSize QFontMetrics::size( int flgs, const QString &str, int len, int tabstops,
|
---|
| 2518 | int *tabarray, QTextParag **intern ) const
|
---|
| 2519 | {
|
---|
| 2520 | return boundingRect(0,0,0,0,flgs,str,len,tabstops,tabarray,intern).size();
|
---|
| 2521 | }
|
---|
| 2522 |
|
---|
| 2523 | /*!
|
---|
| 2524 | Returns the distance from the base line to where an underscore
|
---|
| 2525 | should be drawn.
|
---|
| 2526 |
|
---|
| 2527 | \sa overlinePos(), strikeOutPos(), lineWidth()
|
---|
| 2528 | */
|
---|
| 2529 | int QFontMetrics::underlinePos() const
|
---|
| 2530 | {
|
---|
| 2531 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2532 | #ifdef QT_CHECK_STATE
|
---|
| 2533 | Q_ASSERT( engine != 0 );
|
---|
| 2534 | #endif // QT_CHECK_STATE
|
---|
| 2535 |
|
---|
| 2536 | return engine->underlinePosition();
|
---|
| 2537 | }
|
---|
| 2538 |
|
---|
| 2539 | /*!
|
---|
| 2540 | Returns the distance from the base line to where an overline
|
---|
| 2541 | should be drawn.
|
---|
| 2542 |
|
---|
| 2543 | \sa underlinePos(), strikeOutPos(), lineWidth()
|
---|
| 2544 | */
|
---|
| 2545 | int QFontMetrics::overlinePos() const
|
---|
| 2546 | {
|
---|
| 2547 | int pos = ascent() + 1;
|
---|
| 2548 | return pos > 0 ? pos : 1;
|
---|
| 2549 | }
|
---|
| 2550 |
|
---|
| 2551 | /*!
|
---|
| 2552 | Returns the distance from the base line to where the strikeout
|
---|
| 2553 | line should be drawn.
|
---|
| 2554 |
|
---|
| 2555 | \sa underlinePos(), overlinePos(), lineWidth()
|
---|
| 2556 | */
|
---|
| 2557 | int QFontMetrics::strikeOutPos() const
|
---|
| 2558 | {
|
---|
| 2559 | int pos = ascent() / 3;
|
---|
| 2560 | return pos > 0 ? pos : 1;
|
---|
| 2561 | }
|
---|
| 2562 |
|
---|
| 2563 | /*!
|
---|
| 2564 | Returns the width of the underline and strikeout lines, adjusted
|
---|
| 2565 | for the point size of the font.
|
---|
| 2566 |
|
---|
| 2567 | \sa underlinePos(), overlinePos(), strikeOutPos()
|
---|
| 2568 | */
|
---|
| 2569 | int QFontMetrics::lineWidth() const
|
---|
| 2570 | {
|
---|
| 2571 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2572 | #ifdef QT_CHECK_STATE
|
---|
| 2573 | Q_ASSERT( engine != 0 );
|
---|
| 2574 | #endif // QT_CHECK_STATE
|
---|
| 2575 |
|
---|
| 2576 | return engine->lineThickness();
|
---|
| 2577 | }
|
---|
| 2578 |
|
---|
| 2579 |
|
---|
| 2580 |
|
---|
| 2581 |
|
---|
| 2582 | /*****************************************************************************
|
---|
| 2583 | QFontInfo member functions
|
---|
| 2584 | *****************************************************************************/
|
---|
| 2585 |
|
---|
| 2586 | /*!
|
---|
| 2587 | \class QFontInfo qfontinfo.h
|
---|
| 2588 |
|
---|
| 2589 | \brief The QFontInfo class provides general information about fonts.
|
---|
| 2590 |
|
---|
| 2591 | \ingroup graphics
|
---|
| 2592 | \ingroup shared
|
---|
| 2593 |
|
---|
| 2594 | The QFontInfo class provides the same access functions as QFont,
|
---|
| 2595 | e.g. family(), pointSize(), italic(), weight(), fixedPitch(),
|
---|
| 2596 | styleHint() etc. But whilst the QFont access functions return the
|
---|
| 2597 | values that were set, a QFontInfo object returns the values that
|
---|
| 2598 | apply to the font that will actually be used to draw the text.
|
---|
| 2599 |
|
---|
| 2600 | For example, when the program asks for a 25pt Courier font on a
|
---|
| 2601 | machine that has a non-scalable 24pt Courier font, QFont will
|
---|
| 2602 | (normally) use the 24pt Courier for rendering. In this case,
|
---|
| 2603 | QFont::pointSize() returns 25 and QFontInfo::pointSize() returns
|
---|
| 2604 | 24.
|
---|
| 2605 |
|
---|
| 2606 | There are three ways to create a QFontInfo object.
|
---|
| 2607 | \list 1
|
---|
| 2608 | \i Calling the QFontInfo constructor with a QFont creates a font
|
---|
| 2609 | info object for a screen-compatible font, i.e. the font cannot be
|
---|
| 2610 | a printer font<sup>*</sup>. If the font is changed later, the font
|
---|
| 2611 | info object is \e not updated.
|
---|
| 2612 |
|
---|
| 2613 | \i QWidget::fontInfo() returns the font info for a widget's font.
|
---|
| 2614 | This is equivalent to calling QFontInfo(widget->font()). If the
|
---|
| 2615 | widget's font is changed later, the font info object is \e not
|
---|
| 2616 | updated.
|
---|
| 2617 |
|
---|
| 2618 | \i QPainter::fontInfo() returns the font info for a painter's
|
---|
| 2619 | current font. If the painter's font is changed later, the font
|
---|
| 2620 | info object is \e not updated.
|
---|
| 2621 | \endlist
|
---|
| 2622 |
|
---|
| 2623 | <sup>*</sup> If you use a printer font the values returned may be
|
---|
| 2624 | inaccurate. Printer fonts are not always accessible so the nearest
|
---|
| 2625 | screen font is used if a printer font is supplied.
|
---|
| 2626 |
|
---|
| 2627 | \sa QFont QFontMetrics QFontDatabase
|
---|
| 2628 | */
|
---|
| 2629 |
|
---|
| 2630 | /*!
|
---|
| 2631 | Constructs a font info object for \a font.
|
---|
| 2632 |
|
---|
| 2633 | The font must be screen-compatible, i.e. a font you use when
|
---|
| 2634 | drawing text in \link QWidget widgets\endlink or \link QPixmap
|
---|
| 2635 | pixmaps\endlink, not QPicture or QPrinter.
|
---|
| 2636 |
|
---|
| 2637 | The font info object holds the information for the font that is
|
---|
| 2638 | passed in the constructor at the time it is created, and is not
|
---|
| 2639 | updated if the font's attributes are changed later.
|
---|
| 2640 |
|
---|
| 2641 | Use QPainter::fontInfo() to get the font info when painting.
|
---|
| 2642 | This will give correct results also when painting on paint device
|
---|
| 2643 | that is not screen-compatible.
|
---|
| 2644 | */
|
---|
| 2645 | QFontInfo::QFontInfo( const QFont &font )
|
---|
| 2646 | : d( font.d ), painter( 0 ), fscript( QFont::NoScript )
|
---|
| 2647 | {
|
---|
| 2648 | d->ref();
|
---|
| 2649 | }
|
---|
| 2650 |
|
---|
| 2651 | /*!
|
---|
| 2652 | Constructs a font info object for \a font using the specified \a
|
---|
| 2653 | script.
|
---|
| 2654 | */
|
---|
| 2655 | QFontInfo::QFontInfo( const QFont &font, QFont::Script script )
|
---|
| 2656 | : d( font.d ), painter( 0 ), fscript( script )
|
---|
| 2657 | {
|
---|
| 2658 | d->ref();
|
---|
| 2659 | }
|
---|
| 2660 |
|
---|
| 2661 | /*! \internal
|
---|
| 2662 |
|
---|
| 2663 | Constructs a font info object from the painter's font \a p.
|
---|
| 2664 | */
|
---|
| 2665 | QFontInfo::QFontInfo( const QPainter *p )
|
---|
| 2666 | : painter( 0 ), fscript( QFont::NoScript )
|
---|
| 2667 | {
|
---|
| 2668 | QPainter *painter = (QPainter *) p;
|
---|
| 2669 |
|
---|
| 2670 | #if defined(CHECK_STATE)
|
---|
| 2671 | if ( !painter->isActive() )
|
---|
| 2672 | qWarning( "QFontInfo: Get font info between QPainter::begin() "
|
---|
| 2673 | "and QPainter::end()" );
|
---|
| 2674 | #endif
|
---|
| 2675 |
|
---|
| 2676 | painter->setf( QPainter::FontInf );
|
---|
| 2677 | if ( painter->testf(QPainter::DirtyFont) )
|
---|
| 2678 | painter->updateFont();
|
---|
| 2679 | if ( painter->pfont )
|
---|
| 2680 | d = painter->pfont->d;
|
---|
| 2681 | else
|
---|
| 2682 | d = painter->cfont.d;
|
---|
| 2683 | d->ref();
|
---|
| 2684 | }
|
---|
| 2685 |
|
---|
| 2686 | /*!
|
---|
| 2687 | Constructs a copy of \a fi.
|
---|
| 2688 | */
|
---|
| 2689 | QFontInfo::QFontInfo( const QFontInfo &fi )
|
---|
| 2690 | : d(fi.d), painter(0), fscript( fi.fscript )
|
---|
| 2691 | {
|
---|
| 2692 | d->ref();
|
---|
| 2693 | }
|
---|
| 2694 |
|
---|
| 2695 | /*!
|
---|
| 2696 | Destroys the font info object.
|
---|
| 2697 | */
|
---|
| 2698 | QFontInfo::~QFontInfo()
|
---|
| 2699 | {
|
---|
| 2700 | if ( d->deref() )
|
---|
| 2701 | delete d;
|
---|
| 2702 | }
|
---|
| 2703 |
|
---|
| 2704 | /*!
|
---|
| 2705 | Assigns the font info in \a fi.
|
---|
| 2706 | */
|
---|
| 2707 | QFontInfo &QFontInfo::operator=( const QFontInfo &fi )
|
---|
| 2708 | {
|
---|
| 2709 | if ( d != fi.d ) {
|
---|
| 2710 | if ( d->deref() )
|
---|
| 2711 | delete d;
|
---|
| 2712 | d = fi.d;
|
---|
| 2713 | d->ref();
|
---|
| 2714 | }
|
---|
| 2715 | painter = 0;
|
---|
| 2716 | fscript = fi.fscript;
|
---|
| 2717 | return *this;
|
---|
| 2718 | }
|
---|
| 2719 |
|
---|
| 2720 | /*!
|
---|
| 2721 | Returns the family name of the matched window system font.
|
---|
| 2722 |
|
---|
| 2723 | \sa QFont::family()
|
---|
| 2724 | */
|
---|
| 2725 | QString QFontInfo::family() const
|
---|
| 2726 | {
|
---|
| 2727 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2728 | #ifdef QT_CHECK_STATE
|
---|
| 2729 | Q_ASSERT( engine != 0 );
|
---|
| 2730 | #endif // QT_CHECK_STATE
|
---|
| 2731 | return engine->fontDef.family;
|
---|
| 2732 | }
|
---|
| 2733 |
|
---|
| 2734 | /*!
|
---|
| 2735 | Returns the point size of the matched window system font.
|
---|
| 2736 |
|
---|
| 2737 | \sa QFont::pointSize()
|
---|
| 2738 | */
|
---|
| 2739 | int QFontInfo::pointSize() const
|
---|
| 2740 | {
|
---|
| 2741 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2742 | #ifdef QT_CHECK_STATE
|
---|
| 2743 | Q_ASSERT( engine != 0 );
|
---|
| 2744 | #endif // QT_CHECK_STATE
|
---|
| 2745 | return ( engine->fontDef.pointSize + 5 ) / 10;
|
---|
| 2746 | }
|
---|
| 2747 |
|
---|
| 2748 | /*!
|
---|
| 2749 | Returns the pixel size of the matched window system font.
|
---|
| 2750 |
|
---|
| 2751 | \sa QFont::pointSize()
|
---|
| 2752 | */
|
---|
| 2753 | int QFontInfo::pixelSize() const
|
---|
| 2754 | {
|
---|
| 2755 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2756 | #ifdef QT_CHECK_STATE
|
---|
| 2757 | Q_ASSERT( engine != 0 );
|
---|
| 2758 | #endif // QT_CHECK_STATE
|
---|
| 2759 | return engine->fontDef.pixelSize;
|
---|
| 2760 | }
|
---|
| 2761 |
|
---|
| 2762 | /*!
|
---|
| 2763 | Returns the italic value of the matched window system font.
|
---|
| 2764 |
|
---|
| 2765 | \sa QFont::italic()
|
---|
| 2766 | */
|
---|
| 2767 | bool QFontInfo::italic() const
|
---|
| 2768 | {
|
---|
| 2769 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2770 | #ifdef QT_CHECK_STATE
|
---|
| 2771 | Q_ASSERT( engine != 0 );
|
---|
| 2772 | #endif // QT_CHECK_STATE
|
---|
| 2773 | return engine->fontDef.italic;
|
---|
| 2774 | }
|
---|
| 2775 |
|
---|
| 2776 | /*!
|
---|
| 2777 | Returns the weight of the matched window system font.
|
---|
| 2778 |
|
---|
| 2779 | \sa QFont::weight(), bold()
|
---|
| 2780 | */
|
---|
| 2781 | int QFontInfo::weight() const
|
---|
| 2782 | {
|
---|
| 2783 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2784 | #ifdef QT_CHECK_STATE
|
---|
| 2785 | Q_ASSERT( engine != 0 );
|
---|
| 2786 | #endif // QT_CHECK_STATE
|
---|
| 2787 | return engine->fontDef.weight;
|
---|
| 2788 |
|
---|
| 2789 | }
|
---|
| 2790 |
|
---|
| 2791 | /*!
|
---|
| 2792 | \fn bool QFontInfo::bold() const
|
---|
| 2793 |
|
---|
| 2794 | Returns TRUE if weight() would return a value greater than \c
|
---|
| 2795 | QFont::Normal; otherwise returns FALSE.
|
---|
| 2796 |
|
---|
| 2797 | \sa weight(), QFont::bold()
|
---|
| 2798 | */
|
---|
| 2799 |
|
---|
| 2800 | /*!
|
---|
| 2801 | Returns the underline value of the matched window system font.
|
---|
| 2802 |
|
---|
| 2803 | \sa QFont::underline()
|
---|
| 2804 |
|
---|
| 2805 | \internal
|
---|
| 2806 |
|
---|
| 2807 | Here we read the underline flag directly from the QFont.
|
---|
| 2808 | This is OK for X11 and for Windows because we always get what we want.
|
---|
| 2809 | */
|
---|
| 2810 | bool QFontInfo::underline() const
|
---|
| 2811 | {
|
---|
| 2812 | return d->underline;
|
---|
| 2813 | }
|
---|
| 2814 |
|
---|
| 2815 | /*!
|
---|
| 2816 | Returns the overline value of the matched window system font.
|
---|
| 2817 |
|
---|
| 2818 | \sa QFont::overline()
|
---|
| 2819 |
|
---|
| 2820 | \internal
|
---|
| 2821 |
|
---|
| 2822 | Here we read the overline flag directly from the QFont.
|
---|
| 2823 | This is OK for X11 and for Windows because we always get what we want.
|
---|
| 2824 | */
|
---|
| 2825 | bool QFontInfo::overline() const
|
---|
| 2826 | {
|
---|
| 2827 | return d->overline;
|
---|
| 2828 | }
|
---|
| 2829 |
|
---|
| 2830 | /*!
|
---|
| 2831 | Returns the strikeout value of the matched window system font.
|
---|
| 2832 |
|
---|
| 2833 | \sa QFont::strikeOut()
|
---|
| 2834 |
|
---|
| 2835 | \internal Here we read the strikeOut flag directly from the QFont.
|
---|
| 2836 | This is OK for X11 and for Windows because we always get what we want.
|
---|
| 2837 | */
|
---|
| 2838 | bool QFontInfo::strikeOut() const
|
---|
| 2839 | {
|
---|
| 2840 | return d->strikeOut;
|
---|
| 2841 | }
|
---|
| 2842 |
|
---|
| 2843 | /*!
|
---|
| 2844 | Returns the fixed pitch value of the matched window system font.
|
---|
| 2845 |
|
---|
| 2846 | \sa QFont::fixedPitch()
|
---|
| 2847 | */
|
---|
| 2848 | bool QFontInfo::fixedPitch() const
|
---|
| 2849 | {
|
---|
| 2850 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2851 | #ifdef QT_CHECK_STATE
|
---|
| 2852 | Q_ASSERT( engine != 0 );
|
---|
| 2853 | #endif // QT_CHECK_STATE
|
---|
| 2854 | #ifdef Q_OS_MAC
|
---|
| 2855 | if (!engine->fontDef.fixedPitchComputed) {
|
---|
| 2856 | QChar ch[2] = { QChar('i'), QChar('m') };
|
---|
| 2857 | glyph_t g[2];
|
---|
| 2858 | int l = 2;
|
---|
| 2859 | advance_t a[2];
|
---|
| 2860 | engine->stringToCMap(ch, 2, g, a, &l, false);
|
---|
| 2861 | engine->fontDef.fixedPitch = a[0] == a[1];
|
---|
| 2862 | engine->fontDef.fixedPitchComputed = TRUE;
|
---|
| 2863 | }
|
---|
| 2864 | #endif
|
---|
| 2865 | return engine->fontDef.fixedPitch;
|
---|
| 2866 | }
|
---|
| 2867 |
|
---|
| 2868 | /*!
|
---|
| 2869 | Returns the style of the matched window system font.
|
---|
| 2870 |
|
---|
| 2871 | Currently only returns the style hint set in QFont.
|
---|
| 2872 |
|
---|
| 2873 | \sa QFont::styleHint() QFont::StyleHint
|
---|
| 2874 | */
|
---|
| 2875 | QFont::StyleHint QFontInfo::styleHint() const
|
---|
| 2876 | {
|
---|
| 2877 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2878 | #ifdef QT_CHECK_STATE
|
---|
| 2879 | Q_ASSERT( engine != 0 );
|
---|
| 2880 | #endif // QT_CHECK_STATE
|
---|
| 2881 | return (QFont::StyleHint) engine->fontDef.styleHint;
|
---|
| 2882 | }
|
---|
| 2883 |
|
---|
| 2884 | /*!
|
---|
| 2885 | Returns TRUE if the font is a raw mode font; otherwise returns
|
---|
| 2886 | FALSE.
|
---|
| 2887 |
|
---|
| 2888 | If it is a raw mode font, all other functions in QFontInfo will
|
---|
| 2889 | return the same values set in the QFont, regardless of the font
|
---|
| 2890 | actually used.
|
---|
| 2891 |
|
---|
| 2892 | \sa QFont::rawMode()
|
---|
| 2893 | */
|
---|
| 2894 | bool QFontInfo::rawMode() const
|
---|
| 2895 | {
|
---|
| 2896 | return d->rawMode;
|
---|
| 2897 | }
|
---|
| 2898 |
|
---|
| 2899 | /*!
|
---|
| 2900 | Returns TRUE if the matched window system font is exactly the same
|
---|
| 2901 | as the one specified by the font; otherwise returns FALSE.
|
---|
| 2902 |
|
---|
| 2903 | \sa QFont::exactMatch()
|
---|
| 2904 | */
|
---|
| 2905 | bool QFontInfo::exactMatch() const
|
---|
| 2906 | {
|
---|
| 2907 | QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
|
---|
| 2908 | #ifdef QT_CHECK_STATE
|
---|
| 2909 | Q_ASSERT( engine != 0 );
|
---|
| 2910 | #endif // QT_CHECK_STATE
|
---|
| 2911 |
|
---|
| 2912 | return d->rawMode ? engine->type() != QFontEngine::Box
|
---|
| 2913 | : d->request == engine->fontDef;
|
---|
| 2914 | }
|
---|
| 2915 |
|
---|
| 2916 |
|
---|
| 2917 |
|
---|
| 2918 |
|
---|
| 2919 | // **********************************************************************
|
---|
| 2920 | // QFontCache
|
---|
| 2921 | // **********************************************************************
|
---|
| 2922 |
|
---|
| 2923 | #ifdef QFONTCACHE_DEBUG
|
---|
| 2924 | // fast timeouts for debugging
|
---|
| 2925 | static const int fast_timeout = 1000; // 1s
|
---|
| 2926 | static const int slow_timeout = 5000; // 5s
|
---|
| 2927 | #else
|
---|
| 2928 | static const int fast_timeout = 10000; // 10s
|
---|
| 2929 | static const int slow_timeout = 300000; // 5m
|
---|
| 2930 | #endif // QFONTCACHE_DEBUG
|
---|
| 2931 |
|
---|
| 2932 | QFontCache *QFontCache::instance = 0;
|
---|
| 2933 | const uint QFontCache::min_cost = 4*1024; // 4mb
|
---|
| 2934 |
|
---|
[80] | 2935 | #if defined (Q_OS_OS2)
|
---|
| 2936 |
|
---|
| 2937 | // On OS/2, destructors of static objects in a DLL cannot use objects created
|
---|
| 2938 | // on the stack of the main thread when the application is being abnormally
|
---|
| 2939 | // terminated (exit(), DosExit(), DosKillProcess(), etc), because at a time when
|
---|
| 2940 | // these static destructors are called (from _DLL_InitTerm on most compilers,
|
---|
| 2941 | // including GCC and IBM VAC) the stack is most likely reused by the DLL
|
---|
| 2942 | // termination code. Since QFontCache is a child of QApplication (which is
|
---|
| 2943 | // usually created as a local object inside the main() function) and wants to
|
---|
| 2944 | // use its parent during destruction, this becomes a real problem and causes a
|
---|
| 2945 | // guaranteed application trap during abnormal termination. The workaround is to
|
---|
| 2946 | // use atexit() instead. Note that this will only work for the exit() case
|
---|
| 2947 | // (on DosExit() or DosKillProcess(), the stdlib's exit list is not processed).
|
---|
| 2948 |
|
---|
| 2949 | static void cleanupFontCache()
|
---|
| 2950 | {
|
---|
| 2951 | if (QFontCache::instance != 0)
|
---|
| 2952 | delete QFontCache::instance;
|
---|
| 2953 | }
|
---|
| 2954 |
|
---|
| 2955 | #else
|
---|
[2] | 2956 | static QSingleCleanupHandler<QFontCache> cleanup_fontcache;
|
---|
[80] | 2957 | #endif
|
---|
[2] | 2958 |
|
---|
| 2959 | QFontCache::QFontCache()
|
---|
| 2960 | : QObject( qApp, "global font cache" ), total_cost( 0 ), max_cost( min_cost ),
|
---|
| 2961 | current_timestamp( 0 ), fast( FALSE ), timer_id( -1 )
|
---|
| 2962 | {
|
---|
| 2963 | Q_ASSERT( instance == 0 );
|
---|
| 2964 | instance = this;
|
---|
[80] | 2965 | #if defined (Q_OS_OS2)
|
---|
| 2966 | atexit( cleanupFontCache );
|
---|
| 2967 | #else
|
---|
[2] | 2968 | cleanup_fontcache.set( &instance );
|
---|
[80] | 2969 | #endif
|
---|
[2] | 2970 | }
|
---|
| 2971 |
|
---|
| 2972 | QFontCache::~QFontCache()
|
---|
| 2973 | {
|
---|
| 2974 | {
|
---|
| 2975 | EngineDataCache::Iterator it = engineDataCache.begin(),
|
---|
| 2976 | end = engineDataCache.end();
|
---|
| 2977 | while ( it != end ) {
|
---|
| 2978 | if ( it.data()->count == 0 )
|
---|
| 2979 | delete it.data();
|
---|
| 2980 | else
|
---|
| 2981 | FC_DEBUG("QFontCache::~QFontCache: engineData %p still has refcount %d",
|
---|
| 2982 | it.data(), it.data()->count);
|
---|
| 2983 | ++it;
|
---|
| 2984 | }
|
---|
| 2985 | }
|
---|
| 2986 | EngineCache::Iterator it = engineCache.begin(),
|
---|
| 2987 | end = engineCache.end();
|
---|
| 2988 | while ( it != end ) {
|
---|
| 2989 | if ( it.data().data->count == 0 ) {
|
---|
| 2990 | if ( --it.data().data->cache_count == 0 ) {
|
---|
| 2991 | FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %d %d %d %d %d)",
|
---|
| 2992 | it.data().data, it.key().script, it.key().def.pointSize,
|
---|
| 2993 | it.key().def.pixelSize, it.key().def.weight, it.key().def.italic,
|
---|
| 2994 | it.key().def.fixedPitch);
|
---|
| 2995 |
|
---|
| 2996 | delete it.data().data;
|
---|
| 2997 | }
|
---|
| 2998 | } else {
|
---|
| 2999 | FC_DEBUG("QFontCache::~QFontCache: engine = %p still has refcount %d",
|
---|
| 3000 | it.data().data, it.data().data->count);
|
---|
| 3001 | }
|
---|
| 3002 | ++it;
|
---|
| 3003 | }
|
---|
| 3004 | instance = 0;
|
---|
| 3005 | }
|
---|
| 3006 |
|
---|
| 3007 | #ifdef Q_WS_QWS
|
---|
| 3008 | void QFontCache::clear()
|
---|
| 3009 | {
|
---|
| 3010 | {
|
---|
| 3011 | EngineDataCache::Iterator it = engineDataCache.begin(),
|
---|
| 3012 | end = engineDataCache.end();
|
---|
| 3013 | while ( it != end ) {
|
---|
| 3014 | QFontEngineData *data = it.data();
|
---|
| 3015 | if ( data->engine )
|
---|
| 3016 | data->engine->deref();
|
---|
| 3017 | data->engine = 0;
|
---|
| 3018 | ++it;
|
---|
| 3019 | }
|
---|
| 3020 | }
|
---|
| 3021 |
|
---|
| 3022 | EngineCache::Iterator it = engineCache.begin(),
|
---|
| 3023 | end = engineCache.end();
|
---|
| 3024 | while ( it != end ) {
|
---|
| 3025 | if ( it.data().data->count == 0 ) {
|
---|
| 3026 | if ( --it.data().data->cache_count == 0 ) {
|
---|
| 3027 | FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %d %d %d %d %d)",
|
---|
| 3028 | it.data().data, it.key().script, it.key().def.pointSize,
|
---|
| 3029 | it.key().def.pixelSize, it.key().def.weight, it.key().def.italic,
|
---|
| 3030 | it.key().def.fixedPitch);
|
---|
| 3031 | delete it.data().data;
|
---|
| 3032 | }
|
---|
| 3033 | } else {
|
---|
| 3034 | FC_DEBUG("QFontCache::~QFontCache: engine = %p still has refcount %d",
|
---|
| 3035 | it.data().data, it.data().data->count);
|
---|
| 3036 | }
|
---|
| 3037 | ++it;
|
---|
| 3038 | }
|
---|
| 3039 | }
|
---|
| 3040 | #endif
|
---|
| 3041 |
|
---|
| 3042 | QFontEngineData *QFontCache::findEngineData( const Key &key ) const
|
---|
| 3043 | {
|
---|
| 3044 | EngineDataCache::ConstIterator it = engineDataCache.find( key ),
|
---|
| 3045 | end = engineDataCache.end();
|
---|
| 3046 | if ( it == end ) return 0;
|
---|
| 3047 |
|
---|
| 3048 | // found
|
---|
| 3049 | return it.data();
|
---|
| 3050 | }
|
---|
| 3051 |
|
---|
| 3052 | void QFontCache::insertEngineData( const Key &key, QFontEngineData *engineData )
|
---|
| 3053 | {
|
---|
| 3054 | FC_DEBUG( "QFontCache: inserting new engine data %p", engineData );
|
---|
| 3055 |
|
---|
| 3056 | engineDataCache.insert( key, engineData );
|
---|
| 3057 | increaseCost( sizeof( QFontEngineData ) );
|
---|
| 3058 | }
|
---|
| 3059 |
|
---|
| 3060 | QFontEngine *QFontCache::findEngine( const Key &key )
|
---|
| 3061 | {
|
---|
| 3062 | EngineCache::Iterator it = engineCache.find( key ),
|
---|
| 3063 | end = engineCache.end();
|
---|
| 3064 | if ( it == end ) return 0;
|
---|
| 3065 |
|
---|
| 3066 | // found... update the hitcount and timestamp
|
---|
| 3067 | it.data().hits++;
|
---|
| 3068 | it.data().timestamp = ++current_timestamp;
|
---|
| 3069 |
|
---|
| 3070 | FC_DEBUG( "QFontCache: found font engine\n"
|
---|
| 3071 | " %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'",
|
---|
| 3072 | it.data().data, it.data().timestamp, it.data().hits,
|
---|
| 3073 | it.data().data->count, it.data().data->cache_count,
|
---|
| 3074 | it.data().data->name() );
|
---|
| 3075 |
|
---|
| 3076 | return it.data().data;
|
---|
| 3077 | }
|
---|
| 3078 |
|
---|
| 3079 | void QFontCache::insertEngine( const Key &key, QFontEngine *engine )
|
---|
| 3080 | {
|
---|
| 3081 | FC_DEBUG( "QFontCache: inserting new engine %p", engine );
|
---|
| 3082 |
|
---|
| 3083 | Engine data( engine );
|
---|
| 3084 | data.timestamp = ++current_timestamp;
|
---|
| 3085 |
|
---|
| 3086 | engineCache.insert( key, data );
|
---|
| 3087 |
|
---|
| 3088 | // only increase the cost if this is the first time we insert the engine
|
---|
| 3089 | if ( engine->cache_count == 0 )
|
---|
| 3090 | increaseCost( engine->cache_cost );
|
---|
| 3091 |
|
---|
| 3092 | ++engine->cache_count;
|
---|
| 3093 | }
|
---|
| 3094 |
|
---|
| 3095 | void QFontCache::increaseCost( uint cost )
|
---|
| 3096 | {
|
---|
| 3097 | cost = ( cost + 512 ) / 1024; // store cost in kb
|
---|
| 3098 | cost = cost > 0 ? cost : 1;
|
---|
| 3099 | total_cost += cost;
|
---|
| 3100 |
|
---|
| 3101 | FC_DEBUG( " COST: increased %u kb, total_cost %u kb, max_cost %u kb",
|
---|
| 3102 | cost, total_cost, max_cost );
|
---|
| 3103 |
|
---|
| 3104 | if ( total_cost > max_cost) {
|
---|
| 3105 | max_cost = total_cost;
|
---|
| 3106 |
|
---|
| 3107 | if ( timer_id == -1 || ! fast ) {
|
---|
| 3108 | FC_DEBUG( " TIMER: starting fast timer (%d ms)", fast_timeout );
|
---|
| 3109 |
|
---|
| 3110 | if (timer_id != -1) killTimer( timer_id );
|
---|
| 3111 | timer_id = startTimer( fast_timeout );
|
---|
| 3112 | fast = TRUE;
|
---|
| 3113 | }
|
---|
| 3114 | }
|
---|
| 3115 | }
|
---|
| 3116 |
|
---|
| 3117 | void QFontCache::decreaseCost( uint cost )
|
---|
| 3118 | {
|
---|
| 3119 | cost = ( cost + 512 ) / 1024; // cost is stored in kb
|
---|
| 3120 | cost = cost > 0 ? cost : 1;
|
---|
| 3121 | Q_ASSERT( cost <= total_cost );
|
---|
| 3122 | total_cost -= cost;
|
---|
| 3123 |
|
---|
| 3124 | FC_DEBUG( " COST: decreased %u kb, total_cost %u kb, max_cost %u kb",
|
---|
| 3125 | cost, total_cost, max_cost );
|
---|
| 3126 | }
|
---|
| 3127 |
|
---|
[8] | 3128 | #if defined(Q_WS_WIN) || defined(Q_WS_PM) || defined (Q_WS_QWS)
|
---|
[2] | 3129 | void QFontCache::cleanupPrinterFonts()
|
---|
| 3130 | {
|
---|
| 3131 | FC_DEBUG( "QFontCache::cleanupPrinterFonts" );
|
---|
| 3132 |
|
---|
| 3133 | {
|
---|
| 3134 | FC_DEBUG( " CLEAN engine data:" );
|
---|
| 3135 |
|
---|
| 3136 | // clean out all unused engine datas
|
---|
| 3137 | EngineDataCache::Iterator it = engineDataCache.begin(),
|
---|
| 3138 | end = engineDataCache.end();
|
---|
| 3139 | while ( it != end ) {
|
---|
| 3140 | if ( it.key().screen == 0 ) {
|
---|
| 3141 | ++it;
|
---|
| 3142 | continue;
|
---|
| 3143 | }
|
---|
| 3144 |
|
---|
| 3145 | if( it.data()->count > 0 ) {
|
---|
| 3146 | #ifdef Q_WS_WIN
|
---|
| 3147 | for(int i = 0; i < QFont::LastPrivateScript; ++i) {
|
---|
| 3148 | if( it.data()->engines[i] ) {
|
---|
| 3149 | it.data()->engines[i]->deref();
|
---|
| 3150 | it.data()->engines[i] = 0;
|
---|
| 3151 | }
|
---|
| 3152 | }
|
---|
| 3153 | #else
|
---|
| 3154 | if ( it.data()->engine ) {
|
---|
| 3155 | it.data()->engine->deref();
|
---|
| 3156 | it.data()->engine = 0;
|
---|
| 3157 | }
|
---|
| 3158 | #endif
|
---|
| 3159 | ++it;
|
---|
| 3160 | } else {
|
---|
| 3161 |
|
---|
| 3162 | EngineDataCache::Iterator rem = it++;
|
---|
| 3163 |
|
---|
| 3164 | decreaseCost( sizeof( QFontEngineData ) );
|
---|
| 3165 |
|
---|
| 3166 | FC_DEBUG( " %p", rem.data() );
|
---|
| 3167 |
|
---|
| 3168 | delete rem.data();
|
---|
| 3169 | engineDataCache.remove( rem );
|
---|
| 3170 | }
|
---|
| 3171 | }
|
---|
| 3172 | }
|
---|
| 3173 |
|
---|
| 3174 | EngineCache::Iterator it = engineCache.begin(),
|
---|
| 3175 | end = engineCache.end();
|
---|
| 3176 | while( it != end ) {
|
---|
| 3177 | if ( it.data().data->count > 0 || it.key().screen == 0) {
|
---|
| 3178 | ++it;
|
---|
| 3179 | continue;
|
---|
| 3180 | }
|
---|
| 3181 |
|
---|
| 3182 | FC_DEBUG( " %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'",
|
---|
| 3183 | it.data().data, it.data().timestamp, it.data().hits,
|
---|
| 3184 | it.data().data->count, it.data().data->cache_count,
|
---|
| 3185 | it.data().data->name() );
|
---|
| 3186 |
|
---|
| 3187 | if ( --it.data().data->cache_count == 0 ) {
|
---|
| 3188 | FC_DEBUG( " DELETE: last occurence in cache" );
|
---|
| 3189 |
|
---|
| 3190 | decreaseCost( it.data().data->cache_cost );
|
---|
| 3191 | delete it.data().data;
|
---|
| 3192 | }
|
---|
| 3193 |
|
---|
| 3194 | engineCache.remove( it++ );
|
---|
| 3195 | }
|
---|
| 3196 | }
|
---|
| 3197 | #endif
|
---|
| 3198 |
|
---|
| 3199 | void QFontCache::timerEvent( QTimerEvent * )
|
---|
| 3200 | {
|
---|
| 3201 | FC_DEBUG( "QFontCache::timerEvent: performing cache maintenance (timestamp %u)",
|
---|
| 3202 | current_timestamp );
|
---|
| 3203 |
|
---|
| 3204 | if ( total_cost <= max_cost && max_cost <= min_cost ) {
|
---|
| 3205 | FC_DEBUG( " cache redused sufficiently, stopping timer" );
|
---|
| 3206 |
|
---|
| 3207 | killTimer( timer_id );
|
---|
| 3208 | timer_id = -1;
|
---|
| 3209 | fast = FALSE;
|
---|
| 3210 |
|
---|
| 3211 | return;
|
---|
| 3212 | }
|
---|
| 3213 |
|
---|
| 3214 | // go through the cache and count up everything in use
|
---|
| 3215 | uint in_use_cost = 0;
|
---|
| 3216 |
|
---|
| 3217 | {
|
---|
| 3218 | FC_DEBUG( " SWEEP engine data:" );
|
---|
| 3219 |
|
---|
| 3220 | // make sure the cost of each engine data is at least 1kb
|
---|
| 3221 | const uint engine_data_cost =
|
---|
| 3222 | sizeof( QFontEngineData ) > 1024 ? sizeof( QFontEngineData ) : 1024;
|
---|
| 3223 |
|
---|
| 3224 | EngineDataCache::ConstIterator it = engineDataCache.begin(),
|
---|
| 3225 | end = engineDataCache.end();
|
---|
| 3226 | for ( ; it != end; ++it ) {
|
---|
| 3227 | #ifdef QFONTCACHE_DEBUG
|
---|
| 3228 | FC_DEBUG( " %p: ref %2d", it.data(), it.data()->count );
|
---|
| 3229 |
|
---|
| 3230 | # if defined(Q_WS_X11) || defined(Q_WS_WIN)
|
---|
| 3231 | // print out all engines
|
---|
| 3232 | for ( int i = 0; i < QFont::LastPrivateScript; ++i ) {
|
---|
| 3233 | if ( ! it.data()->engines[i] ) continue;
|
---|
| 3234 | FC_DEBUG( " contains %p", it.data()->engines[i] );
|
---|
| 3235 | }
|
---|
| 3236 | # endif // Q_WS_X11 || Q_WS_WIN
|
---|
| 3237 | #endif // QFONTCACHE_DEBUG
|
---|
| 3238 |
|
---|
| 3239 | if ( it.data()->count > 0 )
|
---|
| 3240 | in_use_cost += engine_data_cost;
|
---|
| 3241 | }
|
---|
| 3242 | }
|
---|
| 3243 |
|
---|
| 3244 | {
|
---|
| 3245 | FC_DEBUG( " SWEEP engine:" );
|
---|
| 3246 |
|
---|
| 3247 | EngineCache::ConstIterator it = engineCache.begin(),
|
---|
| 3248 | end = engineCache.end();
|
---|
| 3249 | for ( ; it != end; ++it ) {
|
---|
| 3250 | FC_DEBUG( " %p: timestamp %4u hits %2u ref %2d/%2d, cost %u bytes",
|
---|
| 3251 | it.data().data, it.data().timestamp, it.data().hits,
|
---|
| 3252 | it.data().data->count, it.data().data->cache_count,
|
---|
| 3253 | it.data().data->cache_cost );
|
---|
| 3254 |
|
---|
| 3255 | if ( it.data().data->count > 0 )
|
---|
| 3256 | in_use_cost += it.data().data->cache_cost / it.data().data->cache_count;
|
---|
| 3257 | }
|
---|
| 3258 |
|
---|
| 3259 | // attempt to make up for rounding errors
|
---|
| 3260 | in_use_cost += engineCache.count();
|
---|
| 3261 | }
|
---|
| 3262 |
|
---|
| 3263 | in_use_cost = ( in_use_cost + 512 ) / 1024; // cost is stored in kb
|
---|
| 3264 |
|
---|
| 3265 | /*
|
---|
| 3266 | calculate the new maximum cost for the cache
|
---|
| 3267 |
|
---|
| 3268 | NOTE: in_use_cost is *not* correct due to rounding errors in the
|
---|
| 3269 | above algorithm. instead of worrying about getting the
|
---|
| 3270 | calculation correct, we are more interested in speed, and use
|
---|
| 3271 | in_use_cost as a floor for new_max_cost
|
---|
| 3272 | */
|
---|
| 3273 | uint new_max_cost = QMAX( QMAX( max_cost / 2, in_use_cost ), min_cost );
|
---|
| 3274 |
|
---|
| 3275 | FC_DEBUG( " after sweep, in use %u kb, total %u kb, max %u kb, new max %u kb",
|
---|
| 3276 | in_use_cost, total_cost, max_cost, new_max_cost );
|
---|
| 3277 |
|
---|
| 3278 | if ( new_max_cost == max_cost ) {
|
---|
| 3279 | if ( fast ) {
|
---|
| 3280 | FC_DEBUG( " cannot shrink cache, slowing timer" );
|
---|
| 3281 |
|
---|
| 3282 | killTimer( timer_id );
|
---|
| 3283 | timer_id = startTimer( slow_timeout );
|
---|
| 3284 | fast = FALSE;
|
---|
| 3285 | }
|
---|
| 3286 |
|
---|
| 3287 | return;
|
---|
| 3288 | } else if ( ! fast ) {
|
---|
| 3289 | FC_DEBUG( " dropping into passing gear" );
|
---|
| 3290 |
|
---|
| 3291 | killTimer( timer_id );
|
---|
| 3292 | timer_id = startTimer( fast_timeout );
|
---|
| 3293 | fast = TRUE;
|
---|
| 3294 | }
|
---|
| 3295 |
|
---|
| 3296 | max_cost = new_max_cost;
|
---|
| 3297 |
|
---|
| 3298 | {
|
---|
| 3299 | FC_DEBUG( " CLEAN engine data:" );
|
---|
| 3300 |
|
---|
| 3301 | // clean out all unused engine datas
|
---|
| 3302 | EngineDataCache::Iterator it = engineDataCache.begin(),
|
---|
| 3303 | end = engineDataCache.end();
|
---|
| 3304 | while ( it != end ) {
|
---|
| 3305 | if ( it.data()->count > 0 ) {
|
---|
| 3306 | ++it;
|
---|
| 3307 | continue;
|
---|
| 3308 | }
|
---|
| 3309 |
|
---|
| 3310 | EngineDataCache::Iterator rem = it++;
|
---|
| 3311 |
|
---|
| 3312 | decreaseCost( sizeof( QFontEngineData ) );
|
---|
| 3313 |
|
---|
| 3314 | FC_DEBUG( " %p", rem.data() );
|
---|
| 3315 |
|
---|
| 3316 | delete rem.data();
|
---|
| 3317 | engineDataCache.remove( rem );
|
---|
| 3318 | }
|
---|
| 3319 | }
|
---|
| 3320 |
|
---|
| 3321 | // clean out the engine cache just enough to get below our new max cost
|
---|
| 3322 | uint current_cost;
|
---|
| 3323 | do {
|
---|
| 3324 | current_cost = total_cost;
|
---|
| 3325 |
|
---|
| 3326 | EngineCache::Iterator it = engineCache.begin(),
|
---|
| 3327 | end = engineCache.end();
|
---|
| 3328 | // determine the oldest and least popular of the unused engines
|
---|
| 3329 | uint oldest = ~0;
|
---|
| 3330 | uint least_popular = ~0;
|
---|
| 3331 |
|
---|
| 3332 | for ( ; it != end; ++it ) {
|
---|
| 3333 | if ( it.data().data->count > 0 ) continue;
|
---|
| 3334 |
|
---|
| 3335 | if ( it.data().timestamp < oldest &&
|
---|
| 3336 | it.data().hits <= least_popular ) {
|
---|
| 3337 | oldest = it.data().timestamp;
|
---|
| 3338 | least_popular = it.data().hits;
|
---|
| 3339 | }
|
---|
| 3340 | }
|
---|
| 3341 |
|
---|
| 3342 | FC_DEBUG( " oldest %u least popular %u", oldest, least_popular );
|
---|
| 3343 |
|
---|
| 3344 | for ( it = engineCache.begin(); it != end; ++it ) {
|
---|
| 3345 | if ( it.data().data->count == 0 &&
|
---|
| 3346 | it.data().timestamp == oldest &&
|
---|
| 3347 | it.data().hits == least_popular)
|
---|
| 3348 | break;
|
---|
| 3349 | }
|
---|
| 3350 |
|
---|
| 3351 | if ( it != end ) {
|
---|
| 3352 | FC_DEBUG( " %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'",
|
---|
| 3353 | it.data().data, it.data().timestamp, it.data().hits,
|
---|
| 3354 | it.data().data->count, it.data().data->cache_count,
|
---|
| 3355 | it.data().data->name() );
|
---|
| 3356 |
|
---|
| 3357 | if ( --it.data().data->cache_count == 0 ) {
|
---|
| 3358 | FC_DEBUG( " DELETE: last occurence in cache" );
|
---|
| 3359 |
|
---|
| 3360 | decreaseCost( it.data().data->cache_cost );
|
---|
| 3361 | delete it.data().data;
|
---|
| 3362 | } else {
|
---|
| 3363 | /*
|
---|
| 3364 | this particular font engine is in the cache multiple
|
---|
| 3365 | times... set current_cost to zero, so that we can
|
---|
| 3366 | keep looping to get rid of all occurences
|
---|
| 3367 | */
|
---|
| 3368 | current_cost = 0;
|
---|
| 3369 | }
|
---|
| 3370 |
|
---|
| 3371 | engineCache.remove( it );
|
---|
| 3372 | }
|
---|
| 3373 | } while ( current_cost != total_cost && total_cost > max_cost );
|
---|
| 3374 | }
|
---|