source: vendor/trolltech/current/src/kernel/qfontdatabase.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

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