[2] | 1 | /****************************************************************************
|
---|
| 2 | ** $Id: qfontdatabase.cpp 8 2005-11-16 19:36:46Z dmik $
|
---|
| 3 | **
|
---|
| 4 | ** Implementation of font database class.
|
---|
| 5 | **
|
---|
| 6 | ** Created : 990603
|
---|
| 7 | **
|
---|
| 8 | ** Copyright (C) 1999-2000 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 | #include "qfontdatabase.h"
|
---|
| 39 |
|
---|
| 40 | #ifndef QT_NO_FONTDATABASE
|
---|
| 41 |
|
---|
| 42 | #include <qtl.h>
|
---|
| 43 | #include <qapplication.h>
|
---|
| 44 |
|
---|
| 45 | #include <private/qunicodetables_p.h>
|
---|
| 46 | #include "qfontengine_p.h"
|
---|
| 47 |
|
---|
| 48 | #include <qcleanuphandler.h>
|
---|
| 49 |
|
---|
| 50 | #ifdef Q_WS_X11
|
---|
| 51 | #include <locale.h>
|
---|
| 52 | #endif
|
---|
| 53 | #include <stdlib.h>
|
---|
| 54 |
|
---|
| 55 | // #define QFONTDATABASE_DEBUG
|
---|
| 56 | #ifdef QFONTDATABASE_DEBUG
|
---|
| 57 | # define FD_DEBUG qDebug
|
---|
| 58 | #else
|
---|
| 59 | # define FD_DEBUG if (FALSE) qDebug
|
---|
| 60 | #endif
|
---|
| 61 |
|
---|
| 62 | // #define FONT_MATCH_DEBUG
|
---|
| 63 | #ifdef FONT_MATCH_DEBUG
|
---|
| 64 | # define FM_DEBUG qDebug
|
---|
| 65 | #else
|
---|
| 66 | # define FM_DEBUG if (FALSE) qDebug
|
---|
| 67 | #endif
|
---|
| 68 |
|
---|
| 69 | #if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
|
---|
| 70 | # define for if(0){}else for
|
---|
| 71 | #endif
|
---|
| 72 |
|
---|
[8] | 73 | #define SMOOTH_SCALABLE 0xffff
|
---|
| 74 |
|
---|
[2] | 75 | static int ucstricmp( const QString &as, const QString &bs )
|
---|
| 76 | {
|
---|
| 77 | const QChar *a = as.unicode();
|
---|
| 78 | const QChar *b = bs.unicode();
|
---|
| 79 | if ( a == b )
|
---|
| 80 | return 0;
|
---|
| 81 | if ( a == 0 )
|
---|
| 82 | return 1;
|
---|
| 83 | if ( b == 0 )
|
---|
| 84 | return -1;
|
---|
| 85 | int l=QMIN(as.length(),bs.length());
|
---|
| 86 | while ( l-- && ::lower( *a ) == ::lower( *b ) )
|
---|
| 87 | a++,b++;
|
---|
| 88 | if ( l==-1 )
|
---|
| 89 | return ( as.length()-bs.length() );
|
---|
| 90 | return ::lower( *a ).unicode() - ::lower( *b ).unicode();
|
---|
| 91 | }
|
---|
| 92 |
|
---|
| 93 | static int getFontWeight( const QString &weightString )
|
---|
| 94 | {
|
---|
| 95 | QString s = weightString.lower();
|
---|
| 96 |
|
---|
| 97 | // Test in decreasing order of commonness
|
---|
| 98 | if (s == "medium" ||
|
---|
| 99 | s == "normal")
|
---|
| 100 | return QFont::Normal;
|
---|
| 101 | if (s == "bold")
|
---|
| 102 | return QFont::Bold;
|
---|
| 103 | if (s == "demibold" || s == "demi bold")
|
---|
| 104 | return QFont::DemiBold;
|
---|
| 105 | if (s == "black")
|
---|
| 106 | return QFont::Black;
|
---|
| 107 | if (s == "light")
|
---|
| 108 | return QFont::Light;
|
---|
| 109 |
|
---|
| 110 | if (s.contains("bold")) {
|
---|
| 111 | if (s.contains("demi"))
|
---|
| 112 | return (int) QFont::DemiBold;
|
---|
| 113 | return (int) QFont::Bold;
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | if (s.contains("light"))
|
---|
| 117 | return (int) QFont::Light;
|
---|
| 118 |
|
---|
| 119 | if (s.contains("black"))
|
---|
| 120 | return (int) QFont::Black;
|
---|
| 121 |
|
---|
| 122 | return (int) QFont::Normal;
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 | #ifdef Q_WS_X11
|
---|
| 126 | struct QtFontEncoding
|
---|
| 127 | {
|
---|
| 128 | signed int encoding : 16;
|
---|
| 129 |
|
---|
| 130 | uint xpoint : 16;
|
---|
| 131 | uint xres : 8;
|
---|
| 132 | uint yres : 8;
|
---|
| 133 | uint avgwidth : 16;
|
---|
| 134 | uchar pitch : 8;
|
---|
| 135 | };
|
---|
| 136 | #endif // Q_WS_X11
|
---|
| 137 |
|
---|
| 138 | struct QtFontSize
|
---|
| 139 | {
|
---|
| 140 | unsigned short pixelSize;
|
---|
| 141 |
|
---|
[8] | 142 | #ifdef Q_WS_PM
|
---|
| 143 | unsigned short pointSize; // in deca-points
|
---|
| 144 | LONG lMatch;
|
---|
| 145 | #endif
|
---|
[2] | 146 | #ifdef Q_WS_X11
|
---|
| 147 | int count;
|
---|
| 148 | QtFontEncoding *encodings;
|
---|
| 149 | QtFontEncoding *encodingID( int id, uint xpoint = 0, uint xres = 0,
|
---|
| 150 | uint yres = 0, uint avgwidth = 0, bool add = FALSE);
|
---|
| 151 | #endif // Q_WS_X11
|
---|
| 152 | };
|
---|
| 153 |
|
---|
| 154 |
|
---|
| 155 | #ifdef Q_WS_X11
|
---|
| 156 | QtFontEncoding *QtFontSize::encodingID( int id, uint xpoint, uint xres,
|
---|
| 157 | uint yres, uint avgwidth, bool add )
|
---|
| 158 | {
|
---|
| 159 | // we don't match using the xpoint, xres and yres parameters, only the id
|
---|
| 160 | for ( int i = 0; i < count; ++i ) {
|
---|
| 161 | if ( encodings[i].encoding == id )
|
---|
| 162 | return encodings + i;
|
---|
| 163 | }
|
---|
| 164 |
|
---|
| 165 | if ( !add ) return 0;
|
---|
| 166 |
|
---|
| 167 | if ( !(count % 4) )
|
---|
| 168 | encodings = ( QtFontEncoding * )
|
---|
| 169 | realloc( encodings,
|
---|
| 170 | (((count+4) >> 2 ) << 2 ) * sizeof( QtFontEncoding ) );
|
---|
| 171 | encodings[count].encoding = id;
|
---|
| 172 | encodings[count].xpoint = xpoint;
|
---|
| 173 | encodings[count].xres = xres;
|
---|
| 174 | encodings[count].yres = yres;
|
---|
| 175 | encodings[count].avgwidth = avgwidth;
|
---|
| 176 | encodings[count].pitch = '*';
|
---|
| 177 | return encodings + count++;
|
---|
| 178 | }
|
---|
| 179 | #endif // Q_WS_X11
|
---|
| 180 |
|
---|
| 181 | struct QtFontStyle
|
---|
| 182 | {
|
---|
| 183 | struct Key {
|
---|
| 184 | Key( const QString &styleString );
|
---|
| 185 | Key() : italic( FALSE ), oblique( FALSE ),
|
---|
| 186 | weight( QFont::Normal ), stretch( 0 ) { }
|
---|
| 187 | Key( const Key &o ) : italic( o.italic ), oblique( o.oblique ),
|
---|
| 188 | weight( o.weight ), stretch( o.stretch ) { }
|
---|
| 189 | uint italic : 1;
|
---|
| 190 | uint oblique : 1;
|
---|
| 191 | signed int weight : 8;
|
---|
| 192 | signed int stretch : 12;
|
---|
| 193 |
|
---|
| 194 | bool operator==( const Key & other ) {
|
---|
| 195 | return ( italic == other.italic &&
|
---|
| 196 | oblique == other.oblique &&
|
---|
| 197 | weight == other.weight &&
|
---|
| 198 | (stretch == 0 || other.stretch == 0 || stretch == other.stretch) );
|
---|
| 199 | }
|
---|
| 200 | bool operator!=( const Key &other ) {
|
---|
| 201 | return !operator==(other);
|
---|
| 202 | }
|
---|
| 203 | bool operator <( const Key &o ) {
|
---|
| 204 | int x = (italic << 13) + (oblique << 12) + (weight << 14) + stretch;
|
---|
| 205 | int y = (o.italic << 13) + (o.oblique << 12) + (o.weight << 14) + o.stretch;
|
---|
| 206 | return ( x < y );
|
---|
| 207 | }
|
---|
| 208 | };
|
---|
| 209 |
|
---|
| 210 | QtFontStyle( const Key &k )
|
---|
| 211 | : key( k ), bitmapScalable( FALSE ), smoothScalable( FALSE ),
|
---|
| 212 | fakeOblique( FALSE ), count( 0 ), pixelSizes( 0 )
|
---|
| 213 | {
|
---|
[8] | 214 | #if defined(Q_WS_PM)
|
---|
| 215 | szFacename[0] = 0;
|
---|
| 216 | #elif defined(Q_WS_X11)
|
---|
[2] | 217 | weightName = setwidthName = 0;
|
---|
[8] | 218 | #endif
|
---|
[2] | 219 | }
|
---|
| 220 |
|
---|
| 221 | ~QtFontStyle() {
|
---|
| 222 | #ifdef Q_WS_X11
|
---|
| 223 | delete [] weightName;
|
---|
| 224 | delete [] setwidthName;
|
---|
| 225 | while ( count-- )
|
---|
| 226 | free(pixelSizes[count].encodings);
|
---|
| 227 | #endif
|
---|
| 228 | free( pixelSizes );
|
---|
| 229 | }
|
---|
| 230 |
|
---|
| 231 | Key key;
|
---|
| 232 | bool bitmapScalable : 1;
|
---|
| 233 | bool smoothScalable : 1;
|
---|
| 234 | bool fakeOblique : 1;
|
---|
| 235 | int count : 29;
|
---|
| 236 | QtFontSize *pixelSizes;
|
---|
| 237 |
|
---|
[8] | 238 | #ifdef Q_WS_PM
|
---|
| 239 | CHAR szFacename [FACESIZE];
|
---|
| 240 | #endif
|
---|
[2] | 241 | #ifdef Q_WS_X11
|
---|
| 242 | const char *weightName;
|
---|
| 243 | const char *setwidthName;
|
---|
| 244 | #endif // Q_WS_X11
|
---|
| 245 |
|
---|
[8] | 246 | #ifdef Q_WS_PM
|
---|
| 247 | QtFontSize *pixelSize(
|
---|
| 248 | unsigned short size, bool = FALSE, unsigned short pointSize = 0 );
|
---|
| 249 | #else
|
---|
[2] | 250 | QtFontSize *pixelSize( unsigned short size, bool = FALSE );
|
---|
[8] | 251 | #endif
|
---|
[2] | 252 | };
|
---|
| 253 |
|
---|
| 254 | QtFontStyle::Key::Key( const QString &styleString )
|
---|
| 255 | : italic( FALSE ), oblique( FALSE ), weight( QFont::Normal ), stretch( 0 )
|
---|
| 256 | {
|
---|
| 257 | weight = getFontWeight( styleString );
|
---|
| 258 |
|
---|
| 259 | if ( styleString.contains( "Italic" ) )
|
---|
| 260 | italic = TRUE;
|
---|
| 261 | else if ( styleString.contains( "Oblique" ) )
|
---|
| 262 | oblique = TRUE;
|
---|
| 263 | }
|
---|
| 264 |
|
---|
[8] | 265 | #ifdef Q_WS_PM
|
---|
| 266 | QtFontSize *QtFontStyle::pixelSize(
|
---|
| 267 | unsigned short size, bool add, unsigned short pointSize )
|
---|
| 268 | #else
|
---|
[2] | 269 | QtFontSize *QtFontStyle::pixelSize( unsigned short size, bool add )
|
---|
[8] | 270 | #endif
|
---|
[2] | 271 | {
|
---|
| 272 | for ( int i = 0; i < count; i++ ) {
|
---|
[8] | 273 | #ifdef Q_WS_PM
|
---|
| 274 | if (
|
---|
| 275 | pixelSizes[i].pixelSize == size &&
|
---|
| 276 | (
|
---|
| 277 | size == SMOOTH_SCALABLE ||
|
---|
| 278 | !pointSize ||
|
---|
| 279 | pixelSizes[i].pointSize == pointSize
|
---|
| 280 | )
|
---|
| 281 | )
|
---|
| 282 | #else
|
---|
[2] | 283 | if ( pixelSizes[i].pixelSize == size )
|
---|
[8] | 284 | #endif
|
---|
[2] | 285 | return pixelSizes + i;
|
---|
| 286 | }
|
---|
| 287 | if ( !add )
|
---|
| 288 | return 0;
|
---|
| 289 |
|
---|
| 290 | if ( !(count % 8) )
|
---|
| 291 | pixelSizes = (QtFontSize *)
|
---|
| 292 | realloc( pixelSizes,
|
---|
| 293 | (((count+8) >> 3 ) << 3) * sizeof(QtFontSize) );
|
---|
| 294 | pixelSizes[count].pixelSize = size;
|
---|
[8] | 295 | #ifdef Q_WS_PM
|
---|
| 296 | pixelSizes[count].pointSize = pointSize;
|
---|
| 297 | pixelSizes[count].lMatch = 0;
|
---|
| 298 | #endif
|
---|
[2] | 299 | #ifdef Q_WS_X11
|
---|
| 300 | pixelSizes[count].count = 0;
|
---|
| 301 | pixelSizes[count].encodings = 0;
|
---|
| 302 | #endif
|
---|
| 303 | return pixelSizes + (count++);
|
---|
| 304 | }
|
---|
| 305 |
|
---|
| 306 | struct QtFontFoundry
|
---|
| 307 | {
|
---|
| 308 | QtFontFoundry( const QString &n ) : name( n ), count( 0 ), styles( 0 ) {}
|
---|
| 309 | ~QtFontFoundry() {
|
---|
| 310 | while ( count-- )
|
---|
| 311 | delete styles[count];
|
---|
| 312 | free( styles );
|
---|
| 313 | }
|
---|
| 314 |
|
---|
| 315 | QString name;
|
---|
| 316 |
|
---|
| 317 | int count;
|
---|
| 318 | QtFontStyle **styles;
|
---|
| 319 | QtFontStyle *style( const QtFontStyle::Key &, bool = FALSE );
|
---|
| 320 | };
|
---|
| 321 |
|
---|
| 322 | QtFontStyle *QtFontFoundry::style( const QtFontStyle::Key &key, bool create )
|
---|
| 323 | {
|
---|
| 324 | int pos = 0;
|
---|
| 325 | if ( count ) {
|
---|
| 326 | int low = 0;
|
---|
| 327 | int high = count;
|
---|
| 328 | pos = count / 2;
|
---|
| 329 | while ( high > low ) {
|
---|
| 330 | if ( styles[pos]->key == key )
|
---|
| 331 | return styles[pos];
|
---|
| 332 | if ( styles[pos]->key < key )
|
---|
| 333 | low = pos + 1;
|
---|
| 334 | else
|
---|
| 335 | high = pos;
|
---|
| 336 | pos = (high + low) / 2;
|
---|
| 337 | };
|
---|
| 338 | pos = low;
|
---|
| 339 | }
|
---|
| 340 | if ( !create )
|
---|
| 341 | return 0;
|
---|
| 342 |
|
---|
| 343 | // qDebug("adding key (weight=%d, italic=%d, oblique=%d stretch=%d) at %d", key.weight, key.italic, key.oblique, key.stretch, pos );
|
---|
| 344 | if ( !(count % 8) )
|
---|
| 345 | styles = (QtFontStyle **)
|
---|
| 346 | realloc( styles, (((count+8) >> 3 ) << 3) * sizeof( QtFontStyle * ) );
|
---|
| 347 |
|
---|
| 348 | memmove( styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *) );
|
---|
| 349 | styles[pos] = new QtFontStyle( key );
|
---|
| 350 | count++;
|
---|
| 351 | return styles[pos];
|
---|
| 352 | }
|
---|
| 353 |
|
---|
| 354 |
|
---|
| 355 | struct QtFontFamily
|
---|
| 356 | {
|
---|
| 357 | enum ScriptStatus { Unknown = 0, Supported = 1,
|
---|
| 358 | UnSupported_Xft= 2, UnSupported_Xlfd = 4, UnSupported = 6 };
|
---|
| 359 |
|
---|
| 360 | QtFontFamily(const QString &n )
|
---|
| 361 | : fixedPitch( FALSE ),
|
---|
| 362 | #ifdef Q_WS_X11
|
---|
| 363 | hasXft( FALSE ), xftScriptCheck( FALSE ), xlfdLoaded( FALSE ),
|
---|
| 364 | #endif
|
---|
| 365 | #ifdef Q_WS_WIN
|
---|
| 366 | scriptCheck( FALSE ),
|
---|
| 367 | #endif
|
---|
| 368 | #if defined(Q_OS_MAC) && !defined(QWS)
|
---|
| 369 | fixedPitchComputed(FALSE),
|
---|
| 370 | #endif
|
---|
| 371 | fullyLoaded( FALSE ),
|
---|
| 372 | name( n ), count( 0 ), foundries( 0 ) {
|
---|
| 373 | memset( scripts, 0, sizeof( scripts ) );
|
---|
[8] | 374 | #ifdef Q_WS_PM
|
---|
| 375 | //@@TODO (dmik): temporary solution to let QFontDialog work:
|
---|
| 376 | // at least UnknownScript is supported.
|
---|
| 377 | scripts[QFont::UnknownScript] = Supported;
|
---|
| 378 | #endif
|
---|
[2] | 379 | }
|
---|
| 380 | ~QtFontFamily() {
|
---|
| 381 | while ( count-- )
|
---|
| 382 | delete foundries[count];
|
---|
| 383 | free( foundries );
|
---|
| 384 | }
|
---|
| 385 |
|
---|
| 386 | bool fixedPitch : 1;
|
---|
| 387 | #ifdef Q_WS_X11
|
---|
| 388 | bool hasXft : 1;
|
---|
| 389 | bool xftScriptCheck : 1;
|
---|
| 390 | bool xlfdLoaded : 1;
|
---|
| 391 | #endif
|
---|
| 392 | #ifdef Q_WS_WIN
|
---|
| 393 | bool scriptCheck : 1;
|
---|
| 394 | #endif
|
---|
| 395 | #if defined(Q_OS_MAC) && !defined(QWS)
|
---|
| 396 | bool fixedPitchComputed : 1;
|
---|
| 397 | #endif
|
---|
| 398 | bool fullyLoaded : 1;
|
---|
| 399 | QString name;
|
---|
[8] | 400 | #ifndef Q_WS_X11
|
---|
[2] | 401 | QString rawName;
|
---|
[8] | 402 | #endif
|
---|
[2] | 403 | #ifdef Q_WS_X11
|
---|
| 404 | QCString fontFilename;
|
---|
| 405 | int fontFileIndex;
|
---|
| 406 | #endif
|
---|
| 407 | int count;
|
---|
| 408 | QtFontFoundry **foundries;
|
---|
| 409 |
|
---|
| 410 | unsigned char scripts[QFont::LastPrivateScript];
|
---|
| 411 |
|
---|
| 412 | QtFontFoundry *foundry( const QString &f, bool = FALSE );
|
---|
| 413 | };
|
---|
| 414 |
|
---|
| 415 | QtFontFoundry *QtFontFamily::foundry( const QString &f, bool create )
|
---|
| 416 | {
|
---|
| 417 | if ( f.isNull() && count == 1 )
|
---|
| 418 | return foundries[0];
|
---|
| 419 |
|
---|
| 420 | for ( int i = 0; i < count; i++ ) {
|
---|
| 421 | if ( ucstricmp( foundries[i]->name, f ) == 0 )
|
---|
| 422 | return foundries[i];
|
---|
| 423 | }
|
---|
| 424 | if ( !create )
|
---|
| 425 | return 0;
|
---|
| 426 |
|
---|
| 427 | if ( !(count % 8) )
|
---|
| 428 | foundries = (QtFontFoundry **)
|
---|
| 429 | realloc( foundries,
|
---|
| 430 | (((count+8) >> 3 ) << 3) * sizeof( QtFontFoundry * ) );
|
---|
| 431 |
|
---|
| 432 | foundries[count] = new QtFontFoundry( f );
|
---|
| 433 | return foundries[count++];
|
---|
| 434 | }
|
---|
| 435 |
|
---|
| 436 | class QFontDatabasePrivate {
|
---|
| 437 | public:
|
---|
[8] | 438 | QFontDatabasePrivate() :
|
---|
| 439 | count( 0 ), families( 0 ) { }
|
---|
[2] | 440 | ~QFontDatabasePrivate() {
|
---|
[8] | 441 | #ifdef Q_WS_PM
|
---|
| 442 | cleanup();
|
---|
| 443 | #else
|
---|
[2] | 444 | while ( count-- )
|
---|
| 445 | delete families[count];
|
---|
| 446 | free( families );
|
---|
[8] | 447 | #endif
|
---|
[2] | 448 | }
|
---|
| 449 | QtFontFamily *family( const QString &f, bool = FALSE );
|
---|
| 450 |
|
---|
| 451 | int count;
|
---|
| 452 | QtFontFamily **families;
|
---|
[8] | 453 |
|
---|
| 454 | #ifdef Q_WS_PM
|
---|
| 455 | static QFontDatabasePrivate* instance();
|
---|
| 456 | private:
|
---|
| 457 | void cleanup() {
|
---|
| 458 | while ( count )
|
---|
| 459 | delete families[--count];
|
---|
| 460 | free( families );
|
---|
| 461 | families = 0;
|
---|
| 462 | }
|
---|
| 463 | void reload();
|
---|
| 464 | #endif
|
---|
[2] | 465 | };
|
---|
| 466 |
|
---|
| 467 | QtFontFamily *QFontDatabasePrivate::family( const QString &f, bool create )
|
---|
| 468 | {
|
---|
| 469 | int low = 0;
|
---|
| 470 | int high = count;
|
---|
| 471 | int pos = count / 2;
|
---|
| 472 | int res = 1;
|
---|
| 473 | if ( count ) {
|
---|
| 474 | while ( (res = ucstricmp( families[pos]->name, f )) && pos != low ) {
|
---|
| 475 | if ( res > 0 )
|
---|
| 476 | high = pos;
|
---|
| 477 | else
|
---|
| 478 | low = pos;
|
---|
| 479 | pos = (high + low) / 2;
|
---|
| 480 | };
|
---|
| 481 | if ( !res )
|
---|
| 482 | return families[pos];
|
---|
| 483 | }
|
---|
| 484 | if ( !create )
|
---|
| 485 | return 0;
|
---|
| 486 |
|
---|
| 487 | if ( res < 0 )
|
---|
| 488 | pos++;
|
---|
| 489 |
|
---|
| 490 | // qDebug("adding family %s at %d total=%d", f.latin1(), pos, count);
|
---|
| 491 | if ( !(count % 8) )
|
---|
| 492 | families = (QtFontFamily **)
|
---|
| 493 | realloc( families,
|
---|
| 494 | (((count+8) >> 3 ) << 3) * sizeof( QtFontFamily * ) );
|
---|
| 495 |
|
---|
| 496 | memmove( families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *) );
|
---|
| 497 | families[pos] = new QtFontFamily( f );
|
---|
| 498 | count++;
|
---|
| 499 | return families[pos];
|
---|
| 500 | }
|
---|
| 501 |
|
---|
| 502 |
|
---|
| 503 |
|
---|
| 504 |
|
---|
| 505 | #if defined(Q_WS_X11) || defined(Q_WS_WIN)
|
---|
| 506 | static const unsigned short sample_chars[QFont::LastPrivateScript] =
|
---|
| 507 | {
|
---|
| 508 | // European Alphabetic Scripts
|
---|
| 509 | // Latin,
|
---|
| 510 | 0x0041,
|
---|
| 511 | // Greek,
|
---|
| 512 | 0x0390,
|
---|
| 513 | // Cyrillic,
|
---|
| 514 | 0x0410,
|
---|
| 515 | // Armenian,
|
---|
| 516 | 0x0540,
|
---|
| 517 | // Georgian,
|
---|
| 518 | 0x10d0,
|
---|
| 519 | // Runic,
|
---|
| 520 | 0x16a0,
|
---|
| 521 | // Ogham,
|
---|
| 522 | 0x1680,
|
---|
| 523 | // SpacingModifiers,
|
---|
| 524 | 0x02b0,
|
---|
| 525 | // CombiningMarks,
|
---|
| 526 | 0x0300,
|
---|
| 527 |
|
---|
| 528 | // Middle Eastern Scripts
|
---|
| 529 | // Hebrew,
|
---|
| 530 | 0x05d0,
|
---|
| 531 | // Arabic,
|
---|
| 532 | 0x0630,
|
---|
| 533 | // Syriac,
|
---|
| 534 | 0x0710,
|
---|
| 535 | // Thaana,
|
---|
| 536 | 0x0780,
|
---|
| 537 |
|
---|
| 538 | // South and Southeast Asian Scripts
|
---|
| 539 | // Devanagari,
|
---|
| 540 | 0x0910,
|
---|
| 541 | // Bengali,
|
---|
| 542 | 0x0990,
|
---|
| 543 | // Gurmukhi,
|
---|
| 544 | 0x0a10,
|
---|
| 545 | // Gujarati,
|
---|
| 546 | 0x0a90,
|
---|
| 547 | // Oriya,
|
---|
| 548 | 0x0b10,
|
---|
| 549 | // Tamil,
|
---|
| 550 | 0x0b90,
|
---|
| 551 | // Telugu,
|
---|
| 552 | 0x0c10,
|
---|
| 553 | // Kannada,
|
---|
| 554 | 0x0c90,
|
---|
| 555 | // Malayalam,
|
---|
| 556 | 0x0d10,
|
---|
| 557 | // Sinhala,
|
---|
| 558 | 0x0d90,
|
---|
| 559 | // Thai,
|
---|
| 560 | 0x0e10,
|
---|
| 561 | // Lao,
|
---|
| 562 | 0x0e81,
|
---|
| 563 | // Tibetan,
|
---|
| 564 | 0x0f00,
|
---|
| 565 | // Myanmar,
|
---|
| 566 | 0x1000,
|
---|
| 567 | // Khmer,
|
---|
| 568 | 0x1780,
|
---|
| 569 |
|
---|
| 570 | // East Asian Scripts
|
---|
| 571 | // Han,
|
---|
| 572 | 0x4e00,
|
---|
| 573 | // Hiragana,
|
---|
| 574 | 0x3050,
|
---|
| 575 | // Katakana,
|
---|
| 576 | 0x30b0,
|
---|
| 577 | // Hangul,
|
---|
| 578 | 0xac00,
|
---|
| 579 | // Bopomofo,
|
---|
| 580 | 0x3110,
|
---|
| 581 | // Yi,
|
---|
| 582 | 0xa000,
|
---|
| 583 |
|
---|
| 584 | // Additional Scripts
|
---|
| 585 | // Ethiopic,
|
---|
| 586 | 0x1200,
|
---|
| 587 | // Cherokee,
|
---|
| 588 | 0x13a0,
|
---|
| 589 | // CanadianAboriginal,
|
---|
| 590 | 0x1410,
|
---|
| 591 | // Mongolian,
|
---|
| 592 | 0x1800,
|
---|
| 593 |
|
---|
| 594 | // Symbols
|
---|
| 595 | // CurrencySymbols,
|
---|
| 596 | 0x20aa,
|
---|
| 597 | // LetterlikeSymbols,
|
---|
| 598 | 0x2122,
|
---|
| 599 | // NumberForms,
|
---|
| 600 | 0x215b,
|
---|
| 601 | // MathematicalOperators,
|
---|
| 602 | 0x222b,
|
---|
| 603 | // TechnicalSymbols,
|
---|
| 604 | 0x2440,
|
---|
| 605 | // GeometricSymbols,
|
---|
| 606 | 0x2500,
|
---|
| 607 | // MiscellaneousSymbols,
|
---|
| 608 | 0x2600,
|
---|
| 609 | // EnclosedAndSquare,
|
---|
| 610 | 0x2460,
|
---|
| 611 | // Braille,
|
---|
| 612 | 0x2800,
|
---|
| 613 |
|
---|
| 614 | // Unicode,
|
---|
| 615 | 0xfffd,
|
---|
| 616 |
|
---|
| 617 | // some scripts added in Unicode 3.2
|
---|
| 618 | // Tagalog,
|
---|
| 619 | 0x1700,
|
---|
| 620 | // Hanunoo,
|
---|
| 621 | 0x1720,
|
---|
| 622 | // Buhid,
|
---|
| 623 | 0x1740,
|
---|
| 624 | // Tagbanwa,
|
---|
| 625 | 0x1770,
|
---|
| 626 |
|
---|
| 627 | // KatakanaHalfWidth
|
---|
| 628 | 0xff65,
|
---|
| 629 |
|
---|
| 630 | // Limbu
|
---|
| 631 | 0x1901,
|
---|
| 632 | // TaiLe
|
---|
| 633 | 0x1950,
|
---|
| 634 |
|
---|
| 635 | // NScripts
|
---|
| 636 | 0x0000,
|
---|
| 637 | // NoScript
|
---|
| 638 | 0x0000,
|
---|
| 639 |
|
---|
| 640 | // Han_Japanese
|
---|
| 641 | 0x4e00,
|
---|
| 642 | // Han_SimplifiedChinese,
|
---|
| 643 | 0x4e00,
|
---|
| 644 | // Han_TraditionalChinese,
|
---|
| 645 | 0x4e00,
|
---|
| 646 | // Han_Korean
|
---|
| 647 | 0x4e00
|
---|
| 648 | };
|
---|
| 649 |
|
---|
| 650 | #if defined(Q_WS_X11) && !defined(QT_NO_XFTFREETYPE)
|
---|
| 651 | static inline bool requiresOpenType(QFont::Script s)
|
---|
| 652 | {
|
---|
| 653 | return (s >= QFont::Syriac && s <= QFont::Sinhala)
|
---|
| 654 | || (s >= QFont::Tibetan && s <= QFont::Khmer);
|
---|
| 655 | }
|
---|
| 656 | #endif
|
---|
| 657 |
|
---|
| 658 | // returns a sample unicode character for the specified script
|
---|
| 659 | static QChar sampleCharacter(QFont::Script script)
|
---|
| 660 | {
|
---|
| 661 | return QChar(sample_chars[script]);
|
---|
| 662 | }
|
---|
| 663 |
|
---|
| 664 | static inline bool canRender( QFontEngine *fe, QFont::Script script )
|
---|
| 665 | {
|
---|
| 666 | if ( !fe ) return FALSE;
|
---|
| 667 |
|
---|
| 668 | QChar sample = sampleCharacter(script);
|
---|
| 669 | bool hasChar = fe->canRender( &sample, 1 );
|
---|
| 670 |
|
---|
| 671 | #ifdef FONT_MATCH_DEBUG
|
---|
| 672 | if (hasChar)
|
---|
| 673 | FM_DEBUG(" font has char 0x%04x", sample.unicode() );
|
---|
| 674 | #endif
|
---|
| 675 | #if defined(Q_WS_X11) && !defined(QT_NO_XFTFREETYPE)
|
---|
| 676 | if (hasChar && requiresOpenType(script)) {
|
---|
| 677 | QOpenType *ot = fe->openType();
|
---|
| 678 | if (!ot || !ot->supportsScript(script))
|
---|
| 679 | return false;
|
---|
| 680 | }
|
---|
| 681 | #endif
|
---|
| 682 |
|
---|
| 683 | return hasChar;
|
---|
| 684 | }
|
---|
| 685 | #endif // Q_WS_X11 || Q_WS_WIN
|
---|
| 686 |
|
---|
| 687 |
|
---|
| 688 | static QSingleCleanupHandler<QFontDatabasePrivate> qfontdatabase_cleanup;
|
---|
[8] | 689 | #ifdef Q_WS_PM
|
---|
| 690 | QFontDatabasePrivate* QFontDatabasePrivate::instance()
|
---|
| 691 | {
|
---|
| 692 | static QFontDatabasePrivate *db = 0;
|
---|
| 693 | if ( !db ) {
|
---|
| 694 | db = new QFontDatabasePrivate;
|
---|
| 695 | qfontdatabase_cleanup.set(&db);
|
---|
| 696 | db->reload();
|
---|
| 697 | }
|
---|
| 698 | return db;
|
---|
| 699 | }
|
---|
| 700 | #else
|
---|
[2] | 701 | static QFontDatabasePrivate *db=0;
|
---|
[8] | 702 | #endif
|
---|
[2] | 703 |
|
---|
| 704 | #if defined( Q_WS_X11 )
|
---|
| 705 | # include "qfontdatabase_x11.cpp"
|
---|
| 706 | #elif defined( Q_WS_MAC )
|
---|
| 707 | # include "qfontdatabase_mac.cpp"
|
---|
| 708 | #elif defined( Q_WS_WIN )
|
---|
| 709 | # include "qfontdatabase_win.cpp"
|
---|
[8] | 710 | #elif defined( Q_WS_PM )
|
---|
| 711 | # include "qfontdatabase_pm.cpp"
|
---|
[2] | 712 | #elif defined( Q_WS_QWS )
|
---|
| 713 | # include "qfontdatabase_qws.cpp"
|
---|
| 714 | #endif
|
---|
| 715 |
|
---|
| 716 |
|
---|
| 717 |
|
---|
| 718 |
|
---|
[8] | 719 | #if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_PM)
|
---|
[2] | 720 | static
|
---|
| 721 | unsigned int bestFoundry( QFont::Script script, unsigned int score, int styleStrategy,
|
---|
| 722 | const QtFontFamily *family, const QString &foundry_name,
|
---|
| 723 | QtFontStyle::Key styleKey, int pixelSize, char pitch,
|
---|
| 724 | QtFontFoundry **best_foundry, QtFontStyle **best_style,
|
---|
| 725 | QtFontSize **best_size
|
---|
[8] | 726 | #if defined(Q_WS_X11)
|
---|
[2] | 727 | , QtFontEncoding **best_encoding, int force_encoding_id
|
---|
[8] | 728 | #elif defined(Q_WS_PM)
|
---|
| 729 | , int pointSize
|
---|
[2] | 730 | #endif
|
---|
| 731 | )
|
---|
| 732 | {
|
---|
| 733 | Q_UNUSED( script );
|
---|
| 734 | Q_UNUSED( pitch );
|
---|
| 735 |
|
---|
| 736 | FM_DEBUG( " REMARK: looking for best foundry for family '%s'", family->name.latin1() );
|
---|
| 737 |
|
---|
| 738 | for ( int x = 0; x < family->count; ++x ) {
|
---|
| 739 | QtFontFoundry *foundry = family->foundries[x];
|
---|
| 740 | if ( ! foundry_name.isEmpty() &&
|
---|
| 741 | ucstricmp( foundry->name, foundry_name ) != 0 )
|
---|
| 742 | continue;
|
---|
| 743 |
|
---|
| 744 | FM_DEBUG( " looking for matching style in foundry '%s'",
|
---|
| 745 | foundry->name.isEmpty() ? "-- none --" : foundry->name.latin1() );
|
---|
| 746 |
|
---|
| 747 | QtFontStyle *style = 0;
|
---|
| 748 | int best = 0;
|
---|
| 749 | int dist = 0xffff;
|
---|
| 750 |
|
---|
| 751 | for ( int i = 0; i < foundry->count; i++ ) {
|
---|
| 752 | style = foundry->styles[i];
|
---|
| 753 |
|
---|
| 754 | int d = QABS( styleKey.weight - style->key.weight );
|
---|
| 755 |
|
---|
| 756 | if ( styleKey.stretch != 0 && style->key.stretch != 0 ) {
|
---|
| 757 | d += QABS( styleKey.stretch - style->key.stretch );
|
---|
| 758 | }
|
---|
| 759 |
|
---|
| 760 | if ( styleKey.italic ) {
|
---|
| 761 | if ( !style->key.italic )
|
---|
| 762 | d += style->key.oblique ? 0x0800 : 0x1000;
|
---|
| 763 | } else if ( styleKey.oblique ) {
|
---|
| 764 | if (!style->key.oblique )
|
---|
| 765 | d += style->key.italic ? 0x0800 : 0x1000;
|
---|
| 766 | } else if ( style->key.italic || style->key.oblique ) {
|
---|
| 767 | d += 0x1000;
|
---|
| 768 | }
|
---|
| 769 |
|
---|
| 770 | if ( d < dist ) {
|
---|
| 771 | best = i;
|
---|
| 772 | dist = d;
|
---|
| 773 | }
|
---|
| 774 | }
|
---|
| 775 |
|
---|
| 776 | FM_DEBUG( " best style has distance 0x%x", dist );
|
---|
| 777 | style = foundry->styles[best];
|
---|
| 778 |
|
---|
| 779 | if ( ! style->smoothScalable && ( styleStrategy & QFont::ForceOutline ) ) {
|
---|
| 780 | FM_DEBUG( " ForceOutline set, but not smoothly scalable" );
|
---|
| 781 | continue;
|
---|
| 782 | }
|
---|
| 783 |
|
---|
| 784 | int px = -1;
|
---|
| 785 | QtFontSize *size = 0;
|
---|
| 786 |
|
---|
| 787 | // 1. see if we have an exact matching size
|
---|
| 788 | if (! (styleStrategy & QFont::ForceOutline)) {
|
---|
[8] | 789 | #if defined(Q_WS_PM)
|
---|
| 790 | size = style->pixelSize(pixelSize, FALSE, pointSize);
|
---|
| 791 | #else
|
---|
[2] | 792 | size = style->pixelSize(pixelSize);
|
---|
[8] | 793 | #endif
|
---|
[2] | 794 | if (size) px = size->pixelSize;
|
---|
| 795 | }
|
---|
| 796 |
|
---|
| 797 | // 2. see if we have a smoothly scalable font
|
---|
| 798 | if (! size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
|
---|
| 799 | size = style->pixelSize(SMOOTH_SCALABLE);
|
---|
| 800 | if (size) px = pixelSize;
|
---|
| 801 | }
|
---|
| 802 |
|
---|
| 803 | // 3. see if we have a bitmap scalable font
|
---|
| 804 | if (! size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
|
---|
| 805 | size = style->pixelSize(0);
|
---|
| 806 | if (size) px = pixelSize;
|
---|
| 807 | }
|
---|
| 808 |
|
---|
| 809 | // 4. find closest size match
|
---|
| 810 | if (! size) {
|
---|
| 811 | unsigned int distance = ~0u;
|
---|
| 812 | for (int x = 0; x < style->count; ++x) {
|
---|
| 813 | unsigned int d = QABS(style->pixelSizes[x].pixelSize - pixelSize);
|
---|
| 814 | if (d < distance) {
|
---|
| 815 | distance = d;
|
---|
| 816 | size = style->pixelSizes + x;
|
---|
| 817 | }
|
---|
| 818 | }
|
---|
| 819 |
|
---|
| 820 | if (style->bitmapScalable && ! (styleStrategy & QFont::PreferQuality) &&
|
---|
| 821 | (distance * 10 / pixelSize) >= 2) {
|
---|
| 822 | // the closest size is not close enough, go ahead and
|
---|
| 823 | // use a bitmap scaled font
|
---|
| 824 | size = style->pixelSize(0);
|
---|
| 825 | px = pixelSize;
|
---|
| 826 | } else {
|
---|
| 827 | px = size->pixelSize;
|
---|
| 828 | }
|
---|
| 829 | }
|
---|
| 830 |
|
---|
| 831 | #ifdef Q_WS_X11
|
---|
| 832 | QtFontEncoding *encoding = 0;
|
---|
| 833 | if ( force_encoding_id >= 0 ) {
|
---|
| 834 | encoding = size->encodingID( force_encoding_id );
|
---|
| 835 | if ( ! encoding ) {
|
---|
| 836 | FM_DEBUG( " required encoding_id not available" );
|
---|
| 837 | continue;
|
---|
| 838 | }
|
---|
| 839 | } else {
|
---|
| 840 | encoding = size->encodingID( -1 ); // -1 == prefer Xft
|
---|
| 841 |
|
---|
| 842 | if ( encoding && ( styleStrategy & ( QFont::OpenGLCompatible |
|
---|
| 843 | QFont::PreferBitmap ) ) ) {
|
---|
| 844 | FM_DEBUG( " PreferBitmap and/or OpenGL set, skipping Xft" );
|
---|
| 845 | continue;
|
---|
| 846 | }
|
---|
| 847 |
|
---|
| 848 | if ( ! encoding ) { // Xft not available, find an XLFD font
|
---|
| 849 | // try the default encoding first
|
---|
| 850 | encoding = size->encodingID( QFontPrivate::defaultEncodingID );
|
---|
| 851 |
|
---|
| 852 | if ( ! encoding || ! scripts_for_xlfd_encoding[encoding->encoding][script] ) {
|
---|
| 853 | // find the first encoding that supports the requested script
|
---|
| 854 | encoding = 0;
|
---|
| 855 | for (int x = 0; !encoding && x < size->count; ++x ) {
|
---|
| 856 | const int enc = size->encodings[x].encoding;
|
---|
| 857 | if ( scripts_for_xlfd_encoding[enc][script] ) {
|
---|
| 858 | encoding = &size->encodings[x];
|
---|
| 859 | break;
|
---|
| 860 | }
|
---|
| 861 | }
|
---|
| 862 | }
|
---|
| 863 | }
|
---|
| 864 | }
|
---|
| 865 |
|
---|
| 866 | if ( ! encoding ) {
|
---|
| 867 | FM_DEBUG( " foundry doesn't support the script we want" );
|
---|
| 868 | continue;
|
---|
| 869 | }
|
---|
| 870 | #endif // Q_WS_X11
|
---|
| 871 |
|
---|
| 872 | unsigned int this_score = 0x0000;
|
---|
| 873 | #ifdef Q_WS_X11
|
---|
| 874 | if ( encoding->encoding != -1 ) {
|
---|
| 875 | this_score += 1;
|
---|
| 876 | if ( encoding->encoding != QFontPrivate::defaultEncodingID )
|
---|
| 877 | this_score += 10;
|
---|
| 878 | }
|
---|
| 879 | if (pitch != '*') {
|
---|
| 880 | if ( !( pitch == 'm' && encoding->pitch == 'c' ) && pitch != encoding->pitch )
|
---|
| 881 | this_score += 200;
|
---|
| 882 | }
|
---|
| 883 | #else
|
---|
| 884 | if (pitch != '*') {
|
---|
| 885 | if ((pitch == 'm' && !family->fixedPitch)
|
---|
| 886 | || (pitch == 'p' && family->fixedPitch))
|
---|
| 887 | this_score += 200;
|
---|
| 888 | }
|
---|
| 889 | #endif
|
---|
| 890 | if ( styleKey != style->key )
|
---|
| 891 | this_score += 100;
|
---|
| 892 | if ( !style->smoothScalable && px != size->pixelSize ) // bitmap scaled
|
---|
| 893 | this_score += 50;
|
---|
| 894 |
|
---|
| 895 | if ( this_score < score ) {
|
---|
| 896 | FM_DEBUG( " found a match: score %u best score so far %u",
|
---|
| 897 | this_score, score );
|
---|
| 898 |
|
---|
| 899 | score = this_score;
|
---|
| 900 | *best_foundry = foundry;
|
---|
| 901 | *best_style = style;
|
---|
| 902 | *best_size = size;
|
---|
| 903 | #ifdef Q_WS_X11
|
---|
| 904 | *best_encoding = encoding;
|
---|
| 905 | #endif // Q_WS_X11
|
---|
| 906 | } else {
|
---|
| 907 | FM_DEBUG( " score %u no better than best %u", this_score, score);
|
---|
| 908 | }
|
---|
| 909 | }
|
---|
| 910 |
|
---|
| 911 | return score;
|
---|
| 912 | }
|
---|
| 913 |
|
---|
| 914 | /*!
|
---|
| 915 | \internal
|
---|
| 916 | */
|
---|
| 917 | QFontEngine *
|
---|
| 918 | QFontDatabase::findFont( QFont::Script script, const QFontPrivate *fp,
|
---|
| 919 | const QFontDef &request, int force_encoding_id )
|
---|
| 920 | {
|
---|
| 921 | #ifndef Q_WS_X11
|
---|
| 922 | Q_UNUSED( force_encoding_id );
|
---|
| 923 | #endif
|
---|
| 924 |
|
---|
[8] | 925 | #ifdef Q_WS_PM
|
---|
| 926 | QFontDatabasePrivate *db = QFontDatabasePrivate::instance();
|
---|
| 927 | #else
|
---|
[2] | 928 | if ( !db )
|
---|
| 929 | initializeDb();
|
---|
[8] | 930 | #endif
|
---|
[2] | 931 |
|
---|
| 932 | QFontEngine *fe = 0;
|
---|
| 933 | if ( fp ) {
|
---|
[8] | 934 | #ifndef Q_WS_PM
|
---|
[2] | 935 | if ( fp->rawMode ) {
|
---|
| 936 | fe = loadEngine( script, fp, request, 0, 0, 0
|
---|
| 937 | #ifdef Q_WS_X11
|
---|
| 938 | , 0, 0, FALSE
|
---|
| 939 | #endif
|
---|
| 940 | );
|
---|
| 941 |
|
---|
| 942 | // if we fail to load the rawmode font, use a 12pixel box engine instead
|
---|
| 943 | if (! fe) fe = new QFontEngineBox( 12 );
|
---|
| 944 | return fe;
|
---|
| 945 | }
|
---|
[8] | 946 | #endif // !Q_WS_PM
|
---|
[2] | 947 |
|
---|
| 948 | QFontCache::Key key( request, script,
|
---|
[8] | 949 | #if defined(Q_WS_WIN) || defined(Q_WS_PM)
|
---|
[2] | 950 | (int)fp->paintdevice
|
---|
| 951 | #else
|
---|
| 952 | fp->screen
|
---|
| 953 | #endif
|
---|
| 954 | );
|
---|
| 955 | fe = QFontCache::instance->findEngine( key );
|
---|
| 956 | if ( fe ) return fe;
|
---|
| 957 | }
|
---|
| 958 |
|
---|
| 959 | QString family_name, foundry_name;
|
---|
| 960 | QtFontStyle::Key styleKey;
|
---|
| 961 | styleKey.italic = request.italic;
|
---|
| 962 | styleKey.weight = request.weight;
|
---|
| 963 | styleKey.stretch = request.stretch;
|
---|
| 964 | char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';
|
---|
| 965 |
|
---|
| 966 | parseFontName( request.family, foundry_name, family_name );
|
---|
| 967 |
|
---|
[8] | 968 | #ifdef Q_WS_PM
|
---|
| 969 | // the "System VIO" PM font is broken in such way that its real pixel
|
---|
| 970 | // sizes do not correspond to their nominal point sizes specified in the
|
---|
| 971 | // font header (i.e. pixelSize is not equal to (pointSize * dpi) / 720).
|
---|
| 972 | // therefore we use the special table to convert pointSize to pixelSize
|
---|
| 973 | // in order to let bestFoundry() select the proper font with its nominal
|
---|
| 974 | // point size corresponding to the requested one.
|
---|
| 975 | // NOTE: this will produce incorrect results if "System VIO" is NOT
|
---|
| 976 | // an OS/2 standatd supplied bitmap font.
|
---|
| 977 | if( !ucstricmp( family_name, "System VIO") ) {
|
---|
| 978 | // possible sizes of the "System VIO" font ("pixel, point" pairs),
|
---|
| 979 | // sorted by point size
|
---|
| 980 | static const short SystemVIO_sz[] = {
|
---|
| 981 | 12, 20, 16, 30,
|
---|
| 982 | 8, 40, 13, 50,
|
---|
| 983 | 15, 60, 24, 70,
|
---|
| 984 | 8, 80, 10, 90,
|
---|
| 985 | 12, 100, 14, 110,
|
---|
| 986 | 16, 120, 18, 130,
|
---|
| 987 | 16, 140, 12, 150,
|
---|
| 988 | 20, 160, 21, 170,
|
---|
| 989 | 29, 180,
|
---|
| 990 | };
|
---|
| 991 | const int SystemVIO_sz_len = sizeof(SystemVIO_sz) / sizeof(SystemVIO_sz[0]);
|
---|
| 992 | int pt = request.pointSize;
|
---|
| 993 | pt = QMAX( pt, SystemVIO_sz [1] ); // min limit
|
---|
| 994 | pt = QMIN( pt, SystemVIO_sz [SystemVIO_sz_len - 1] ); // max limit
|
---|
| 995 | int i = 1;
|
---|
| 996 | while ( SystemVIO_sz[i] < pt ) i += 2;
|
---|
| 997 | if ( SystemVIO_sz[i] > pt ) {
|
---|
| 998 | int prev = SystemVIO_sz[i-2];
|
---|
| 999 | int mid = prev + (SystemVIO_sz[i] - prev + 1) / 2;
|
---|
| 1000 | if ( pt < mid ) i -= 2;
|
---|
| 1001 | }
|
---|
| 1002 | ((QFontDef&)request).pixelSize = SystemVIO_sz[i-1];
|
---|
| 1003 | ((QFontDef&)request).pointSize = SystemVIO_sz[i];
|
---|
| 1004 | }
|
---|
| 1005 | #endif
|
---|
| 1006 |
|
---|
[2] | 1007 | #ifdef Q_WS_X11
|
---|
| 1008 | if (family_name.isEmpty() && script == QFont::Han) {
|
---|
| 1009 | // modify script according to locale
|
---|
| 1010 | static QFont::Script defaultHan = QFont::UnknownScript;
|
---|
| 1011 | if (defaultHan == QFont::UnknownScript) {
|
---|
| 1012 | QCString locale = setlocale(LC_ALL, NULL);
|
---|
| 1013 | if (locale.contains("ko"))
|
---|
| 1014 | defaultHan = QFont::Han_Korean;
|
---|
| 1015 | else if (locale.contains("zh_TW"))
|
---|
| 1016 | defaultHan = QFont::Han_TraditionalChinese;
|
---|
| 1017 | else if (locale.contains("zh"))
|
---|
| 1018 | defaultHan = QFont::Han_SimplifiedChinese;
|
---|
| 1019 | else
|
---|
| 1020 | defaultHan = QFont::Han_Japanese;
|
---|
| 1021 | }
|
---|
| 1022 | script = defaultHan;
|
---|
| 1023 | }
|
---|
| 1024 | #endif
|
---|
| 1025 |
|
---|
| 1026 | FM_DEBUG( "QFontDatabase::findFont\n"
|
---|
| 1027 | " request:\n"
|
---|
| 1028 | " family: %s [%s], script: %d (%s)\n"
|
---|
| 1029 | " weight: %d, italic: %d\n"
|
---|
| 1030 | " stretch: %d\n"
|
---|
| 1031 | " pixelSize: %d\n"
|
---|
[8] | 1032 | " pointSize: %d\n"
|
---|
[2] | 1033 | " pitch: %c",
|
---|
| 1034 | family_name.isEmpty() ? "-- first in script --" : family_name.latin1(),
|
---|
| 1035 | foundry_name.isEmpty() ? "-- any --" : foundry_name.latin1(),
|
---|
| 1036 | script, scriptName( script ).latin1(),
|
---|
[8] | 1037 | request.weight, request.italic, request.stretch,
|
---|
| 1038 | request.pixelSize, request.pointSize,
|
---|
| 1039 | pitch );
|
---|
[2] | 1040 |
|
---|
| 1041 | #ifdef QT_XFT2
|
---|
| 1042 | if (family_name.isEmpty()
|
---|
| 1043 | || family_name == "Sans Serif"
|
---|
| 1044 | || family_name == "Serif"
|
---|
| 1045 | || family_name == "Monospace") {
|
---|
| 1046 | fe = loadFontConfigFont(fp, request, script);
|
---|
| 1047 | }
|
---|
| 1048 | if (!fe)
|
---|
| 1049 | #endif
|
---|
| 1050 | {
|
---|
| 1051 | QtFontFamily *best_family = 0;
|
---|
| 1052 | QtFontFoundry *best_foundry = 0;
|
---|
| 1053 | QtFontStyle *best_style = 0;
|
---|
| 1054 | QtFontSize *best_size = 0;
|
---|
| 1055 | #ifdef Q_WS_X11
|
---|
| 1056 | QtFontEncoding *best_encoding = 0;
|
---|
| 1057 | #endif // Q_WS_X11
|
---|
| 1058 |
|
---|
| 1059 | unsigned int score = ~0;
|
---|
| 1060 |
|
---|
| 1061 | load( family_name, script );
|
---|
| 1062 |
|
---|
| 1063 | for ( int x = 0; x < db->count; ++x ) {
|
---|
| 1064 | QtFontFamily *try_family = db->families[x];
|
---|
| 1065 | if ( !family_name.isEmpty() &&
|
---|
| 1066 | ucstricmp( try_family->name, family_name ) != 0 )
|
---|
| 1067 | continue;
|
---|
| 1068 |
|
---|
| 1069 | if ( family_name.isEmpty() )
|
---|
| 1070 | load( try_family->name, script );
|
---|
| 1071 |
|
---|
| 1072 | uint score_adjust = 0;
|
---|
| 1073 | QFont::Script override_script = script;
|
---|
[8] | 1074 | #ifndef Q_WS_PM
|
---|
[2] | 1075 | if ( ! ( try_family->scripts[script] & QtFontFamily::Supported )
|
---|
| 1076 | && script != QFont::Unicode) {
|
---|
| 1077 | // family not supported in the script we want
|
---|
| 1078 | #ifdef Q_WS_X11
|
---|
| 1079 | if (script >= QFont::Han_Japanese && script <= QFont::Han_Korean
|
---|
| 1080 | && try_family->scripts[QFont::Han] == QtFontFamily::Supported) {
|
---|
| 1081 | // try with the han script instead, give it a penalty
|
---|
| 1082 | if (override_script == QFont::Han_TraditionalChinese
|
---|
| 1083 | && (try_family->scripts[QFont::Han_SimplifiedChinese] & QtFontFamily::Supported)) {
|
---|
| 1084 | override_script = QFont::Han_SimplifiedChinese;
|
---|
| 1085 | score_adjust = 200;
|
---|
| 1086 | } else if (override_script == QFont::Han_SimplifiedChinese
|
---|
| 1087 | && (try_family->scripts[QFont::Han_TraditionalChinese] & QtFontFamily::Supported)) {
|
---|
| 1088 | override_script = QFont::Han_TraditionalChinese;
|
---|
| 1089 | score_adjust = 200;
|
---|
| 1090 | } else {
|
---|
| 1091 | override_script = QFont::Han;
|
---|
| 1092 | score_adjust = 400;
|
---|
| 1093 | }
|
---|
| 1094 | } else
|
---|
| 1095 | #endif
|
---|
| 1096 | if (family_name.isEmpty()) {
|
---|
| 1097 | continue;
|
---|
| 1098 | } else if (try_family->scripts[QFont::UnknownScript] & QtFontFamily::Supported) {
|
---|
| 1099 | // try with the unknown script (for a symbol font)
|
---|
| 1100 | override_script = QFont::UnknownScript;
|
---|
| 1101 | } else if (try_family->scripts[QFont::Unicode] & QtFontFamily::Supported) {
|
---|
| 1102 | // try with the unicode script instead
|
---|
| 1103 | override_script = QFont::Unicode;
|
---|
| 1104 | } else {
|
---|
| 1105 | // family not supported by unicode/unknown scripts
|
---|
| 1106 | continue;
|
---|
| 1107 | }
|
---|
| 1108 | }
|
---|
[8] | 1109 | #endif // !Q_WS_PM
|
---|
[2] | 1110 |
|
---|
| 1111 | QtFontFoundry *try_foundry = 0;
|
---|
| 1112 | QtFontStyle *try_style = 0;
|
---|
| 1113 | QtFontSize *try_size = 0;
|
---|
| 1114 | #ifdef Q_WS_X11
|
---|
| 1115 | QtFontEncoding *try_encoding = 0;
|
---|
| 1116 | #endif // Q_WS_X11
|
---|
| 1117 |
|
---|
| 1118 | // as we know the script is supported, we can be sure
|
---|
| 1119 | // to find a matching font here.
|
---|
| 1120 | unsigned int newscore =
|
---|
| 1121 | bestFoundry( override_script, score, request.styleStrategy,
|
---|
| 1122 | try_family, foundry_name, styleKey, request.pixelSize, pitch,
|
---|
| 1123 | &try_foundry, &try_style, &try_size
|
---|
[8] | 1124 | #if defined(Q_WS_X11)
|
---|
[2] | 1125 | , &try_encoding, force_encoding_id
|
---|
[8] | 1126 | #elif defined(Q_WS_PM)
|
---|
| 1127 | , request.pointSize
|
---|
[2] | 1128 | #endif
|
---|
| 1129 | );
|
---|
| 1130 | if ( try_foundry == 0 ) {
|
---|
| 1131 | // the specific foundry was not found, so look for
|
---|
| 1132 | // any foundry matching our requirements
|
---|
| 1133 | newscore = bestFoundry( override_script, score, request.styleStrategy, try_family,
|
---|
| 1134 | QString::null, styleKey, request.pixelSize,
|
---|
| 1135 | pitch, &try_foundry, &try_style, &try_size
|
---|
[8] | 1136 | #if defined(Q_WS_X11)
|
---|
[2] | 1137 | , &try_encoding, force_encoding_id
|
---|
[8] | 1138 | #elif defined(Q_WS_PM)
|
---|
| 1139 | , request.pointSize
|
---|
[2] | 1140 | #endif
|
---|
| 1141 | );
|
---|
| 1142 | }
|
---|
| 1143 | newscore += score_adjust;
|
---|
| 1144 |
|
---|
| 1145 | if ( newscore < score ) {
|
---|
| 1146 | score = newscore;
|
---|
| 1147 | best_family = try_family;
|
---|
| 1148 | best_foundry = try_foundry;
|
---|
| 1149 | best_style = try_style;
|
---|
| 1150 | best_size = try_size;
|
---|
| 1151 | #ifdef Q_WS_X11
|
---|
| 1152 | best_encoding = try_encoding;
|
---|
| 1153 | #endif // Q_WS_X11
|
---|
| 1154 | }
|
---|
| 1155 | if ( newscore < 10 ) // xlfd instead of xft... just accept it
|
---|
| 1156 | break;
|
---|
| 1157 | }
|
---|
| 1158 |
|
---|
| 1159 | if ( best_family != 0 && best_foundry != 0 && best_style != 0
|
---|
| 1160 | #ifdef Q_WS_X11
|
---|
| 1161 | && best_size != 0 && best_encoding != 0
|
---|
| 1162 | #endif
|
---|
| 1163 | ) {
|
---|
| 1164 | FM_DEBUG( " BEST:\n"
|
---|
| 1165 | " family: %s [%s]\n"
|
---|
| 1166 | " weight: %d, italic: %d, oblique: %d\n"
|
---|
| 1167 | " stretch: %d\n"
|
---|
| 1168 | " pixelSize: %d\n"
|
---|
| 1169 | " pitch: %c\n"
|
---|
| 1170 | " encoding: %d\n",
|
---|
| 1171 | best_family->name.latin1(),
|
---|
| 1172 | best_foundry->name.isEmpty() ? "-- none --" : best_foundry->name.latin1(),
|
---|
| 1173 | best_style->key.weight, best_style->key.italic, best_style->key.oblique,
|
---|
| 1174 | best_style->key.stretch, best_size ? best_size->pixelSize : 0xffff,
|
---|
| 1175 | #ifdef Q_WS_X11
|
---|
| 1176 | best_encoding->pitch, best_encoding->encoding
|
---|
| 1177 | #else
|
---|
| 1178 | 'p', 0
|
---|
| 1179 | #endif
|
---|
| 1180 | );
|
---|
| 1181 |
|
---|
| 1182 | fe = loadEngine( script, fp, request, best_family, best_foundry, best_style
|
---|
[8] | 1183 | #if defined(Q_WS_PM)
|
---|
| 1184 | , best_size
|
---|
| 1185 | #elif defined(Q_WS_X11)
|
---|
[2] | 1186 | , best_size, best_encoding, ( force_encoding_id >= 0 )
|
---|
| 1187 | #endif
|
---|
| 1188 | );
|
---|
| 1189 | }
|
---|
| 1190 | if (fe) {
|
---|
| 1191 | fe->fontDef.family = best_family->name;
|
---|
| 1192 | if ( ! best_foundry->name.isEmpty() ) {
|
---|
| 1193 | fe->fontDef.family += QString::fromLatin1( " [" );
|
---|
| 1194 | fe->fontDef.family += best_foundry->name;
|
---|
| 1195 | fe->fontDef.family += QString::fromLatin1( "]" );
|
---|
| 1196 | }
|
---|
| 1197 |
|
---|
[8] | 1198 | #ifdef Q_WS_PM
|
---|
| 1199 | // On OS/2, fontDef.pixelSize and fontDef.pointSize are filled
|
---|
| 1200 | // by QFontEnginePM constructor
|
---|
| 1201 | #else
|
---|
[2] | 1202 | if ( best_style->smoothScalable )
|
---|
| 1203 | fe->fontDef.pixelSize = request.pixelSize;
|
---|
| 1204 | else if ( best_style->bitmapScalable &&
|
---|
| 1205 | ( request.styleStrategy & QFont::PreferMatch ) )
|
---|
| 1206 | fe->fontDef.pixelSize = request.pixelSize;
|
---|
| 1207 | else
|
---|
| 1208 | fe->fontDef.pixelSize = best_size->pixelSize;
|
---|
| 1209 |
|
---|
| 1210 | if ( fp ) {
|
---|
| 1211 | #if defined(Q_WS_X11)
|
---|
| 1212 | fe->fontDef.pointSize =
|
---|
| 1213 | qRound(10. * qt_pointSize(fe->fontDef.pixelSize, fp->paintdevice, fp->screen));
|
---|
| 1214 | #elif defined(Q_WS_WIN)
|
---|
| 1215 | fe->fontDef.pointSize = int( double( fe->fontDef.pixelSize ) * 720.0 /
|
---|
| 1216 | GetDeviceCaps(shared_dc,LOGPIXELSY) );
|
---|
| 1217 | #else
|
---|
| 1218 | fe->fontDef.pointSize = int( double( fe->fontDef.pixelSize ) * 720.0 /
|
---|
| 1219 | 96.0 );
|
---|
| 1220 | #endif
|
---|
| 1221 | } else {
|
---|
| 1222 | fe->fontDef.pointSize = request.pointSize;
|
---|
| 1223 | }
|
---|
[8] | 1224 | #endif
|
---|
[2] | 1225 | fe->fontDef.styleHint = request.styleHint;
|
---|
| 1226 | fe->fontDef.styleStrategy = request.styleStrategy;
|
---|
| 1227 |
|
---|
| 1228 | fe->fontDef.weight = best_style->key.weight;
|
---|
| 1229 | fe->fontDef.italic = best_style->key.italic || best_style->key.oblique;
|
---|
| 1230 | fe->fontDef.fixedPitch = best_family->fixedPitch;
|
---|
| 1231 | fe->fontDef.stretch = best_style->key.stretch;
|
---|
| 1232 | fe->fontDef.ignorePitch = FALSE;
|
---|
| 1233 | }
|
---|
| 1234 | }
|
---|
| 1235 |
|
---|
| 1236 | if ( fe ) {
|
---|
[8] | 1237 | #ifdef Q_WS_PM
|
---|
| 1238 | ///@@TODO (dmik): should do something here?
|
---|
| 1239 | #else
|
---|
[2] | 1240 | if ( script != QFont::Unicode && !canRender( fe, script ) ) {
|
---|
| 1241 | FM_DEBUG( " WARN: font loaded cannot render sample 0x%04x",
|
---|
| 1242 | sampleCharacter(script).unicode() );
|
---|
| 1243 | delete fe;
|
---|
| 1244 |
|
---|
| 1245 | if ( ! request.family.isEmpty() )
|
---|
| 1246 | return 0;
|
---|
| 1247 |
|
---|
| 1248 | FM_DEBUG( "returning box engine" );
|
---|
| 1249 |
|
---|
| 1250 | fe = new QFontEngineBox( request.pixelSize );
|
---|
| 1251 |
|
---|
| 1252 | if ( fp
|
---|
| 1253 | #ifdef Q_WS_WIN
|
---|
| 1254 | && !fp->paintdevice
|
---|
| 1255 | #endif
|
---|
| 1256 | ) {
|
---|
| 1257 | QFontCache::Key key( request, script, fp->screen );
|
---|
| 1258 | QFontCache::instance->insertEngine( key, fe );
|
---|
| 1259 | }
|
---|
| 1260 |
|
---|
| 1261 | return fe;
|
---|
| 1262 | }
|
---|
[8] | 1263 | #endif // !Q_WS_PM
|
---|
[2] | 1264 |
|
---|
| 1265 | if ( fp ) {
|
---|
| 1266 | QFontCache::Key key( request, script,
|
---|
[8] | 1267 | #if defined(Q_WS_WIN) || defined(Q_WS_PM)
|
---|
[2] | 1268 | (int)fp->paintdevice
|
---|
| 1269 | #else
|
---|
| 1270 | fp->screen
|
---|
| 1271 | #endif
|
---|
| 1272 | );
|
---|
| 1273 | QFontCache::instance->insertEngine( key, fe );
|
---|
| 1274 |
|
---|
[8] | 1275 | #ifndef Q_WS_PM
|
---|
[2] | 1276 | for ( int i = 0; i < QFont::NScripts; ++i ) {
|
---|
| 1277 | if ( i == script ) continue;
|
---|
| 1278 |
|
---|
| 1279 | if (!canRender(fe, (QFont::Script) i))
|
---|
| 1280 | continue;
|
---|
| 1281 |
|
---|
| 1282 | key.script = i;
|
---|
| 1283 | QFontCache::instance->insertEngine( key, fe );
|
---|
| 1284 | }
|
---|
[8] | 1285 | #endif // !Q_WS_PM
|
---|
[2] | 1286 | }
|
---|
| 1287 | } else {
|
---|
| 1288 | if ( request.family.isEmpty() ) {
|
---|
[8] | 1289 | #ifdef Q_WS_PM
|
---|
| 1290 | //@@TODO (dmik): what to return in such case?
|
---|
| 1291 | qFatal( "QFontDatabase::findFont: request.family is empty and nothing is found, should it ever happen?" );
|
---|
| 1292 | #else
|
---|
[2] | 1293 | FM_DEBUG( "returning box engine" );
|
---|
| 1294 |
|
---|
| 1295 | fe = new QFontEngineBox( request.pixelSize );
|
---|
| 1296 |
|
---|
| 1297 | if ( fp ) {
|
---|
| 1298 | QFontCache::Key key( request, script,
|
---|
[8] | 1299 | #if defined(Q_WS_WIN) || defined(Q_WS_PM)
|
---|
[2] | 1300 | (int)fp->paintdevice
|
---|
| 1301 | #else
|
---|
| 1302 | fp->screen
|
---|
| 1303 | #endif
|
---|
| 1304 | );
|
---|
| 1305 | QFontCache::instance->insertEngine( key, fe );
|
---|
| 1306 | }
|
---|
[8] | 1307 | #endif // Q_WS_PM
|
---|
[2] | 1308 | }
|
---|
| 1309 | }
|
---|
| 1310 |
|
---|
| 1311 | return fe;
|
---|
| 1312 | }
|
---|
[8] | 1313 | #endif // Q_WS_X11 || Q_WS_WIN || Q_WS_PM
|
---|
[2] | 1314 |
|
---|
| 1315 |
|
---|
| 1316 |
|
---|
| 1317 |
|
---|
| 1318 | static QString styleString( int weight, bool italic, bool oblique )
|
---|
| 1319 | {
|
---|
| 1320 | QString result;
|
---|
| 1321 | if ( weight >= QFont::Black )
|
---|
| 1322 | result = "Black";
|
---|
| 1323 | else if ( weight >= QFont::Bold )
|
---|
| 1324 | result = "Bold";
|
---|
| 1325 | else if ( weight >= QFont::DemiBold )
|
---|
| 1326 | result = "Demi Bold";
|
---|
| 1327 | else if ( weight < QFont::Normal )
|
---|
| 1328 | result = "Light";
|
---|
| 1329 |
|
---|
| 1330 | if ( italic )
|
---|
| 1331 | result += " Italic";
|
---|
| 1332 | else if ( oblique )
|
---|
| 1333 | result += " Oblique";
|
---|
| 1334 |
|
---|
| 1335 | if ( result.isEmpty() )
|
---|
| 1336 | result = "Normal";
|
---|
| 1337 |
|
---|
| 1338 | return result.simplifyWhiteSpace();
|
---|
| 1339 | }
|
---|
| 1340 |
|
---|
| 1341 | /*!
|
---|
| 1342 | Returns a string that describes the style of the font \a f. For
|
---|
| 1343 | example, "Bold Italic", "Bold", "Italic" or "Normal". An empty
|
---|
| 1344 | string may be returned.
|
---|
| 1345 | */
|
---|
| 1346 | QString QFontDatabase::styleString( const QFont &f )
|
---|
| 1347 | {
|
---|
| 1348 | // ### fix oblique here
|
---|
| 1349 | return ::styleString( f.weight(), f.italic(), FALSE );
|
---|
| 1350 | }
|
---|
| 1351 |
|
---|
| 1352 |
|
---|
| 1353 | /*!
|
---|
| 1354 | \class QFontDatabase qfontdatabase.h
|
---|
| 1355 | \brief The QFontDatabase class provides information about the fonts available in the underlying window system.
|
---|
| 1356 |
|
---|
| 1357 | \ingroup environment
|
---|
| 1358 | \ingroup graphics
|
---|
| 1359 |
|
---|
| 1360 | The most common uses of this class are to query the database for
|
---|
| 1361 | the list of font families() and for the pointSizes() and styles()
|
---|
| 1362 | that are available for each family. An alternative to pointSizes()
|
---|
| 1363 | is smoothSizes() which returns the sizes at which a given family
|
---|
| 1364 | and style will look attractive.
|
---|
| 1365 |
|
---|
| 1366 | If the font family is available from two or more foundries the
|
---|
| 1367 | foundry name is included in the family name, e.g. "Helvetica
|
---|
| 1368 | [Adobe]" and "Helvetica [Cronyx]". When you specify a family you
|
---|
| 1369 | can either use the old hyphenated Qt 2.x "foundry-family" format,
|
---|
| 1370 | e.g. "Cronyx-Helvetica", or the new bracketed Qt 3.x "family
|
---|
| 1371 | [foundry]" format e.g. "Helvetica [Cronyx]". If the family has a
|
---|
| 1372 | foundry it is always returned, e.g. by families(), using the
|
---|
| 1373 | bracketed format.
|
---|
| 1374 |
|
---|
| 1375 | The font() function returns a QFont given a family, style and
|
---|
| 1376 | point size.
|
---|
| 1377 |
|
---|
| 1378 | A family and style combination can be checked to see if it is
|
---|
| 1379 | italic() or bold(), and to retrieve its weight(). Similarly we can
|
---|
| 1380 | call isBitmapScalable(), isSmoothlyScalable(), isScalable() and
|
---|
| 1381 | isFixedPitch().
|
---|
| 1382 |
|
---|
| 1383 | A text version of a style is given by styleString().
|
---|
| 1384 |
|
---|
| 1385 | The QFontDatabase class also supports some static functions, for
|
---|
| 1386 | example, standardSizes(). You can retrieve the Unicode 3.0
|
---|
| 1387 | description of a \link QFont::Script script\endlink using
|
---|
| 1388 | scriptName(), and a sample of characters in a script with
|
---|
| 1389 | scriptSample().
|
---|
| 1390 |
|
---|
| 1391 | Example:
|
---|
| 1392 | \code
|
---|
| 1393 | #include <qapplication.h>
|
---|
| 1394 | #include <qfontdatabase.h>
|
---|
| 1395 | #include <else.h>
|
---|
| 1396 |
|
---|
| 1397 | int main( int argc, char **argv )
|
---|
| 1398 | {
|
---|
| 1399 | QApplication app( argc, argv );
|
---|
| 1400 | QFontDatabase fdb;
|
---|
| 1401 | QStringList families = fdb.families();
|
---|
| 1402 | for ( QStringList::Iterator f = families.begin(); f != families.end(); ++f ) {
|
---|
| 1403 | QString family = *f;
|
---|
| 1404 | qDebug( family );
|
---|
| 1405 | QStringList styles = fdb.styles( family );
|
---|
| 1406 | for ( QStringList::Iterator s = styles.begin(); s != styles.end(); ++s ) {
|
---|
| 1407 | QString style = *s;
|
---|
| 1408 | QString dstyle = "\t" + style + " (";
|
---|
| 1409 | QValueList<int> smoothies = fdb.smoothSizes( family, style );
|
---|
| 1410 | for ( QValueList<int>::Iterator points = smoothies.begin();
|
---|
| 1411 | points != smoothies.end(); ++points ) {
|
---|
| 1412 | dstyle += QString::number( *points ) + " ";
|
---|
| 1413 | }
|
---|
| 1414 | dstyle = dstyle.left( dstyle.length() - 1 ) + ")";
|
---|
| 1415 | qDebug( dstyle );
|
---|
| 1416 | }
|
---|
| 1417 | }
|
---|
| 1418 | return 0;
|
---|
| 1419 | }
|
---|
| 1420 | \endcode
|
---|
| 1421 | This example gets the list of font families, then the list of
|
---|
| 1422 | styles for each family and the point sizes that are available for
|
---|
| 1423 | each family/style combination.
|
---|
| 1424 | */
|
---|
| 1425 | /*!
|
---|
| 1426 | \obsolete
|
---|
| 1427 | \fn inline QStringList QFontDatabase::families( bool ) const
|
---|
| 1428 | */
|
---|
| 1429 | /*!
|
---|
| 1430 | \obsolete
|
---|
| 1431 | \fn inline QStringList QFontDatabase::styles( const QString &family,
|
---|
| 1432 | const QString & ) const
|
---|
| 1433 | */
|
---|
| 1434 | /*!
|
---|
| 1435 | \obsolete
|
---|
| 1436 | \fn inline QValueList<int> QFontDatabase::pointSizes( const QString &family,
|
---|
| 1437 | const QString &style ,
|
---|
| 1438 | const QString & )
|
---|
| 1439 | */
|
---|
| 1440 |
|
---|
| 1441 | /*!
|
---|
| 1442 | \obsolete
|
---|
| 1443 | \fn inline QValueList<int> QFontDatabase::smoothSizes( const QString &family,
|
---|
| 1444 | const QString &style,
|
---|
| 1445 | const QString & )
|
---|
| 1446 | */
|
---|
| 1447 | /*!
|
---|
| 1448 | \obsolete
|
---|
| 1449 | \fn inline QFont QFontDatabase::font( const QString &familyName,
|
---|
| 1450 | const QString &style,
|
---|
| 1451 | int pointSize,
|
---|
| 1452 | const QString &)
|
---|
| 1453 | */
|
---|
| 1454 | /*!
|
---|
| 1455 | \obsolete
|
---|
| 1456 | \fn inline bool QFontDatabase::isBitmapScalable( const QString &family,
|
---|
| 1457 | const QString &style,
|
---|
| 1458 | const QString & ) const
|
---|
| 1459 | */
|
---|
| 1460 |
|
---|
| 1461 | /*!
|
---|
| 1462 | \obsolete
|
---|
| 1463 | \fn inline bool QFontDatabase::isSmoothlyScalable( const QString &family,
|
---|
| 1464 | const QString &style,
|
---|
| 1465 | const QString & ) const
|
---|
| 1466 | */
|
---|
| 1467 |
|
---|
| 1468 | /*!
|
---|
| 1469 | \obsolete
|
---|
| 1470 | \fn inline bool QFontDatabase::isScalable( const QString &family,
|
---|
| 1471 | const QString &style,
|
---|
| 1472 | const QString & ) const
|
---|
| 1473 | */
|
---|
| 1474 |
|
---|
| 1475 | /*!
|
---|
| 1476 | \obsolete
|
---|
| 1477 | \fn inline bool QFontDatabase::isFixedPitch( const QString &family,
|
---|
| 1478 | const QString &style,
|
---|
| 1479 | const QString & ) const
|
---|
| 1480 | */
|
---|
| 1481 |
|
---|
| 1482 | /*!
|
---|
| 1483 | \obsolete
|
---|
| 1484 | \fn inline bool QFontDatabase::italic( const QString &family,
|
---|
| 1485 | const QString &style,
|
---|
| 1486 | const QString & ) const
|
---|
| 1487 | */
|
---|
| 1488 |
|
---|
| 1489 | /*!
|
---|
| 1490 | \obsolete
|
---|
| 1491 | \fn inline bool QFontDatabase::bold( const QString &family,
|
---|
| 1492 | const QString &style,
|
---|
| 1493 | const QString & ) const
|
---|
| 1494 | */
|
---|
| 1495 |
|
---|
| 1496 | /*!
|
---|
| 1497 | \obsolete
|
---|
| 1498 | \fn inline int QFontDatabase::weight( const QString &family,
|
---|
| 1499 | const QString &style,
|
---|
| 1500 | const QString & ) const
|
---|
| 1501 | */
|
---|
| 1502 |
|
---|
| 1503 |
|
---|
| 1504 | /*!
|
---|
| 1505 | Creates a font database object.
|
---|
| 1506 | */
|
---|
| 1507 | QFontDatabase::QFontDatabase()
|
---|
| 1508 | {
|
---|
[8] | 1509 | #ifdef Q_WS_PM
|
---|
| 1510 | d = QFontDatabasePrivate::instance();
|
---|
| 1511 | #else
|
---|
[2] | 1512 | createDatabase();
|
---|
| 1513 |
|
---|
| 1514 | d = db;
|
---|
[8] | 1515 | #endif
|
---|
[2] | 1516 | }
|
---|
| 1517 |
|
---|
| 1518 |
|
---|
| 1519 | /*! Returns a sorted list of the names of the available font families.
|
---|
| 1520 |
|
---|
| 1521 | If a family exists in several foundries, the returned name for
|
---|
| 1522 | that font is in the form "family [foundry]". Examples: "Times
|
---|
| 1523 | [Adobe]", "Times [Cronyx]", "Palatino".
|
---|
| 1524 | */
|
---|
| 1525 | QStringList QFontDatabase::families() const
|
---|
| 1526 | {
|
---|
| 1527 | load();
|
---|
| 1528 |
|
---|
| 1529 | QStringList flist;
|
---|
| 1530 | for ( int i = 0; i < d->count; i++ ) {
|
---|
| 1531 | QtFontFamily *f = d->families[i];
|
---|
| 1532 | if ( f->count == 0 )
|
---|
| 1533 | continue;
|
---|
| 1534 | if ( f->count == 1 ) {
|
---|
| 1535 | flist.append( f->name );
|
---|
| 1536 | } else {
|
---|
| 1537 | for ( int j = 0; j < f->count; j++ ) {
|
---|
| 1538 | QString str = f->name;
|
---|
| 1539 | QString foundry = f->foundries[j]->name;
|
---|
| 1540 | if ( !foundry.isEmpty() ) {
|
---|
| 1541 | str += " [";
|
---|
| 1542 | str += foundry;
|
---|
| 1543 | str += "]";
|
---|
| 1544 | }
|
---|
| 1545 | flist.append( str );
|
---|
| 1546 | }
|
---|
| 1547 | }
|
---|
| 1548 | }
|
---|
| 1549 | return flist;
|
---|
| 1550 | }
|
---|
| 1551 |
|
---|
| 1552 | /*!
|
---|
| 1553 | \overload
|
---|
| 1554 |
|
---|
| 1555 | Returns a sorted list of the available font families which support
|
---|
| 1556 | the Unicode script \a script.
|
---|
| 1557 |
|
---|
| 1558 | If a family exists in several foundries, the returned name for
|
---|
| 1559 | that font is in the form "family [foundry]". Examples: "Times
|
---|
| 1560 | [Adobe]", "Times [Cronyx]", "Palatino".
|
---|
| 1561 | */
|
---|
| 1562 | QStringList QFontDatabase::families( QFont::Script script ) const
|
---|
| 1563 | {
|
---|
| 1564 | load();
|
---|
| 1565 |
|
---|
| 1566 | QStringList flist;
|
---|
| 1567 | for ( int i = 0; i < d->count; i++ ) {
|
---|
| 1568 | QtFontFamily *f = d->families[i];
|
---|
| 1569 | if ( f->count == 0 )
|
---|
| 1570 | continue;
|
---|
| 1571 | if (!(f->scripts[script] & QtFontFamily::Supported))
|
---|
| 1572 | continue;
|
---|
| 1573 | if ( f->count == 1 ) {
|
---|
| 1574 | flist.append( f->name );
|
---|
| 1575 | } else {
|
---|
| 1576 | for ( int j = 0; j < f->count; j++ ) {
|
---|
| 1577 | QString str = f->name;
|
---|
| 1578 | QString foundry = f->foundries[j]->name;
|
---|
| 1579 | if ( !foundry.isEmpty() ) {
|
---|
| 1580 | str += " [";
|
---|
| 1581 | str += foundry;
|
---|
| 1582 | str += "]";
|
---|
| 1583 | }
|
---|
| 1584 | flist.append( str );
|
---|
| 1585 | }
|
---|
| 1586 | }
|
---|
| 1587 | }
|
---|
| 1588 | return flist;
|
---|
| 1589 | }
|
---|
| 1590 |
|
---|
| 1591 | /*!
|
---|
| 1592 | Returns a list of the styles available for the font family \a
|
---|
| 1593 | family. Some example styles: "Light", "Light Italic", "Bold",
|
---|
| 1594 | "Oblique", "Demi". The list may be empty.
|
---|
| 1595 | */
|
---|
| 1596 | QStringList QFontDatabase::styles( const QString &family ) const
|
---|
| 1597 | {
|
---|
| 1598 | QString familyName, foundryName;
|
---|
| 1599 | parseFontName( family, foundryName, familyName );
|
---|
| 1600 |
|
---|
| 1601 | load( familyName );
|
---|
| 1602 |
|
---|
| 1603 | QStringList l;
|
---|
| 1604 | QtFontFamily *f = d->family( familyName );
|
---|
| 1605 | if ( !f )
|
---|
| 1606 | return l;
|
---|
| 1607 |
|
---|
| 1608 | QtFontFoundry allStyles( foundryName );
|
---|
| 1609 | for ( int j = 0; j < f->count; j++ ) {
|
---|
| 1610 | QtFontFoundry *foundry = f->foundries[j];
|
---|
| 1611 | if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
|
---|
| 1612 | for ( int k = 0; k < foundry->count; k++ ) {
|
---|
| 1613 | QtFontStyle::Key ke( foundry->styles[k]->key );
|
---|
| 1614 | ke.stretch = 0;
|
---|
| 1615 | allStyles.style( ke, TRUE );
|
---|
| 1616 | }
|
---|
| 1617 | }
|
---|
| 1618 | }
|
---|
| 1619 |
|
---|
| 1620 | for ( int i = 0; i < allStyles.count; i++ )
|
---|
| 1621 | l.append( ::styleString( allStyles.styles[i]->key.weight,
|
---|
| 1622 | allStyles.styles[i]->key.italic,
|
---|
| 1623 | allStyles.styles[i]->key.oblique ) );
|
---|
| 1624 | return l;
|
---|
| 1625 | }
|
---|
| 1626 |
|
---|
| 1627 | /*!
|
---|
| 1628 | Returns TRUE if the font that has family \a family and style \a
|
---|
| 1629 | style is fixed pitch; otherwise returns FALSE.
|
---|
| 1630 | */
|
---|
| 1631 |
|
---|
| 1632 | bool QFontDatabase::isFixedPitch(const QString &family,
|
---|
| 1633 | const QString &style) const
|
---|
| 1634 | {
|
---|
| 1635 | Q_UNUSED(style);
|
---|
| 1636 |
|
---|
| 1637 | QString familyName, foundryName;
|
---|
| 1638 | parseFontName( family, foundryName, familyName );
|
---|
| 1639 |
|
---|
| 1640 | load( familyName );
|
---|
| 1641 |
|
---|
| 1642 | QtFontFamily *f = d->family( familyName );
|
---|
| 1643 | #if defined(Q_OS_MAC) && !defined(QWS)
|
---|
| 1644 | if (f) {
|
---|
| 1645 | if (!f->fixedPitchComputed) {
|
---|
| 1646 | QFontMetrics fm(familyName);
|
---|
| 1647 | f->fixedPitch = fm.width('i') == fm.width('m');
|
---|
| 1648 | f->fixedPitchComputed = TRUE;
|
---|
| 1649 | }
|
---|
| 1650 | }
|
---|
| 1651 | #endif
|
---|
| 1652 |
|
---|
| 1653 | return ( f && f->fixedPitch );
|
---|
| 1654 | }
|
---|
| 1655 |
|
---|
| 1656 | /*!
|
---|
| 1657 | Returns TRUE if the font that has family \a family and style \a
|
---|
| 1658 | style is a scalable bitmap font; otherwise returns FALSE. Scaling
|
---|
| 1659 | a bitmap font usually produces an unattractive hardly readable
|
---|
| 1660 | result, because the pixels of the font are scaled. If you need to
|
---|
| 1661 | scale a bitmap font it is better to scale it to one of the fixed
|
---|
| 1662 | sizes returned by smoothSizes().
|
---|
| 1663 |
|
---|
| 1664 | \sa isScalable(), isSmoothlyScalable()
|
---|
| 1665 | */
|
---|
| 1666 | bool QFontDatabase::isBitmapScalable( const QString &family,
|
---|
| 1667 | const QString &style) const
|
---|
| 1668 | {
|
---|
| 1669 | bool bitmapScalable = FALSE;
|
---|
| 1670 | QString familyName, foundryName;
|
---|
| 1671 | parseFontName( family, foundryName, familyName );
|
---|
| 1672 |
|
---|
| 1673 | load( familyName );
|
---|
| 1674 |
|
---|
| 1675 | QtFontStyle::Key styleKey( style );
|
---|
| 1676 |
|
---|
| 1677 | QtFontFamily *f = d->family( familyName );
|
---|
| 1678 | if ( !f ) return bitmapScalable;
|
---|
| 1679 |
|
---|
| 1680 | for ( int j = 0; j < f->count; j++ ) {
|
---|
| 1681 | QtFontFoundry *foundry = f->foundries[j];
|
---|
| 1682 | if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
|
---|
| 1683 | for ( int k = 0; k < foundry->count; k++ )
|
---|
| 1684 | if ( foundry->styles[k]->key == styleKey &&
|
---|
| 1685 | foundry->styles[k]->bitmapScalable &&
|
---|
| 1686 | !foundry->styles[k]->smoothScalable ) {
|
---|
| 1687 | bitmapScalable = TRUE;
|
---|
| 1688 | goto end;
|
---|
| 1689 | }
|
---|
| 1690 | }
|
---|
| 1691 | }
|
---|
| 1692 | end:
|
---|
| 1693 | return bitmapScalable;
|
---|
| 1694 | }
|
---|
| 1695 |
|
---|
| 1696 |
|
---|
| 1697 | /*!
|
---|
| 1698 | Returns TRUE if the font that has family \a family and style \a
|
---|
| 1699 | style is smoothly scalable; otherwise returns FALSE. If this
|
---|
| 1700 | function returns TRUE, it's safe to scale this font to any size,
|
---|
| 1701 | and the result will always look attractive.
|
---|
| 1702 |
|
---|
| 1703 | \sa isScalable(), isBitmapScalable()
|
---|
| 1704 | */
|
---|
| 1705 | bool QFontDatabase::isSmoothlyScalable( const QString &family,
|
---|
| 1706 | const QString &style) const
|
---|
| 1707 | {
|
---|
| 1708 | bool smoothScalable = FALSE;
|
---|
| 1709 | QString familyName, foundryName;
|
---|
| 1710 | parseFontName( family, foundryName, familyName );
|
---|
| 1711 |
|
---|
| 1712 | load( familyName );
|
---|
| 1713 |
|
---|
| 1714 | QtFontStyle::Key styleKey( style );
|
---|
| 1715 |
|
---|
| 1716 | QtFontFamily *f = d->family( familyName );
|
---|
| 1717 | if ( !f ) return smoothScalable;
|
---|
| 1718 |
|
---|
| 1719 | for ( int j = 0; j < f->count; j++ ) {
|
---|
| 1720 | QtFontFoundry *foundry = f->foundries[j];
|
---|
| 1721 | if ( foundryName.isEmpty() ||
|
---|
| 1722 | ucstricmp( foundry->name, foundryName ) == 0 ) {
|
---|
| 1723 | for ( int k = 0; k < foundry->count; k++ )
|
---|
| 1724 | if ( foundry->styles[k]->key == styleKey &&
|
---|
| 1725 | foundry->styles[k]->smoothScalable ) {
|
---|
| 1726 | smoothScalable = TRUE;
|
---|
| 1727 | goto end;
|
---|
| 1728 | }
|
---|
| 1729 | }
|
---|
| 1730 | }
|
---|
| 1731 | end:
|
---|
| 1732 | return smoothScalable;
|
---|
| 1733 | }
|
---|
| 1734 |
|
---|
| 1735 | /*!
|
---|
| 1736 | Returns TRUE if the font that has family \a family and style \a
|
---|
| 1737 | style is scalable; otherwise returns FALSE.
|
---|
| 1738 |
|
---|
| 1739 | \sa isBitmapScalable(), isSmoothlyScalable()
|
---|
| 1740 | */
|
---|
| 1741 | bool QFontDatabase::isScalable( const QString &family,
|
---|
| 1742 | const QString &style) const
|
---|
| 1743 | {
|
---|
| 1744 | if ( isSmoothlyScalable( family, style) )
|
---|
| 1745 | return TRUE;
|
---|
| 1746 |
|
---|
| 1747 | return isBitmapScalable( family, style);
|
---|
| 1748 | }
|
---|
| 1749 |
|
---|
| 1750 |
|
---|
| 1751 | /*!
|
---|
| 1752 | Returns a list of the point sizes available for the font that has
|
---|
| 1753 | family \a family and style \a style. The list may be empty.
|
---|
| 1754 |
|
---|
| 1755 | \sa smoothSizes(), standardSizes()
|
---|
| 1756 | */
|
---|
| 1757 | QValueList<int> QFontDatabase::pointSizes( const QString &family,
|
---|
| 1758 | const QString &style)
|
---|
| 1759 | {
|
---|
| 1760 | #if defined(Q_WS_WIN) || defined(Q_WS_MAC)
|
---|
| 1761 | // windows and macosx are always smoothly scalable
|
---|
| 1762 | Q_UNUSED( family );
|
---|
| 1763 | Q_UNUSED( style );
|
---|
| 1764 | return standardSizes();
|
---|
| 1765 | #else
|
---|
| 1766 | bool smoothScalable = FALSE;
|
---|
| 1767 | QString familyName, foundryName;
|
---|
| 1768 | parseFontName( family, foundryName, familyName );
|
---|
| 1769 |
|
---|
| 1770 | load( familyName );
|
---|
| 1771 |
|
---|
| 1772 | QtFontStyle::Key styleKey( style );
|
---|
| 1773 |
|
---|
| 1774 | QValueList<int> sizes;
|
---|
| 1775 |
|
---|
| 1776 | QtFontFamily *fam = d->family( familyName );
|
---|
| 1777 | if ( !fam ) return sizes;
|
---|
| 1778 |
|
---|
| 1779 | for ( int j = 0; j < fam->count; j++ ) {
|
---|
| 1780 | QtFontFoundry *foundry = fam->foundries[j];
|
---|
| 1781 | if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
|
---|
| 1782 | QtFontStyle *style = foundry->style( styleKey );
|
---|
| 1783 | if ( !style ) continue;
|
---|
| 1784 |
|
---|
| 1785 | if ( style->smoothScalable ) {
|
---|
| 1786 | smoothScalable = TRUE;
|
---|
| 1787 | goto end;
|
---|
| 1788 | }
|
---|
| 1789 | for ( int l = 0; l < style->count; l++ ) {
|
---|
| 1790 | const QtFontSize *size = style->pixelSizes + l;
|
---|
| 1791 |
|
---|
| 1792 | if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) {
|
---|
[8] | 1793 | #if defined(Q_WS_X11)
|
---|
[2] | 1794 | const uint pointSize = qRound(qt_pointSize(size->pixelSize, 0, -1));
|
---|
[8] | 1795 | #elif defined(Q_WS_PM)
|
---|
| 1796 | //@@TODO (dmik): some bitmap fonts (i.e. System VIO) have point sizes
|
---|
| 1797 | // that do not really correlate with their actual pixel sizes (i.e.
|
---|
| 1798 | // their pointsize != pixelsizde * DPI / 72), What to return in that case?
|
---|
| 1799 | const uint pointSize = size->pointSize / 10;
|
---|
[2] | 1800 | #else
|
---|
| 1801 | const uint pointSize = size->pixelSize; // embedded uses 72dpi
|
---|
| 1802 | #endif
|
---|
| 1803 | if (! sizes.contains(pointSize))
|
---|
| 1804 | sizes.append(pointSize);
|
---|
| 1805 | }
|
---|
| 1806 | }
|
---|
| 1807 | }
|
---|
| 1808 | }
|
---|
| 1809 | end:
|
---|
| 1810 | if ( smoothScalable )
|
---|
| 1811 | return standardSizes();
|
---|
| 1812 |
|
---|
| 1813 | qHeapSort( sizes );
|
---|
| 1814 | return sizes;
|
---|
| 1815 | #endif
|
---|
| 1816 | }
|
---|
| 1817 |
|
---|
| 1818 | /*!
|
---|
| 1819 | Returns a QFont object that has family \a family, style \a style
|
---|
| 1820 | and point size \a pointSize. If no matching font could be created,
|
---|
| 1821 | a QFont object that uses the application's default font is
|
---|
| 1822 | returned.
|
---|
| 1823 | */
|
---|
| 1824 | QFont QFontDatabase::font( const QString &family, const QString &style,
|
---|
| 1825 | int pointSize)
|
---|
| 1826 | {
|
---|
| 1827 | QString familyName, foundryName;
|
---|
| 1828 | parseFontName( family, foundryName, familyName );
|
---|
| 1829 |
|
---|
| 1830 | load( familyName );
|
---|
| 1831 |
|
---|
| 1832 | QtFontFoundry allStyles( foundryName );
|
---|
| 1833 | QtFontFamily *f = d->family( familyName );
|
---|
| 1834 | if ( !f ) return QApplication::font();
|
---|
| 1835 |
|
---|
| 1836 | for ( int j = 0; j < f->count; j++ ) {
|
---|
| 1837 | QtFontFoundry *foundry = f->foundries[j];
|
---|
| 1838 | if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
|
---|
| 1839 | for ( int k = 0; k < foundry->count; k++ )
|
---|
| 1840 | allStyles.style( foundry->styles[k]->key, TRUE );
|
---|
| 1841 | }
|
---|
| 1842 | }
|
---|
| 1843 |
|
---|
| 1844 | QtFontStyle::Key styleKey( style );
|
---|
| 1845 | QtFontStyle *s = allStyles.style( styleKey );
|
---|
| 1846 |
|
---|
| 1847 | // ### perhaps do a bit of matching to find the most compatible font?
|
---|
| 1848 | if ( !s && allStyles.count )
|
---|
| 1849 | s = allStyles.styles[0];
|
---|
| 1850 |
|
---|
| 1851 | if ( !s ) // no styles found?
|
---|
| 1852 | return QApplication::font();
|
---|
| 1853 | return QFont( family, pointSize, s->key.weight,
|
---|
| 1854 | s->key.italic ? TRUE : s->key.oblique ? TRUE : FALSE );
|
---|
| 1855 | }
|
---|
| 1856 |
|
---|
| 1857 |
|
---|
| 1858 | /*!
|
---|
| 1859 | Returns the point sizes of a font that has family \a family and
|
---|
| 1860 | style \a style that will look attractive. The list may be empty.
|
---|
| 1861 | For non-scalable fonts and bitmap scalable fonts, this function
|
---|
| 1862 | is equivalent to pointSizes().
|
---|
| 1863 |
|
---|
| 1864 | \sa pointSizes(), standardSizes()
|
---|
| 1865 | */
|
---|
| 1866 | QValueList<int> QFontDatabase::smoothSizes( const QString &family,
|
---|
| 1867 | const QString &style)
|
---|
| 1868 | {
|
---|
| 1869 | #ifdef Q_WS_WIN
|
---|
| 1870 | Q_UNUSED( family );
|
---|
| 1871 | Q_UNUSED( style );
|
---|
| 1872 | return QFontDatabase::standardSizes();
|
---|
| 1873 | #else
|
---|
| 1874 | bool smoothScalable = FALSE;
|
---|
| 1875 | QString familyName, foundryName;
|
---|
| 1876 | parseFontName( family, foundryName, familyName );
|
---|
| 1877 |
|
---|
| 1878 | load( familyName );
|
---|
| 1879 |
|
---|
| 1880 | QtFontStyle::Key styleKey( style );
|
---|
| 1881 |
|
---|
| 1882 | QValueList<int> sizes;
|
---|
| 1883 |
|
---|
| 1884 | QtFontFamily *fam = d->family( familyName );
|
---|
| 1885 | if ( !fam )
|
---|
| 1886 | return sizes;
|
---|
| 1887 |
|
---|
| 1888 | for ( int j = 0; j < fam->count; j++ ) {
|
---|
| 1889 | QtFontFoundry *foundry = fam->foundries[j];
|
---|
| 1890 | if ( foundryName.isEmpty() ||
|
---|
| 1891 | ucstricmp( foundry->name, foundryName ) == 0 ) {
|
---|
| 1892 | QtFontStyle *style = foundry->style( styleKey );
|
---|
| 1893 | if ( !style ) continue;
|
---|
| 1894 |
|
---|
| 1895 | if ( style->smoothScalable ) {
|
---|
| 1896 | smoothScalable = TRUE;
|
---|
| 1897 | goto end;
|
---|
| 1898 | }
|
---|
| 1899 | for ( int l = 0; l < style->count; l++ ) {
|
---|
| 1900 | const QtFontSize *size = style->pixelSizes + l;
|
---|
| 1901 |
|
---|
| 1902 | if ( size->pixelSize != 0 && size->pixelSize != USHRT_MAX ) {
|
---|
[8] | 1903 | #if defined(Q_WS_X11)
|
---|
[2] | 1904 | const uint pointSize = qRound(qt_pointSize(size->pixelSize, 0, -1));
|
---|
[8] | 1905 | #elif defined(Q_WS_PM)
|
---|
| 1906 | //@@TODO (dmik): some bitmap fonts (i.e. System VIO) have point sizes
|
---|
| 1907 | // that do not really correlate with their actual pixel sizes (i.e.
|
---|
| 1908 | // their pointsize != pixelsizde * DPI / 72), What to return in that case?
|
---|
| 1909 | const uint pointSize = size->pointSize / 10;
|
---|
[2] | 1910 | #else
|
---|
| 1911 | const uint pointSize = size->pixelSize; // embedded uses 72dpi
|
---|
| 1912 | #endif
|
---|
| 1913 | if (! sizes.contains(pointSize))
|
---|
| 1914 | sizes.append( pointSize );
|
---|
| 1915 | }
|
---|
| 1916 | }
|
---|
| 1917 | }
|
---|
| 1918 | }
|
---|
| 1919 | end:
|
---|
| 1920 | if ( smoothScalable )
|
---|
| 1921 | return QFontDatabase::standardSizes();
|
---|
| 1922 |
|
---|
| 1923 | qHeapSort( sizes );
|
---|
| 1924 | return sizes;
|
---|
| 1925 | #endif
|
---|
| 1926 | }
|
---|
| 1927 |
|
---|
| 1928 |
|
---|
| 1929 | /*!
|
---|
| 1930 | Returns a list of standard font sizes.
|
---|
| 1931 |
|
---|
| 1932 | \sa smoothSizes(), pointSizes()
|
---|
| 1933 | */
|
---|
| 1934 | QValueList<int> QFontDatabase::standardSizes()
|
---|
| 1935 | {
|
---|
| 1936 | QValueList<int> ret;
|
---|
| 1937 | static const unsigned short standard[] =
|
---|
| 1938 | { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72, 0 };
|
---|
| 1939 | const unsigned short *sizes = standard;
|
---|
| 1940 | while ( *sizes ) ret << *sizes++;
|
---|
| 1941 | return ret;
|
---|
| 1942 | }
|
---|
| 1943 |
|
---|
| 1944 |
|
---|
| 1945 | /*!
|
---|
| 1946 | Returns TRUE if the font that has family \a family and style \a
|
---|
| 1947 | style is italic; otherwise returns FALSE.
|
---|
| 1948 |
|
---|
| 1949 | \sa weight(), bold()
|
---|
| 1950 | */
|
---|
| 1951 | bool QFontDatabase::italic( const QString &family,
|
---|
| 1952 | const QString &style) const
|
---|
| 1953 | {
|
---|
| 1954 | QString familyName, foundryName;
|
---|
| 1955 | parseFontName( family, foundryName, familyName );
|
---|
| 1956 |
|
---|
| 1957 | load( familyName );
|
---|
| 1958 |
|
---|
| 1959 | QtFontFoundry allStyles( foundryName );
|
---|
| 1960 | QtFontFamily *f = d->family( familyName );
|
---|
| 1961 | if ( !f ) return FALSE;
|
---|
| 1962 |
|
---|
| 1963 | for ( int j = 0; j < f->count; j++ ) {
|
---|
| 1964 | QtFontFoundry *foundry = f->foundries[j];
|
---|
| 1965 | if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
|
---|
| 1966 | for ( int k = 0; k < foundry->count; k++ )
|
---|
| 1967 | allStyles.style( foundry->styles[k]->key, TRUE );
|
---|
| 1968 | }
|
---|
| 1969 | }
|
---|
| 1970 |
|
---|
| 1971 | QtFontStyle::Key styleKey( style );
|
---|
| 1972 | QtFontStyle *s = allStyles.style( styleKey );
|
---|
| 1973 | return s && s->key.italic;
|
---|
| 1974 | }
|
---|
| 1975 |
|
---|
| 1976 |
|
---|
| 1977 | /*!
|
---|
| 1978 | Returns TRUE if the font that has family \a family and style \a
|
---|
| 1979 | style is bold; otherwise returns FALSE.
|
---|
| 1980 |
|
---|
| 1981 | \sa italic(), weight()
|
---|
| 1982 | */
|
---|
| 1983 | bool QFontDatabase::bold( const QString &family,
|
---|
| 1984 | const QString &style) const
|
---|
| 1985 | {
|
---|
| 1986 | QString familyName, foundryName;
|
---|
| 1987 | parseFontName( family, foundryName, familyName );
|
---|
| 1988 |
|
---|
| 1989 | load( familyName );
|
---|
| 1990 |
|
---|
| 1991 | QtFontFoundry allStyles( foundryName );
|
---|
| 1992 | QtFontFamily *f = d->family( familyName );
|
---|
| 1993 | if ( !f ) return FALSE;
|
---|
| 1994 |
|
---|
| 1995 | for ( int j = 0; j < f->count; j++ ) {
|
---|
| 1996 | QtFontFoundry *foundry = f->foundries[j];
|
---|
| 1997 | if ( foundryName.isEmpty() ||
|
---|
| 1998 | ucstricmp( foundry->name, foundryName ) == 0 ) {
|
---|
| 1999 | for ( int k = 0; k < foundry->count; k++ )
|
---|
| 2000 | allStyles.style( foundry->styles[k]->key, TRUE );
|
---|
| 2001 | }
|
---|
| 2002 | }
|
---|
| 2003 |
|
---|
| 2004 | QtFontStyle::Key styleKey( style );
|
---|
| 2005 | QtFontStyle *s = allStyles.style( styleKey );
|
---|
| 2006 | return s && s->key.weight >= QFont::Bold;
|
---|
| 2007 | }
|
---|
| 2008 |
|
---|
| 2009 |
|
---|
| 2010 | /*!
|
---|
| 2011 | Returns the weight of the font that has family \a family and style
|
---|
| 2012 | \a style. If there is no such family and style combination,
|
---|
| 2013 | returns -1.
|
---|
| 2014 |
|
---|
| 2015 | \sa italic(), bold()
|
---|
| 2016 | */
|
---|
| 2017 | int QFontDatabase::weight( const QString &family,
|
---|
| 2018 | const QString &style) const
|
---|
| 2019 | {
|
---|
| 2020 | QString familyName, foundryName;
|
---|
| 2021 | parseFontName( family, foundryName, familyName );
|
---|
| 2022 |
|
---|
| 2023 | load( familyName );
|
---|
| 2024 |
|
---|
| 2025 | QtFontFoundry allStyles( foundryName );
|
---|
| 2026 | QtFontFamily *f = d->family( familyName );
|
---|
| 2027 | if ( !f ) return -1;
|
---|
| 2028 |
|
---|
| 2029 | for ( int j = 0; j < f->count; j++ ) {
|
---|
| 2030 | QtFontFoundry *foundry = f->foundries[j];
|
---|
| 2031 | if ( foundryName.isEmpty() ||
|
---|
| 2032 | ucstricmp( foundry->name, foundryName ) == 0 ) {
|
---|
| 2033 | for ( int k = 0; k < foundry->count; k++ )
|
---|
| 2034 | allStyles.style( foundry->styles[k]->key, TRUE );
|
---|
| 2035 | }
|
---|
| 2036 | }
|
---|
| 2037 |
|
---|
| 2038 | QtFontStyle::Key styleKey( style );
|
---|
| 2039 | QtFontStyle *s = allStyles.style( styleKey );
|
---|
| 2040 | return s ? s->key.weight : -1;
|
---|
| 2041 | }
|
---|
| 2042 |
|
---|
| 2043 |
|
---|
| 2044 | /*!
|
---|
| 2045 | Returns a string that gives a default description of the \a script
|
---|
| 2046 | (e.g. for displaying to the user in a dialog). The name matches
|
---|
| 2047 | the name of the script as defined by the Unicode 3.0 standard.
|
---|
| 2048 |
|
---|
| 2049 | \sa QFont::Script
|
---|
| 2050 | */
|
---|
| 2051 | QString QFontDatabase::scriptName(QFont::Script script)
|
---|
| 2052 | {
|
---|
| 2053 | const char *name = 0;
|
---|
| 2054 |
|
---|
| 2055 | switch (script) {
|
---|
| 2056 | case QFont::Latin:
|
---|
| 2057 | name = QT_TRANSLATE_NOOP("QFont", "Latin");
|
---|
| 2058 | break;
|
---|
| 2059 | case QFont::Greek:
|
---|
| 2060 | name = QT_TRANSLATE_NOOP("QFont", "Greek" );
|
---|
| 2061 | break;
|
---|
| 2062 | case QFont::Cyrillic:
|
---|
| 2063 | name = QT_TRANSLATE_NOOP("QFont", "Cyrillic" );
|
---|
| 2064 | break;
|
---|
| 2065 | case QFont::Armenian:
|
---|
| 2066 | name = QT_TRANSLATE_NOOP("QFont", "Armenian" );
|
---|
| 2067 | break;
|
---|
| 2068 | case QFont::Georgian:
|
---|
| 2069 | name = QT_TRANSLATE_NOOP("QFont", "Georgian" );
|
---|
| 2070 | break;
|
---|
| 2071 | case QFont::Runic:
|
---|
| 2072 | name = QT_TRANSLATE_NOOP("QFont", "Runic" );
|
---|
| 2073 | break;
|
---|
| 2074 | case QFont::Ogham:
|
---|
| 2075 | name = QT_TRANSLATE_NOOP("QFont", "Ogham" );
|
---|
| 2076 | break;
|
---|
| 2077 | case QFont::SpacingModifiers:
|
---|
| 2078 | name = QT_TRANSLATE_NOOP("QFont", "SpacingModifiers" );
|
---|
| 2079 | break;
|
---|
| 2080 | case QFont::CombiningMarks:
|
---|
| 2081 | name = QT_TRANSLATE_NOOP("QFont", "CombiningMarks" );
|
---|
| 2082 | break;
|
---|
| 2083 | case QFont::Hebrew:
|
---|
| 2084 | name = QT_TRANSLATE_NOOP("QFont", "Hebrew" );
|
---|
| 2085 | break;
|
---|
| 2086 | case QFont::Arabic:
|
---|
| 2087 | name = QT_TRANSLATE_NOOP("QFont", "Arabic" );
|
---|
| 2088 | break;
|
---|
| 2089 | case QFont::Syriac:
|
---|
| 2090 | name = QT_TRANSLATE_NOOP("QFont", "Syriac" );
|
---|
| 2091 | break;
|
---|
| 2092 | case QFont::Thaana:
|
---|
| 2093 | name = QT_TRANSLATE_NOOP("QFont", "Thaana" );
|
---|
| 2094 | break;
|
---|
| 2095 | case QFont::Devanagari:
|
---|
| 2096 | name = QT_TRANSLATE_NOOP("QFont", "Devanagari" );
|
---|
| 2097 | break;
|
---|
| 2098 | case QFont::Bengali:
|
---|
| 2099 | name = QT_TRANSLATE_NOOP("QFont", "Bengali" );
|
---|
| 2100 | break;
|
---|
| 2101 | case QFont::Gurmukhi:
|
---|
| 2102 | name = QT_TRANSLATE_NOOP("QFont", "Gurmukhi" );
|
---|
| 2103 | break;
|
---|
| 2104 | case QFont::Gujarati:
|
---|
| 2105 | name = QT_TRANSLATE_NOOP("QFont", "Gujarati" );
|
---|
| 2106 | break;
|
---|
| 2107 | case QFont::Oriya:
|
---|
| 2108 | name = QT_TRANSLATE_NOOP("QFont", "Oriya" );
|
---|
| 2109 | break;
|
---|
| 2110 | case QFont::Tamil:
|
---|
| 2111 | name = QT_TRANSLATE_NOOP("QFont", "Tamil" );
|
---|
| 2112 | break;
|
---|
| 2113 | case QFont::Telugu:
|
---|
| 2114 | name = QT_TRANSLATE_NOOP("QFont", "Telugu" );
|
---|
| 2115 | break;
|
---|
| 2116 | case QFont::Kannada:
|
---|
| 2117 | name = QT_TRANSLATE_NOOP("QFont", "Kannada" );
|
---|
| 2118 | break;
|
---|
| 2119 | case QFont::Malayalam:
|
---|
| 2120 | name = QT_TRANSLATE_NOOP("QFont", "Malayalam" );
|
---|
| 2121 | break;
|
---|
| 2122 | case QFont::Sinhala:
|
---|
| 2123 | name = QT_TRANSLATE_NOOP("QFont", "Sinhala" );
|
---|
| 2124 | break;
|
---|
| 2125 | case QFont::Thai:
|
---|
| 2126 | name = QT_TRANSLATE_NOOP("QFont", "Thai" );
|
---|
| 2127 | break;
|
---|
| 2128 | case QFont::Lao:
|
---|
| 2129 | name = QT_TRANSLATE_NOOP("QFont", "Lao" );
|
---|
| 2130 | break;
|
---|
| 2131 | case QFont::Tibetan:
|
---|
| 2132 | name = QT_TRANSLATE_NOOP("QFont", "Tibetan" );
|
---|
| 2133 | break;
|
---|
| 2134 | case QFont::Myanmar:
|
---|
| 2135 | name = QT_TRANSLATE_NOOP("QFont", "Myanmar" );
|
---|
| 2136 | break;
|
---|
| 2137 | case QFont::Khmer:
|
---|
| 2138 | name = QT_TRANSLATE_NOOP("QFont", "Khmer" );
|
---|
| 2139 | break;
|
---|
| 2140 | case QFont::Han:
|
---|
| 2141 | name = QT_TRANSLATE_NOOP("QFont", "Han" );
|
---|
| 2142 | break;
|
---|
| 2143 | case QFont::Hiragana:
|
---|
| 2144 | name = QT_TRANSLATE_NOOP("QFont", "Hiragana" );
|
---|
| 2145 | break;
|
---|
| 2146 | case QFont::Katakana:
|
---|
| 2147 | name = QT_TRANSLATE_NOOP("QFont", "Katakana" );
|
---|
| 2148 | break;
|
---|
| 2149 | case QFont::Hangul:
|
---|
| 2150 | name = QT_TRANSLATE_NOOP("QFont", "Hangul" );
|
---|
| 2151 | break;
|
---|
| 2152 | case QFont::Bopomofo:
|
---|
| 2153 | name = QT_TRANSLATE_NOOP("QFont", "Bopomofo" );
|
---|
| 2154 | break;
|
---|
| 2155 | case QFont::Yi:
|
---|
| 2156 | name = QT_TRANSLATE_NOOP("QFont", "Yi" );
|
---|
| 2157 | break;
|
---|
| 2158 | case QFont::Ethiopic:
|
---|
| 2159 | name = QT_TRANSLATE_NOOP("QFont", "Ethiopic" );
|
---|
| 2160 | break;
|
---|
| 2161 | case QFont::Cherokee:
|
---|
| 2162 | name = QT_TRANSLATE_NOOP("QFont", "Cherokee" );
|
---|
| 2163 | break;
|
---|
| 2164 | case QFont::CanadianAboriginal:
|
---|
| 2165 | name = QT_TRANSLATE_NOOP("QFont", "Canadian Aboriginal" );
|
---|
| 2166 | break;
|
---|
| 2167 | case QFont::Mongolian:
|
---|
| 2168 | name = QT_TRANSLATE_NOOP("QFont", "Mongolian" );
|
---|
| 2169 | break;
|
---|
| 2170 |
|
---|
| 2171 | case QFont::CurrencySymbols:
|
---|
| 2172 | name = QT_TRANSLATE_NOOP("QFont", "Currency Symbols" );
|
---|
| 2173 | break;
|
---|
| 2174 |
|
---|
| 2175 | case QFont::LetterlikeSymbols:
|
---|
| 2176 | name = QT_TRANSLATE_NOOP("QFont", "Letterlike Symbols" );
|
---|
| 2177 | break;
|
---|
| 2178 |
|
---|
| 2179 | case QFont::NumberForms:
|
---|
| 2180 | name = QT_TRANSLATE_NOOP("QFont", "Number Forms" );
|
---|
| 2181 | break;
|
---|
| 2182 |
|
---|
| 2183 | case QFont::MathematicalOperators:
|
---|
| 2184 | name = QT_TRANSLATE_NOOP("QFont", "Mathematical Operators" );
|
---|
| 2185 | break;
|
---|
| 2186 |
|
---|
| 2187 | case QFont::TechnicalSymbols:
|
---|
| 2188 | name = QT_TRANSLATE_NOOP("QFont", "Technical Symbols" );
|
---|
| 2189 | break;
|
---|
| 2190 |
|
---|
| 2191 | case QFont::GeometricSymbols:
|
---|
| 2192 | name = QT_TRANSLATE_NOOP("QFont", "Geometric Symbols" );
|
---|
| 2193 | break;
|
---|
| 2194 |
|
---|
| 2195 | case QFont::MiscellaneousSymbols:
|
---|
| 2196 | name = QT_TRANSLATE_NOOP("QFont", "Miscellaneous Symbols" );
|
---|
| 2197 | break;
|
---|
| 2198 |
|
---|
| 2199 | case QFont::EnclosedAndSquare:
|
---|
| 2200 | name = QT_TRANSLATE_NOOP("QFont", "Enclosed and Square" );
|
---|
| 2201 | break;
|
---|
| 2202 |
|
---|
| 2203 | case QFont::Braille:
|
---|
| 2204 | name = QT_TRANSLATE_NOOP("QFont", "Braille" );
|
---|
| 2205 | break;
|
---|
| 2206 |
|
---|
| 2207 | case QFont::Unicode:
|
---|
| 2208 | name = QT_TRANSLATE_NOOP("QFont", "Unicode" );
|
---|
| 2209 | break;
|
---|
| 2210 |
|
---|
| 2211 | case QFont::Tagalog:
|
---|
| 2212 | name = QT_TRANSLATE_NOOP( "QFont", "Tagalog" );
|
---|
| 2213 | break;
|
---|
| 2214 |
|
---|
| 2215 | case QFont::Hanunoo:
|
---|
| 2216 | name = QT_TRANSLATE_NOOP( "QFont", "Hanunoo" );
|
---|
| 2217 | break;
|
---|
| 2218 |
|
---|
| 2219 | case QFont::Buhid:
|
---|
| 2220 | name = QT_TRANSLATE_NOOP( "QFont", "Buhid" );
|
---|
| 2221 | break;
|
---|
| 2222 |
|
---|
| 2223 | case QFont::Tagbanwa:
|
---|
| 2224 | name = QT_TRANSLATE_NOOP( "QFont", "Tagbanwa" );
|
---|
| 2225 | break;
|
---|
| 2226 |
|
---|
| 2227 | case QFont::KatakanaHalfWidth:
|
---|
| 2228 | name = QT_TRANSLATE_NOOP( "QFont", "Katakana Half-Width Forms" );
|
---|
| 2229 | break;
|
---|
| 2230 |
|
---|
| 2231 | case QFont::Han_Japanese:
|
---|
| 2232 | name = QT_TRANSLATE_NOOP( "QFont", "Han (Japanese)" );
|
---|
| 2233 | break;
|
---|
| 2234 |
|
---|
| 2235 | case QFont::Han_SimplifiedChinese:
|
---|
| 2236 | name = QT_TRANSLATE_NOOP( "QFont", "Han (Simplified Chinese)" );
|
---|
| 2237 | break;
|
---|
| 2238 |
|
---|
| 2239 | case QFont::Han_TraditionalChinese:
|
---|
| 2240 | name = QT_TRANSLATE_NOOP( "QFont", "Han (Traditional Chinese)" );
|
---|
| 2241 | break;
|
---|
| 2242 |
|
---|
| 2243 | case QFont::Han_Korean:
|
---|
| 2244 | name = QT_TRANSLATE_NOOP( "QFont", "Han (Korean)" );
|
---|
| 2245 | break;
|
---|
| 2246 |
|
---|
| 2247 | default:
|
---|
| 2248 | name = QT_TRANSLATE_NOOP( "QFont", "Unknown Script" );
|
---|
| 2249 | break;
|
---|
| 2250 | }
|
---|
| 2251 |
|
---|
| 2252 | return qApp ? qApp->translate("QFont", name) : QString::fromLatin1(name);
|
---|
| 2253 | }
|
---|
| 2254 |
|
---|
| 2255 |
|
---|
| 2256 | /*!
|
---|
| 2257 | Returns a string with sample characters from \a script.
|
---|
| 2258 |
|
---|
| 2259 | \sa QFont::Script
|
---|
| 2260 | */
|
---|
| 2261 | QString QFontDatabase::scriptSample(QFont::Script script)
|
---|
| 2262 | {
|
---|
| 2263 | QString sample = "AaBb";
|
---|
| 2264 |
|
---|
| 2265 | switch (script) {
|
---|
| 2266 | case QFont::Latin:
|
---|
| 2267 | // This is cheating... we only show latin-1 characters so that we don't
|
---|
| 2268 | // end up loading lots of fonts - at least on X11...
|
---|
| 2269 | sample += QChar(0x00C3);
|
---|
| 2270 | sample += QChar(0x00E1);
|
---|
| 2271 | sample += "Zz";
|
---|
| 2272 | break;
|
---|
| 2273 | case QFont::Greek:
|
---|
| 2274 | sample += QChar(0x0393);
|
---|
| 2275 | sample += QChar(0x03B1);
|
---|
| 2276 | sample += QChar(0x03A9);
|
---|
| 2277 | sample += QChar(0x03C9);
|
---|
| 2278 | break;
|
---|
| 2279 | case QFont::Cyrillic:
|
---|
| 2280 | sample += QChar(0x0414);
|
---|
| 2281 | sample += QChar(0x0434);
|
---|
| 2282 | sample += QChar(0x0436);
|
---|
| 2283 | sample += QChar(0x0402);
|
---|
| 2284 | break;
|
---|
| 2285 | case QFont::Armenian:
|
---|
| 2286 | sample += QChar(0x053f);
|
---|
| 2287 | sample += QChar(0x054f);
|
---|
| 2288 | sample += QChar(0x056f);
|
---|
| 2289 | sample += QChar(0x057f);
|
---|
| 2290 | break;
|
---|
| 2291 | case QFont::Georgian:
|
---|
| 2292 | sample += QChar(0x10a0);
|
---|
| 2293 | sample += QChar(0x10b0);
|
---|
| 2294 | sample += QChar(0x10c0);
|
---|
| 2295 | sample += QChar(0x10d0);
|
---|
| 2296 | break;
|
---|
| 2297 | case QFont::Runic:
|
---|
| 2298 | sample += QChar(0x16a0);
|
---|
| 2299 | sample += QChar(0x16b0);
|
---|
| 2300 | sample += QChar(0x16c0);
|
---|
| 2301 | sample += QChar(0x16d0);
|
---|
| 2302 | break;
|
---|
| 2303 | case QFont::Ogham:
|
---|
| 2304 | sample += QChar(0x1681);
|
---|
| 2305 | sample += QChar(0x1687);
|
---|
| 2306 | sample += QChar(0x1693);
|
---|
| 2307 | sample += QChar(0x168d);
|
---|
| 2308 | break;
|
---|
| 2309 |
|
---|
| 2310 |
|
---|
| 2311 |
|
---|
| 2312 | case QFont::Hebrew:
|
---|
| 2313 | sample += QChar(0x05D0);
|
---|
| 2314 | sample += QChar(0x05D1);
|
---|
| 2315 | sample += QChar(0x05D2);
|
---|
| 2316 | sample += QChar(0x05D3);
|
---|
| 2317 | break;
|
---|
| 2318 | case QFont::Arabic:
|
---|
| 2319 | sample += QChar(0x0628);
|
---|
| 2320 | sample += QChar(0x0629);
|
---|
| 2321 | sample += QChar(0x062A);
|
---|
| 2322 | sample += QChar(0x063A);
|
---|
| 2323 | break;
|
---|
| 2324 | case QFont::Syriac:
|
---|
| 2325 | sample += QChar(0x0715);
|
---|
| 2326 | sample += QChar(0x0725);
|
---|
| 2327 | sample += QChar(0x0716);
|
---|
| 2328 | sample += QChar(0x0726);
|
---|
| 2329 | break;
|
---|
| 2330 | case QFont::Thaana:
|
---|
| 2331 | sample += QChar(0x0784);
|
---|
| 2332 | sample += QChar(0x0794);
|
---|
| 2333 | sample += QChar(0x078c);
|
---|
| 2334 | sample += QChar(0x078d);
|
---|
| 2335 | break;
|
---|
| 2336 |
|
---|
| 2337 |
|
---|
| 2338 |
|
---|
| 2339 | case QFont::Devanagari:
|
---|
| 2340 | sample += QChar(0x0905);
|
---|
| 2341 | sample += QChar(0x0915);
|
---|
| 2342 | sample += QChar(0x0925);
|
---|
| 2343 | sample += QChar(0x0935);
|
---|
| 2344 | break;
|
---|
| 2345 | case QFont::Bengali:
|
---|
| 2346 | sample += QChar(0x0986);
|
---|
| 2347 | sample += QChar(0x0996);
|
---|
| 2348 | sample += QChar(0x09a6);
|
---|
| 2349 | sample += QChar(0x09b6);
|
---|
| 2350 | break;
|
---|
| 2351 | case QFont::Gurmukhi:
|
---|
| 2352 | sample += QChar(0x0a05);
|
---|
| 2353 | sample += QChar(0x0a15);
|
---|
| 2354 | sample += QChar(0x0a25);
|
---|
| 2355 | sample += QChar(0x0a35);
|
---|
| 2356 | break;
|
---|
| 2357 | case QFont::Gujarati:
|
---|
| 2358 | sample += QChar(0x0a85);
|
---|
| 2359 | sample += QChar(0x0a95);
|
---|
| 2360 | sample += QChar(0x0aa5);
|
---|
| 2361 | sample += QChar(0x0ab5);
|
---|
| 2362 | break;
|
---|
| 2363 | case QFont::Oriya:
|
---|
| 2364 | sample += QChar(0x0b06);
|
---|
| 2365 | sample += QChar(0x0b16);
|
---|
| 2366 | sample += QChar(0x0b2b);
|
---|
| 2367 | sample += QChar(0x0b36);
|
---|
| 2368 | break;
|
---|
| 2369 | case QFont::Tamil:
|
---|
| 2370 | sample += QChar(0x0b89);
|
---|
| 2371 | sample += QChar(0x0b99);
|
---|
| 2372 | sample += QChar(0x0ba9);
|
---|
| 2373 | sample += QChar(0x0bb9);
|
---|
| 2374 | break;
|
---|
| 2375 | case QFont::Telugu:
|
---|
| 2376 | sample += QChar(0x0c05);
|
---|
| 2377 | sample += QChar(0x0c15);
|
---|
| 2378 | sample += QChar(0x0c25);
|
---|
| 2379 | sample += QChar(0x0c35);
|
---|
| 2380 | break;
|
---|
| 2381 | case QFont::Kannada:
|
---|
| 2382 | sample += QChar(0x0c85);
|
---|
| 2383 | sample += QChar(0x0c95);
|
---|
| 2384 | sample += QChar(0x0ca5);
|
---|
| 2385 | sample += QChar(0x0cb5);
|
---|
| 2386 | break;
|
---|
| 2387 | case QFont::Malayalam:
|
---|
| 2388 | sample += QChar(0x0d05);
|
---|
| 2389 | sample += QChar(0x0d15);
|
---|
| 2390 | sample += QChar(0x0d25);
|
---|
| 2391 | sample += QChar(0x0d35);
|
---|
| 2392 | break;
|
---|
| 2393 | case QFont::Sinhala:
|
---|
| 2394 | sample += QChar(0x0d90);
|
---|
| 2395 | sample += QChar(0x0da0);
|
---|
| 2396 | sample += QChar(0x0db0);
|
---|
| 2397 | sample += QChar(0x0dc0);
|
---|
| 2398 | break;
|
---|
| 2399 | case QFont::Thai:
|
---|
| 2400 | sample += QChar(0x0e02);
|
---|
| 2401 | sample += QChar(0x0e12);
|
---|
| 2402 | sample += QChar(0x0e22);
|
---|
| 2403 | sample += QChar(0x0e32);
|
---|
| 2404 | break;
|
---|
| 2405 | case QFont::Lao:
|
---|
| 2406 | sample += QChar(0x0e8d);
|
---|
| 2407 | sample += QChar(0x0e9d);
|
---|
| 2408 | sample += QChar(0x0ead);
|
---|
| 2409 | sample += QChar(0x0ebd);
|
---|
| 2410 | break;
|
---|
| 2411 | case QFont::Tibetan:
|
---|
| 2412 | sample += QChar(0x0f00);
|
---|
| 2413 | sample += QChar(0x0f01);
|
---|
| 2414 | sample += QChar(0x0f02);
|
---|
| 2415 | sample += QChar(0x0f03);
|
---|
| 2416 | break;
|
---|
| 2417 | case QFont::Myanmar:
|
---|
| 2418 | sample += QChar(0x1000);
|
---|
| 2419 | sample += QChar(0x1001);
|
---|
| 2420 | sample += QChar(0x1002);
|
---|
| 2421 | sample += QChar(0x1003);
|
---|
| 2422 | break;
|
---|
| 2423 | case QFont::Khmer:
|
---|
| 2424 | sample += QChar(0x1780);
|
---|
| 2425 | sample += QChar(0x1790);
|
---|
| 2426 | sample += QChar(0x17b0);
|
---|
| 2427 | sample += QChar(0x17c0);
|
---|
| 2428 | break;
|
---|
| 2429 |
|
---|
| 2430 |
|
---|
| 2431 |
|
---|
| 2432 | case QFont::Han:
|
---|
| 2433 | sample += QChar(0x6f84);
|
---|
| 2434 | sample += QChar(0x820a);
|
---|
| 2435 | sample += QChar(0x61a9);
|
---|
| 2436 | sample += QChar(0x9781);
|
---|
| 2437 | break;
|
---|
| 2438 | case QFont::Hiragana:
|
---|
| 2439 | sample += QChar(0x3050);
|
---|
| 2440 | sample += QChar(0x3060);
|
---|
| 2441 | sample += QChar(0x3070);
|
---|
| 2442 | sample += QChar(0x3080);
|
---|
| 2443 | break;
|
---|
| 2444 | case QFont::Katakana:
|
---|
| 2445 | sample += QChar(0x30b0);
|
---|
| 2446 | sample += QChar(0x30c0);
|
---|
| 2447 | sample += QChar(0x30d0);
|
---|
| 2448 | sample += QChar(0x30e0);
|
---|
| 2449 | break;
|
---|
| 2450 | case QFont::Hangul:
|
---|
| 2451 | sample += QChar(0xac00);
|
---|
| 2452 | sample += QChar(0xac11);
|
---|
| 2453 | sample += QChar(0xac1a);
|
---|
| 2454 | sample += QChar(0xac2f);
|
---|
| 2455 | break;
|
---|
| 2456 | case QFont::Bopomofo:
|
---|
| 2457 | sample += QChar(0x3105);
|
---|
| 2458 | sample += QChar(0x3115);
|
---|
| 2459 | sample += QChar(0x3125);
|
---|
| 2460 | sample += QChar(0x3129);
|
---|
| 2461 | break;
|
---|
| 2462 | case QFont::Yi:
|
---|
| 2463 | sample += QChar(0xa1a8);
|
---|
| 2464 | sample += QChar(0xa1a6);
|
---|
| 2465 | sample += QChar(0xa200);
|
---|
| 2466 | sample += QChar(0xa280);
|
---|
| 2467 | break;
|
---|
| 2468 |
|
---|
| 2469 |
|
---|
| 2470 |
|
---|
| 2471 | case QFont::Ethiopic:
|
---|
| 2472 | sample += QChar(0x1200);
|
---|
| 2473 | sample += QChar(0x1240);
|
---|
| 2474 | sample += QChar(0x1280);
|
---|
| 2475 | sample += QChar(0x12c0);
|
---|
| 2476 | break;
|
---|
| 2477 | case QFont::Cherokee:
|
---|
| 2478 | sample += QChar(0x13a0);
|
---|
| 2479 | sample += QChar(0x13b0);
|
---|
| 2480 | sample += QChar(0x13c0);
|
---|
| 2481 | sample += QChar(0x13d0);
|
---|
| 2482 | break;
|
---|
| 2483 | case QFont::CanadianAboriginal:
|
---|
| 2484 | sample += QChar(0x1410);
|
---|
| 2485 | sample += QChar(0x1500);
|
---|
| 2486 | sample += QChar(0x15f0);
|
---|
| 2487 | sample += QChar(0x1650);
|
---|
| 2488 | break;
|
---|
| 2489 | case QFont::Mongolian:
|
---|
| 2490 | sample += QChar(0x1820);
|
---|
| 2491 | sample += QChar(0x1840);
|
---|
| 2492 | sample += QChar(0x1860);
|
---|
| 2493 | sample += QChar(0x1880);
|
---|
| 2494 | break;
|
---|
| 2495 |
|
---|
| 2496 |
|
---|
| 2497 | case QFont::CurrencySymbols:
|
---|
| 2498 | case QFont::LetterlikeSymbols:
|
---|
| 2499 | case QFont::NumberForms:
|
---|
| 2500 | case QFont::MathematicalOperators:
|
---|
| 2501 | case QFont::TechnicalSymbols:
|
---|
| 2502 | case QFont::GeometricSymbols:
|
---|
| 2503 | case QFont::MiscellaneousSymbols:
|
---|
| 2504 | case QFont::EnclosedAndSquare:
|
---|
| 2505 | case QFont::Braille:
|
---|
| 2506 | break;
|
---|
| 2507 |
|
---|
| 2508 |
|
---|
| 2509 | case QFont::Unicode:
|
---|
| 2510 | sample += QChar(0x0174);
|
---|
| 2511 | sample += QChar(0x0628);
|
---|
| 2512 | sample += QChar(0x0e02);
|
---|
| 2513 | sample += QChar(0x263A);
|
---|
| 2514 | sample += QChar(0x3129);
|
---|
| 2515 | sample += QChar(0x61a9);
|
---|
| 2516 | sample += QChar(0xac2f);
|
---|
| 2517 | break;
|
---|
| 2518 |
|
---|
| 2519 |
|
---|
| 2520 |
|
---|
| 2521 | default:
|
---|
| 2522 | sample += QChar(0xfffd);
|
---|
| 2523 | sample += QChar(0xfffd);
|
---|
| 2524 | sample += QChar(0xfffd);
|
---|
| 2525 | sample += QChar(0xfffd);
|
---|
| 2526 | break;
|
---|
| 2527 | }
|
---|
| 2528 |
|
---|
| 2529 | return sample;
|
---|
| 2530 | }
|
---|
| 2531 |
|
---|
| 2532 |
|
---|
| 2533 |
|
---|
| 2534 |
|
---|
| 2535 | /*!
|
---|
| 2536 | \internal
|
---|
| 2537 |
|
---|
| 2538 | This makes sense of the font family name:
|
---|
| 2539 |
|
---|
| 2540 | 1) if the family name contains a '-' (ie. "Adobe-Courier"), then we
|
---|
| 2541 | split at the '-', and use the string as the foundry, and the string to
|
---|
| 2542 | the right as the family
|
---|
| 2543 |
|
---|
| 2544 | 2) if the family name contains a '[' and a ']', then we take the text
|
---|
| 2545 | between the square brackets as the foundry, and the text before the
|
---|
| 2546 | square brackets as the family (ie. "Arial [Monotype]")
|
---|
| 2547 | */
|
---|
| 2548 | void QFontDatabase::parseFontName(const QString &name, QString &foundry, QString &family)
|
---|
| 2549 | {
|
---|
| 2550 | if ( name.contains('-') ) {
|
---|
| 2551 | int i = name.find('-');
|
---|
| 2552 | foundry = name.left( i );
|
---|
| 2553 | family = name.right( name.length() - i - 1 );
|
---|
| 2554 | } else if ( name.contains('[') && name.contains(']')) {
|
---|
| 2555 | int i = name.find('[');
|
---|
| 2556 | int li = name.findRev(']');
|
---|
| 2557 |
|
---|
| 2558 | if (i < li) {
|
---|
| 2559 | foundry = name.mid(i + 1, li - i - 1);
|
---|
| 2560 | if (name[i - 1] == ' ')
|
---|
| 2561 | i--;
|
---|
| 2562 | family = name.left(i);
|
---|
| 2563 | }
|
---|
| 2564 | } else {
|
---|
| 2565 | foundry = QString::null;
|
---|
| 2566 | family = name;
|
---|
| 2567 | }
|
---|
| 2568 | }
|
---|
| 2569 |
|
---|
| 2570 | #endif // QT_NO_FONTDATABASE
|
---|