1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include "qfontdatabase.h"
45 #include "qalgorithms.h"
46 #include "qapplication.h"
47 #include "qvarlengtharray.h" // here or earlier - workaround for VC++6
50 #include "private/qunicodetables_p.h"
51 #include "qfontengine_p.h"
54 #include <QtGui/private/qapplication_p.h>
55 #include <QtGui/qplatformfontdatabase_qpa.h>
56 #include "qabstractfileengine.h"
65 #if (defined(Q_WS_QWS)|| defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
66 # include <ft2build.h>
67 # include FT_TRUETYPE_TABLES_H
70 // #define QFONTDATABASE_DEBUG
71 #ifdef QFONTDATABASE_DEBUG
72 # define FD_DEBUG qDebug
74 # define FD_DEBUG if (false) qDebug
77 // #define FONT_MATCH_DEBUG
78 #ifdef FONT_MATCH_DEBUG
79 # define FM_DEBUG qDebug
81 # define FM_DEBUG if (false) qDebug
84 #if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
90 #define SMOOTH_SCALABLE 0xffff
92 bool qt_enable_test_font = false;
94 Q_AUTOTEST_EXPORT void qt_setQtEnableTestFont(bool value)
96 qt_enable_test_font = value;
99 static int getFontWeight(const QString &weightString)
101 QString s = weightString.toLower();
103 // Test in decreasing order of commonness
104 if (s == QLatin1String("medium") ||
105 s == QLatin1String("normal")
106 || s.compare(QApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0)
107 return QFont::Normal;
108 if (s == QLatin1String("bold")
109 || s.compare(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0)
111 if (s == QLatin1String("demibold") || s == QLatin1String("demi bold")
112 || s.compare(QApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0)
113 return QFont::DemiBold;
114 if (s == QLatin1String("black")
115 || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
117 if (s == QLatin1String("light"))
120 if (s.contains(QLatin1String("bold"))
121 || s.contains(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) {
122 if (s.contains(QLatin1String("demi"))
123 || s.compare(QApplication::translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0)
124 return (int) QFont::DemiBold;
125 return (int) QFont::Bold;
128 if (s.contains(QLatin1String("light"))
129 || s.compare(QApplication::translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0)
130 return (int) QFont::Light;
132 if (s.contains(QLatin1String("black"))
133 || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
134 return (int) QFont::Black;
136 return (int) QFont::Normal;
139 // convert 0 ~ 1000 integer to QFont::Weight
140 QFont::Weight weightFromInteger(int weight)
144 else if (weight < 600)
145 return QFont::Normal;
146 else if (weight < 700)
147 return QFont::DemiBold;
148 else if (weight < 800)
154 struct QtFontEncoding
156 signed int encoding : 16;
168 QtFontEncoding *encodings;
169 QtFontEncoding *encodingID(int id, uint xpoint = 0, uint xres = 0,
170 uint yres = 0, uint avgwidth = 0, bool add = false);
171 unsigned short count : 16;
174 #if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
177 #endif // defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
178 #if defined(Q_WS_QPA)
182 unsigned short pixelSize : 16;
187 QtFontEncoding *QtFontSize::encodingID(int id, uint xpoint, uint xres,
188 uint yres, uint avgwidth, bool add)
190 // we don't match using the xpoint, xres and yres parameters, only the id
191 for (int i = 0; i < count; ++i) {
192 if (encodings[i].encoding == id)
193 return encodings + i;
199 QtFontEncoding *newEncodings = (QtFontEncoding *)
201 (((count+4) >> 2) << 2) * sizeof(QtFontEncoding));
202 Q_CHECK_PTR(newEncodings);
203 encodings = newEncodings;
205 encodings[count].encoding = id;
206 encodings[count].xpoint = xpoint;
207 encodings[count].xres = xres;
208 encodings[count].yres = yres;
209 encodings[count].avgwidth = avgwidth;
210 encodings[count].pitch = '*';
211 return encodings + count++;
218 Key(const QString &styleString);
219 Key() : style(QFont::StyleNormal),
220 weight(QFont::Normal), stretch(0) { }
221 Key(const Key &o) : style(o.style),
222 weight(o.weight), stretch(o.stretch) { }
224 signed int weight : 8;
225 signed int stretch : 12;
227 bool operator==(const Key & other) {
228 return (style == other.style &&
229 weight == other.weight &&
230 (stretch == 0 || other.stretch == 0 || stretch == other.stretch));
232 bool operator!=(const Key &other) {
233 return !operator==(other);
235 bool operator <(const Key &o) {
236 int x = (style << 12) + (weight << 14) + stretch;
237 int y = (o.style << 12) + (o.weight << 14) + o.stretch;
242 QtFontStyle(const Key &k)
243 : key(k), bitmapScalable(false), smoothScalable(false),
244 count(0), pixelSizes(0)
246 #if defined(Q_WS_X11)
247 weightName = setwidthName = 0;
253 delete [] weightName;
254 delete [] setwidthName;
256 #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
258 // bitfield count-- in while condition does not work correctly in mwccsym2
261 free(pixelSizes[count].encodings);
263 #if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
264 pixelSizes[count].fileName.~QByteArray();
266 #if defined (Q_WS_QPA)
267 QPlatformIntegration *integration = QApplicationPrivate::platformIntegration();
268 if (integration) { //on shut down there will be some that we don't release.
269 integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
278 bool bitmapScalable : 1;
279 bool smoothScalable : 1;
280 signed int count : 30;
281 QtFontSize *pixelSizes;
284 const char *weightName;
285 const char *setwidthName;
287 #if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
291 QtFontSize *pixelSize(unsigned short size, bool = false);
294 QtFontStyle::Key::Key(const QString &styleString)
295 : style(QFont::StyleNormal), weight(QFont::Normal), stretch(0)
297 weight = getFontWeight(styleString);
299 if (styleString.contains(QLatin1String("Italic"))
300 || styleString.contains(QApplication::translate("QFontDatabase", "Italic")))
301 style = QFont::StyleItalic;
302 else if (styleString.contains(QLatin1String("Oblique"))
303 || styleString.contains(QApplication::translate("QFontDatabase", "Oblique")))
304 style = QFont::StyleOblique;
307 QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add)
309 for (int i = 0; i < count; i++) {
310 if (pixelSizes[i].pixelSize == size)
311 return pixelSizes + i;
317 // Most style have only one font size, we avoid waisting memory
318 QtFontSize *newPixelSizes = (QtFontSize *)malloc(sizeof(QtFontSize));
319 Q_CHECK_PTR(newPixelSizes);
320 pixelSizes = newPixelSizes;
321 } else if (!(count % 8) || count == 1) {
322 QtFontSize *newPixelSizes = (QtFontSize *)
324 (((count+8) >> 3) << 3) * sizeof(QtFontSize));
325 Q_CHECK_PTR(newPixelSizes);
326 pixelSizes = newPixelSizes;
328 pixelSizes[count].pixelSize = size;
330 pixelSizes[count].count = 0;
331 pixelSizes[count].encodings = 0;
333 #if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
334 new (&pixelSizes[count].fileName) QByteArray;
335 pixelSizes[count].fileIndex = 0;
337 #if defined(Q_WS_QPA)
338 pixelSizes[count].handle = 0;
340 return pixelSizes + (count++);
345 QtFontFoundry(const QString &n) : name(n), count(0), styles(0) {}
348 delete styles[count];
355 QtFontStyle **styles;
356 QtFontStyle *style(const QtFontStyle::Key &, bool = false);
359 QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create)
367 if (styles[pos]->key == key)
369 if (styles[pos]->key < key)
373 pos = (high + low) / 2;
380 // qDebug("adding key (weight=%d, style=%d, oblique=%d stretch=%d) at %d", key.weight, key.style, key.oblique, key.stretch, pos);
382 QtFontStyle **newStyles = (QtFontStyle **)
383 realloc(styles, (((count+8) >> 3) << 3) * sizeof(QtFontStyle *));
384 Q_CHECK_PTR(newStyles);
388 QtFontStyle *style = new QtFontStyle(key);
389 memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *));
398 enum WritingSystemStatus {
403 Unsupported = UnsupportedFT | UnsupportedXLFD
406 QtFontFamily(const QString &n)
409 fixedPitch(true), ftWritingSystemCheck(false),
410 xlfdLoaded(false), synthetic(false), symbol_checked(false),
415 writingSystemCheck(false),
418 #if !defined(QWS) && defined(Q_OS_MAC)
419 fixedPitchComputed(false),
421 name(n), count(0), foundries(0)
422 #if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
423 , bogusWritingSystems(false)
425 #if defined(Q_WS_QPA)
426 , askedForFallback(false)
429 memset(writingSystems, 0, sizeof(writingSystems));
433 delete foundries[count];
439 bool ftWritingSystemCheck : 1;
444 bool writingSystemCheck : 1;
447 #if !defined(QWS) && defined(Q_OS_MAC)
448 bool fixedPitchComputed : 1;
451 bool symbol_checked : 1;
455 #if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
456 QByteArray fontFilename;
460 QString english_name;
463 QtFontFoundry **foundries;
465 #if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
466 bool bogusWritingSystems;
467 QStringList fallbackFamilies;
469 #if defined (Q_WS_QPA)
470 bool askedForFallback;
472 unsigned char writingSystems[QFontDatabase::WritingSystemsCount];
474 QtFontFoundry *foundry(const QString &f, bool = false);
477 #if !defined(QWS) && defined(Q_OS_MAC)
478 inline static void qt_mac_get_fixed_pitch(QtFontFamily *f)
480 if(f && !f->fixedPitchComputed) {
481 QFontMetrics fm(f->name);
482 f->fixedPitch = fm.width(QLatin1Char('i')) == fm.width(QLatin1Char('m'));
483 f->fixedPitchComputed = true;
489 QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create)
491 if (f.isNull() && count == 1)
494 for (int i = 0; i < count; i++) {
495 if (foundries[i]->name.compare(f, Qt::CaseInsensitive) == 0)
502 QtFontFoundry **newFoundries = (QtFontFoundry **)
504 (((count+8) >> 3) << 3) * sizeof(QtFontFoundry *));
505 Q_CHECK_PTR(newFoundries);
506 foundries = newFoundries;
509 foundries[count] = new QtFontFoundry(f);
510 return foundries[count++];
513 // ### copied to tools/makeqpf/qpf2.cpp
515 // see the Unicode subset bitfields in the MSDN docs
516 static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
567 // SimplifiedChinese,
569 // TraditionalChinese,
576 { 0, 127 }, // same as latin1
587 #define SimplifiedChineseCsbBit 18
588 #define TraditionalChineseCsbBit 20
589 #define JapaneseCsbBit 17
590 #define KoreanCsbBit 21
592 QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_truetype_bits(quint32 unicodeRange[4], quint32 codePageRange[2])
594 QList<QFontDatabase::WritingSystem> writingSystems;
595 bool hasScript = false;
598 for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
599 int bit = requiredUnicodeBits[i][0];
601 int flag = 1 << (bit&31);
602 if (bit != 126 && unicodeRange[index] & flag) {
603 bit = requiredUnicodeBits[i][1];
606 flag = 1 << (bit&31);
607 if (bit == 127 || unicodeRange[index] & flag) {
608 writingSystems.append(QFontDatabase::WritingSystem(i));
610 // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
614 if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
615 writingSystems.append(QFontDatabase::SimplifiedChinese);
617 //qDebug("font %s supports Simplified Chinese", familyName.latin1());
619 if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
620 writingSystems.append(QFontDatabase::TraditionalChinese);
622 //qDebug("font %s supports Traditional Chinese", familyName.latin1());
624 if(codePageRange[0] & (1 << JapaneseCsbBit)) {
625 writingSystems.append(QFontDatabase::Japanese);
627 //qDebug("font %s supports Japanese", familyName.latin1());
629 if(codePageRange[0] & (1 << KoreanCsbBit)) {
630 writingSystems.append(QFontDatabase::Korean);
632 //qDebug("font %s supports Korean", familyName.latin1());
635 writingSystems.append(QFontDatabase::Symbol);
637 return writingSystems;
640 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
641 // class with virtual destructor, derived in qfontdatabase_s60.cpp
642 class QSymbianFontDatabaseExtras
645 virtual ~QSymbianFontDatabaseExtras() {}
649 class QFontDatabasePrivate
652 QFontDatabasePrivate()
653 : count(0), families(0), reregisterAppFonts(false)
654 #if defined(Q_WS_QWS)
657 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
660 #if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
661 , directWriteFactory(0)
662 , directWriteGdiInterop(0)
666 ~QFontDatabasePrivate() {
668 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
670 delete symbianExtras;
672 #if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
673 if (directWriteGdiInterop)
674 directWriteGdiInterop->Release();
675 if (directWriteFactory != 0)
676 directWriteFactory->Release();
679 QtFontFamily *family(const QString &f, bool = false);
682 delete families[count];
686 // don't clear the memory fonts!
690 #if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
693 QtFontFamily **families;
695 #if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
696 IDWriteFactory *directWriteFactory;
697 IDWriteGdiInterop *directWriteGdiInterop;
701 struct ApplicationFont {
704 #if defined(Q_OS_WIN)
707 QVector<FONTSIGNATURE> signatures;
708 #elif defined(Q_WS_MAC)
709 ATSFontContainerRef handle;
710 #elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
711 QString temporaryFileName;
712 TInt screenDeviceFontFileId;
713 TUid fontStoreFontFileUid;
715 QStringList families;
717 QVector<ApplicationFont> applicationFonts;
718 int addAppFont(const QByteArray &fontData, const QString &fileName);
719 bool reregisterAppFonts;
720 bool isApplicationFont(const QString &fileName);
724 #if defined(Q_WS_QWS)
725 bool loadFromCache(const QString &fontPath);
726 void addQPF2File(const QByteArray &file);
728 #if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
729 void addFont(const QString &familyname, const char *foundryname, int weight,
730 bool italic, int pixelSize, const QByteArray &file, int fileIndex,
732 const QList<QFontDatabase::WritingSystem> &writingSystems = QList<QFontDatabase::WritingSystem>());
733 #ifndef QT_NO_FREETYPE
734 QStringList addTTFile(const QByteArray &file, const QByteArray &fontData = QByteArray());
735 #endif // QT_NO_FREETYPE
737 #if defined(Q_WS_QWS)
739 #elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
740 QSymbianFontDatabaseExtras *symbianExtras;
742 #if defined(Q_WS_QWS) || defined(Q_WS_QPA)
743 QStringList fallbackFamilies;
747 void QFontDatabasePrivate::invalidate()
749 QFontCache::instance()->clear();
751 emit static_cast<QApplication *>(QApplication::instance())->fontDatabaseChanged();
754 QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create)
761 while ((res = families[pos]->name.compare(f, Qt::CaseInsensitive)) && pos != low) {
766 pos = (high + low) / 2;
769 return families[pos];
777 // qDebug("adding family %s at %d total=%d", f.latin1(), pos, count);
779 QtFontFamily **newFamilies = (QtFontFamily **)
781 (((count+8) >> 3) << 3) * sizeof(QtFontFamily *));
782 Q_CHECK_PTR(newFamilies);
783 families = newFamilies;
786 QtFontFamily *family = new QtFontFamily(f);
787 memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *));
788 families[pos] = family;
790 return families[pos];
793 #if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
794 void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundryname, int weight, bool italic, int pixelSize,
795 const QByteArray &file, int fileIndex, bool antialiased,
796 const QList<QFontDatabase::WritingSystem> &writingSystems)
798 // qDebug() << "Adding font" << familyname << weight << italic << pixelSize << file << fileIndex << antialiased;
799 QtFontStyle::Key styleKey;
800 styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal;
801 styleKey.weight = weight;
802 styleKey.stretch = 100;
803 QtFontFamily *f = family(familyname, true);
805 if (writingSystems.isEmpty()) {
806 for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) {
807 f->writingSystems[ws] = QtFontFamily::Supported;
809 f->bogusWritingSystems = true;
811 for (int i = 0; i < writingSystems.count(); ++i) {
812 f->writingSystems[writingSystems.at(i)] = QtFontFamily::Supported;
816 QtFontFoundry *foundry = f->foundry(QString::fromLatin1(foundryname), true);
817 QtFontStyle *style = foundry->style(styleKey, true);
818 style->smoothScalable = (pixelSize == 0);
819 style->antialiased = antialiased;
820 QtFontSize *size = style->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true);
821 size->fileName = file;
822 size->fileIndex = fileIndex;
824 #if defined(Q_WS_QWS)
826 *stream << familyname << foundry->name << weight << quint8(italic) << pixelSize
827 << file << fileIndex << quint8(antialiased);
828 *stream << quint8(writingSystems.count());
829 for (int i = 0; i < writingSystems.count(); ++i)
830 *stream << quint8(writingSystems.at(i));
832 #else // ..in case of defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
833 f->fontFilename = file;
834 f->fontFileIndex = fileIndex;
839 #if (defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
840 QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteArray &fontData)
842 QStringList families;
843 extern FT_Library qt_getFreetype();
844 FT_Library library = qt_getFreetype();
851 if (!fontData.isEmpty()) {
852 error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
854 error = FT_New_Face(library, file, index, &face);
856 if (error != FT_Err_Ok) {
857 qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
860 numFaces = face->num_faces;
862 int weight = QFont::Normal;
863 bool italic = face->style_flags & FT_STYLE_FLAG_ITALIC;
865 if (face->style_flags & FT_STYLE_FLAG_BOLD)
866 weight = QFont::Bold;
868 QList<QFontDatabase::WritingSystem> writingSystems;
869 // detect symbol fonts
870 for (int i = 0; i < face->num_charmaps; ++i) {
871 FT_CharMap cm = face->charmaps[i];
872 if (cm->encoding == ft_encoding_adobe_custom
873 || cm->encoding == ft_encoding_symbol) {
874 writingSystems.append(QFontDatabase::Symbol);
878 if (writingSystems.isEmpty()) {
879 TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
881 quint32 unicodeRange[4] = {
882 static_cast<quint32>(os2->ulUnicodeRange1), static_cast<quint32>(os2->ulUnicodeRange2), static_cast<quint32>(os2->ulUnicodeRange3), static_cast<quint32>(os2->ulUnicodeRange4)
884 quint32 codePageRange[2] = {
885 static_cast<quint32>(os2->ulCodePageRange1), static_cast<quint32>(os2->ulCodePageRange2)
888 writingSystems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange);
889 //for (int i = 0; i < writingSystems.count(); ++i)
890 // qDebug() << QFontDatabase::writingSystemName(writingSystems.at(i));
894 QString family = QString::fromAscii(face->family_name);
895 families.append(family);
896 addFont(family, /*foundry*/ "", weight, italic,
897 /*pixelsize*/ 0, file, index, /*antialias*/ true, writingSystems);
901 } while (index < numFaces);
906 static const int scriptForWritingSystem[] = {
907 QUnicodeTables::Common, // Any
908 QUnicodeTables::Latin, // Latin
909 QUnicodeTables::Greek, // Greek
910 QUnicodeTables::Cyrillic, // Cyrillic
911 QUnicodeTables::Armenian, // Armenian
912 QUnicodeTables::Hebrew, // Hebrew
913 QUnicodeTables::Arabic, // Arabic
914 QUnicodeTables::Syriac, // Syriac
915 QUnicodeTables::Thaana, // Thaana
916 QUnicodeTables::Devanagari, // Devanagari
917 QUnicodeTables::Bengali, // Bengali
918 QUnicodeTables::Gurmukhi, // Gurmukhi
919 QUnicodeTables::Gujarati, // Gujarati
920 QUnicodeTables::Oriya, // Oriya
921 QUnicodeTables::Tamil, // Tamil
922 QUnicodeTables::Telugu, // Telugu
923 QUnicodeTables::Kannada, // Kannada
924 QUnicodeTables::Malayalam, // Malayalam
925 QUnicodeTables::Sinhala, // Sinhala
926 QUnicodeTables::Thai, // Thai
927 QUnicodeTables::Lao, // Lao
928 QUnicodeTables::Tibetan, // Tibetan
929 QUnicodeTables::Myanmar, // Myanmar
930 QUnicodeTables::Georgian, // Georgian
931 QUnicodeTables::Khmer, // Khmer
932 QUnicodeTables::Common, // SimplifiedChinese
933 QUnicodeTables::Common, // TraditionalChinese
934 QUnicodeTables::Common, // Japanese
935 QUnicodeTables::Hangul, // Korean
936 QUnicodeTables::Common, // Vietnamese
937 QUnicodeTables::Common, // Yi
938 QUnicodeTables::Common, // Tagalog
939 QUnicodeTables::Common, // Hanunoo
940 QUnicodeTables::Common, // Buhid
941 QUnicodeTables::Common, // Tagbanwa
942 QUnicodeTables::Common, // Limbu
943 QUnicodeTables::Common, // TaiLe
944 QUnicodeTables::Common, // Braille
945 QUnicodeTables::Common, // Symbol
946 QUnicodeTables::Ogham, // Ogham
947 QUnicodeTables::Runic, // Runic
948 QUnicodeTables::Nko // Nko
951 int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem)
953 return scriptForWritingSystem[writingSystem];
957 #if defined Q_WS_QWS || (defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)) || defined(Q_WS_WIN)
958 static inline bool requiresOpenType(int writingSystem)
960 return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
961 || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
963 static inline bool scriptRequiresOpenType(int script)
965 return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
966 || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
974 This makes sense of the font family name:
976 if the family name contains a '[' and a ']', then we take the text
977 between the square brackets as the foundry, and the text before the
978 square brackets as the family (ie. "Arial [Monotype]")
980 static void parseFontName(const QString &name, QString &foundry, QString &family)
982 int i = name.indexOf(QLatin1Char('['));
983 int li = name.lastIndexOf(QLatin1Char(']'));
984 if (i >= 0 && li >= 0 && i < li) {
985 foundry = name.mid(i + 1, li - i - 1);
986 if (i > 0 && name[i - 1] == QLatin1Char(' '))
988 family = name.left(i);
994 // capitalize the family/foundry names
996 QChar *s = family.data();
997 int len = family.length();
999 if (space) *s = s->toUpper();
1000 space = s->isSpace();
1006 len = foundry.length();
1008 if (space) *s = s->toUpper();
1009 space = s->isSpace();
1017 inline QtFontDesc() : family(0), foundry(0), style(0), size(0), encoding(0), familyIndex(-1) {}
1018 QtFontFamily *family;
1019 QtFontFoundry *foundry;
1022 QtFontEncoding *encoding;
1026 #if !defined(Q_WS_MAC)
1027 static void match(int script, const QFontDef &request,
1028 const QString &family_name, const QString &foundry_name, int force_encoding_id,
1029 QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>(), bool forceXLFD=false);
1031 #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_QPA)
1032 static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef)
1034 fontDef->family = desc.family->name;
1035 if (! desc.foundry->name.isEmpty() && desc.family->count > 1) {
1036 fontDef->family += QString::fromLatin1(" [");
1037 fontDef->family += desc.foundry->name;
1038 fontDef->family += QLatin1Char(']');
1041 if (desc.style->smoothScalable)
1042 fontDef->pixelSize = request.pixelSize;
1043 else if ((desc.style->bitmapScalable && (request.styleStrategy & QFont::PreferMatch)))
1044 fontDef->pixelSize = request.pixelSize;
1046 fontDef->pixelSize = desc.size->pixelSize;
1048 fontDef->styleHint = request.styleHint;
1049 fontDef->styleStrategy = request.styleStrategy;
1051 fontDef->weight = desc.style->key.weight;
1052 fontDef->style = desc.style->key.style;
1053 fontDef->fixedPitch = desc.family->fixedPitch;
1054 fontDef->stretch = desc.style->key.stretch;
1055 fontDef->ignorePitch = false;
1060 #if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) || defined(Q_WS_QPA)
1061 static void getEngineData(const QFontPrivate *d, const QFontCache::Key &key)
1063 // look for the requested font in the engine data cache
1064 d->engineData = QFontCache::instance()->findEngineData(key);
1065 if (!d->engineData) {
1067 d->engineData = new QFontEngineData;
1068 QFontCache::instance()->insertEngineData(key, d->engineData);
1070 d->engineData->ref.ref();
1075 static QStringList familyList(const QFontDef &req)
1077 // list of families to try
1078 QStringList family_list;
1079 if (req.family.isEmpty())
1082 QStringList list = req.family.split(QLatin1Char(','));
1083 for (int i = 0; i < list.size(); ++i) {
1084 QString str = list.at(i).trimmed();
1085 if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
1086 || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
1087 str = str.mid(1, str.length() - 2);
1091 // append the substitute list for each family in family_list
1092 QStringList subs_list;
1093 QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
1094 for (; it != end; ++it)
1095 subs_list += QFont::substitutes(*it);
1096 // qDebug() << "adding substs: " << subs_list;
1098 family_list += subs_list;
1103 Q_GLOBAL_STATIC(QFontDatabasePrivate, privateDb)
1104 Q_GLOBAL_STATIC_WITH_ARGS(QMutex, fontDatabaseMutex, (QMutex::Recursive))
1106 // used in qfontengine_x11.cpp
1107 QMutex *qt_fontdatabase_mutex()
1109 return fontDatabaseMutex();
1112 QT_BEGIN_INCLUDE_NAMESPACE
1113 #if defined(Q_WS_X11)
1114 # include "qfontdatabase_x11.cpp"
1115 #elif defined(Q_WS_MAC)
1116 # include "qfontdatabase_mac.cpp"
1117 #elif defined(Q_WS_WIN)
1118 # include "qfontdatabase_win.cpp"
1119 #elif defined(Q_WS_QWS)
1120 # include "qfontdatabase_qws.cpp"
1121 #elif defined(Q_WS_QPA)
1122 # include "qfontdatabase_qpa.cpp"
1123 #elif defined(Q_OS_SYMBIAN)
1124 # include "qfontdatabase_s60.cpp"
1126 QT_END_INCLUDE_NAMESPACE
1127 #if !defined(Q_WS_X11)
1128 QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
1134 static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey)
1139 for ( int i = 0; i < foundry->count; i++ ) {
1140 QtFontStyle *style = foundry->styles[i];
1142 int d = qAbs( styleKey.weight - style->key.weight );
1144 if ( styleKey.stretch != 0 && style->key.stretch != 0 ) {
1145 d += qAbs( styleKey.stretch - style->key.stretch );
1148 if (styleKey.style != style->key.style) {
1149 if (styleKey.style != QFont::StyleNormal && style->key.style != QFont::StyleNormal)
1150 // one is italic, the other oblique
1162 FM_DEBUG( " best style has distance 0x%x", dist );
1163 return foundry->styles[best];
1166 #if defined(Q_WS_X11)
1167 static QtFontEncoding *findEncoding(int script, int styleStrategy,
1168 QtFontSize *size, int force_encoding_id)
1170 QtFontEncoding *encoding = 0;
1172 if (force_encoding_id >= 0) {
1173 encoding = size->encodingID(force_encoding_id);
1175 FM_DEBUG(" required encoding_id not available");
1179 if (styleStrategy & (QFont::OpenGLCompatible | QFont::PreferBitmap)) {
1180 FM_DEBUG(" PreferBitmap and/or OpenGL set, skipping Freetype");
1182 encoding = size->encodingID(-1); // -1 == prefer Freetype
1187 // FT not available, find an XLFD font, trying the default encoding first
1188 encoding = size->encodingID(QFontPrivate::defaultEncodingID);
1190 // does it support the requested script?
1191 bool supportsScript = false;
1192 for (int ws = 1; !supportsScript && ws < QFontDatabase::WritingSystemsCount; ++ws) {
1193 if (scriptForWritingSystem[ws] != script)
1195 supportsScript = writingSystems_for_xlfd_encoding[encoding->encoding][ws];
1197 if (!supportsScript)
1200 // find the first encoding that supports the requested script
1201 for (int ws = 1; !encoding && ws < QFontDatabase::WritingSystemsCount; ++ws) {
1202 if (scriptForWritingSystem[ws] != script)
1204 for (int x = 0; !encoding && x < size->count; ++x) {
1205 const int enc = size->encodings[x].encoding;
1206 if (writingSystems_for_xlfd_encoding[enc][ws])
1207 encoding = size->encodings + x;
1215 #if !defined(Q_WS_MAC)
1217 unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
1218 const QtFontFamily *family, const QString &foundry_name,
1219 QtFontStyle::Key styleKey, int pixelSize, char pitch,
1220 QtFontDesc *desc, int force_encoding_id)
1222 Q_UNUSED(force_encoding_id);
1232 FM_DEBUG(" REMARK: looking for best foundry for family '%s' [%d]", family->name.toLatin1().constData(), family->count);
1234 for (int x = 0; x < family->count; ++x) {
1235 QtFontFoundry *foundry = family->foundries[x];
1236 if (!foundry_name.isEmpty() && foundry->name.compare(foundry_name, Qt::CaseInsensitive) != 0)
1239 FM_DEBUG(" looking for matching style in foundry '%s' %d",
1240 foundry->name.isEmpty() ? "-- none --" : foundry->name.toLatin1().constData(), foundry->count);
1242 QtFontStyle *style = bestStyle(foundry, styleKey);
1244 if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) {
1245 FM_DEBUG(" ForceOutline set, but not smoothly scalable");
1250 QtFontSize *size = 0;
1252 // 1. see if we have an exact matching size
1253 if (!(styleStrategy & QFont::ForceOutline)) {
1254 size = style->pixelSize(pixelSize);
1256 FM_DEBUG(" found exact size match (%d pixels)", size->pixelSize);
1257 px = size->pixelSize;
1261 // 2. see if we have a smoothly scalable font
1262 if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
1263 size = style->pixelSize(SMOOTH_SCALABLE);
1265 FM_DEBUG(" found smoothly scalable font (%d pixels)", pixelSize);
1270 // 3. see if we have a bitmap scalable font
1271 if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
1272 size = style->pixelSize(0);
1274 FM_DEBUG(" found bitmap scalable font (%d pixels)", pixelSize);
1280 QtFontEncoding *encoding = 0;
1283 // 4. find closest size match
1285 unsigned int distance = ~0u;
1286 for (int x = 0; x < style->count; ++x) {
1289 findEncoding(script, styleStrategy, style->pixelSizes + x, force_encoding_id);
1291 FM_DEBUG(" size %3d does not support the script we want",
1292 style->pixelSizes[x].pixelSize);
1298 if (style->pixelSizes[x].pixelSize < pixelSize) {
1299 // penalize sizes that are smaller than the
1300 // requested size, due to truncation from floating
1301 // point to integer conversions
1302 d = pixelSize - style->pixelSizes[x].pixelSize + 1;
1304 d = style->pixelSizes[x].pixelSize - pixelSize;
1309 size = style->pixelSizes + x;
1310 FM_DEBUG(" best size so far: %3d (%d)", size->pixelSize, pixelSize);
1315 FM_DEBUG(" no size supports the script we want");
1319 if (style->bitmapScalable && ! (styleStrategy & QFont::PreferQuality) &&
1320 (distance * 10 / pixelSize) >= 2) {
1321 // the closest size is not close enough, go ahead and
1322 // use a bitmap scaled font
1323 size = style->pixelSize(0);
1326 px = size->pixelSize;
1332 encoding = findEncoding(script, styleStrategy, size, force_encoding_id);
1333 if (!encoding) size = 0;
1336 FM_DEBUG(" foundry doesn't support the script we want");
1341 unsigned int this_score = 0x0000;
1343 PitchMismatch = 0x4000,
1344 StyleMismatch = 0x2000,
1345 BitmapScaledPenalty = 0x1000,
1346 EncodingMismatch = 0x0002,
1347 XLFDPenalty = 0x0001
1350 if (encoding->encoding != -1) {
1351 this_score += XLFDPenalty;
1352 if (encoding->encoding != QFontPrivate::defaultEncodingID)
1353 this_score += EncodingMismatch;
1356 if (!(pitch == 'm' && encoding->pitch == 'c') && pitch != encoding->pitch)
1357 this_score += PitchMismatch;
1361 #if !defined(QWS) && defined(Q_OS_MAC)
1362 qt_mac_get_fixed_pitch(const_cast<QtFontFamily*>(family));
1364 if ((pitch == 'm' && !family->fixedPitch)
1365 || (pitch == 'p' && family->fixedPitch))
1366 this_score += PitchMismatch;
1369 if (styleKey != style->key)
1370 this_score += StyleMismatch;
1371 if (!style->smoothScalable && px != size->pixelSize) // bitmap scaled
1372 this_score += BitmapScaledPenalty;
1373 if (px != pixelSize) // close, but not exact, size match
1374 this_score += qAbs(px - pixelSize);
1376 if (this_score < score) {
1377 FM_DEBUG(" found a match: score %x best score so far %x",
1381 desc->foundry = foundry;
1382 desc->style = style;
1385 desc->encoding = encoding;
1388 FM_DEBUG(" score %x no better than best %x", this_score, score);
1396 #if !defined(Q_WS_MAC)
1400 Tries to find the best match for a given request and family/foundry
1402 static void match(int script, const QFontDef &request,
1403 const QString &family_name, const QString &foundry_name, int force_encoding_id,
1404 QtFontDesc *desc, const QList<int> &blacklistedFamilies, bool forceXLFD)
1406 Q_UNUSED(force_encoding_id);
1408 QtFontStyle::Key styleKey;
1409 styleKey.style = request.style;
1410 styleKey.weight = request.weight;
1411 styleKey.stretch = request.stretch;
1412 char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';
1415 FM_DEBUG("QFontDatabase::match\n"
1417 " family: %s [%s], script: %d\n"
1418 " weight: %d, style: %d\n"
1422 family_name.isEmpty() ? "-- first in script --" : family_name.toLatin1().constData(),
1423 foundry_name.isEmpty() ? "-- any --" : foundry_name.toLatin1().constData(),
1424 script, request.weight, request.style, request.stretch, request.pixelSize, pitch);
1425 #if defined(FONT_MATCH_DEBUG) && defined(Q_WS_X11)
1426 if (force_encoding_id >= 0) {
1427 FM_DEBUG(" required encoding: %d", force_encoding_id);
1436 desc->familyIndex = -1;
1438 unsigned int score = ~0u;
1441 load(family_name, script, forceXLFD);
1443 Q_UNUSED(forceXLFD);
1444 load(family_name, script);
1447 QFontDatabasePrivate *db = privateDb();
1448 for (int x = 0; x < db->count; ++x) {
1449 if (blacklistedFamilies.contains(x))
1452 test.family = db->families[x];
1453 test.familyIndex = x;
1455 if (!family_name.isEmpty()
1456 && test.family->name.compare(family_name, Qt::CaseInsensitive) != 0
1458 && test.family->english_name.compare(family_name, Qt::CaseInsensitive) != 0
1463 if (family_name.isEmpty())
1464 load(test.family->name, script);
1466 uint score_adjust = 0;
1468 bool supported = (script == QUnicodeTables::Common);
1469 for (int ws = 1; !supported && ws < QFontDatabase::WritingSystemsCount; ++ws) {
1470 if (scriptForWritingSystem[ws] != script)
1472 if (test.family->writingSystems[ws] & QtFontFamily::Supported)
1476 // family not supported in the script we want
1480 // as we know the script is supported, we can be sure
1481 // to find a matching font here.
1482 unsigned int newscore =
1483 bestFoundry(script, score, request.styleStrategy,
1484 test.family, foundry_name, styleKey, request.pixelSize, pitch,
1485 &test, force_encoding_id);
1486 if (test.foundry == 0) {
1487 // the specific foundry was not found, so look for
1488 // any foundry matching our requirements
1489 newscore = bestFoundry(script, score, request.styleStrategy, test.family,
1490 QString(), styleKey, request.pixelSize,
1491 pitch, &test, force_encoding_id);
1493 newscore += score_adjust;
1495 if (newscore < score) {
1499 if (newscore < 10) // xlfd instead of FT... just accept it
1505 static QString styleStringHelper(int weight, QFont::Style style)
1508 if (weight >= QFont::Black)
1509 result = QApplication::translate("QFontDatabase", "Black");
1510 else if (weight >= QFont::Bold)
1511 result = QApplication::translate("QFontDatabase", "Bold");
1512 else if (weight >= QFont::DemiBold)
1513 result = QApplication::translate("QFontDatabase", "Demi Bold");
1514 else if (weight < QFont::Normal)
1515 result = QApplication::translate("QFontDatabase", "Light");
1517 if (style == QFont::StyleItalic)
1518 result += QLatin1Char(' ') + QApplication::translate("QFontDatabase", "Italic");
1519 else if (style == QFont::StyleOblique)
1520 result += QLatin1Char(' ') + QApplication::translate("QFontDatabase", "Oblique");
1522 if (result.isEmpty())
1523 result = QApplication::translate("QFontDatabase", "Normal");
1525 return result.simplified();
1529 Returns a string that describes the style of the \a font. For
1530 example, "Bold Italic", "Bold", "Italic" or "Normal". An empty
1531 string may be returned.
1533 QString QFontDatabase::styleString(const QFont &font)
1535 return styleStringHelper(font.weight(), font.style());
1539 Returns a string that describes the style of the \a fontInfo. For
1540 example, "Bold Italic", "Bold", "Italic" or "Normal". An empty
1541 string may be returned.
1543 QString QFontDatabase::styleString(const QFontInfo &fontInfo)
1545 return styleStringHelper(fontInfo.weight(), fontInfo.style());
1550 \class QFontDatabase
1553 \brief The QFontDatabase class provides information about the fonts available in the underlying window system.
1557 The most common uses of this class are to query the database for
1558 the list of font families() and for the pointSizes() and styles()
1559 that are available for each family. An alternative to pointSizes()
1560 is smoothSizes() which returns the sizes at which a given family
1561 and style will look attractive.
1563 If the font family is available from two or more foundries the
1564 foundry name is included in the family name; for example:
1565 "Helvetica [Adobe]" and "Helvetica [Cronyx]". When you specify a
1566 family, you can either use the old hyphenated "foundry-family"
1567 format or the bracketed "family [foundry]" format; for example:
1568 "Cronyx-Helvetica" or "Helvetica [Cronyx]". If the family has a
1569 foundry it is always returned using the bracketed format, as is
1570 the case with the value returned by families().
1572 The font() function returns a QFont given a family, style and
1575 A family and style combination can be checked to see if it is
1576 italic() or bold(), and to retrieve its weight(). Similarly we can
1577 call isBitmapScalable(), isSmoothlyScalable(), isScalable() and
1580 Use the styleString() to obtain a text version of a style.
1582 The QFontDatabase class also supports some static functions, for
1583 example, standardSizes(). You can retrieve the description of a
1584 writing system using writingSystemName(), and a sample of
1585 characters in a writing system with writingSystemSample().
1589 \snippet doc/src/snippets/qfontdatabase/main.cpp 0
1590 \snippet doc/src/snippets/qfontdatabase/main.cpp 1
1592 This example gets the list of font families, the list of
1593 styles for each family, and the point sizes that are available for
1594 each combination of family and style, displaying this information
1597 \sa QFont, QFontInfo, QFontMetrics, QFontComboBox, {Character Map Example}
1601 Creates a font database object.
1603 QFontDatabase::QFontDatabase()
1605 QMutexLocker locker(fontDatabaseMutex());
1611 \enum QFontDatabase::WritingSystem
1638 \value SimplifiedChinese
1639 \value TraditionalChinese
1644 \value Other (the same as Symbol)
1649 \omitvalue WritingSystemsCount
1653 Returns a sorted list of the available writing systems. This is
1654 list generated from information about all installed fonts on the
1659 QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems() const
1661 QMutexLocker locker(fontDatabaseMutex());
1663 QT_PREPEND_NAMESPACE(load)();
1668 QList<WritingSystem> list;
1669 for (int i = 0; i < d->count; ++i) {
1670 QtFontFamily *family = d->families[i];
1671 if (family->count == 0)
1673 for (int x = Latin; x < WritingSystemsCount; ++x) {
1674 const WritingSystem writingSystem = WritingSystem(x);
1675 if (!(family->writingSystems[writingSystem] & QtFontFamily::Supported))
1677 if (!list.contains(writingSystem))
1678 list.append(writingSystem);
1687 Returns a sorted list of the writing systems supported by a given
1692 QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems(const QString &family) const
1694 QString familyName, foundryName;
1695 parseFontName(family, foundryName, familyName);
1697 QMutexLocker locker(fontDatabaseMutex());
1699 QT_PREPEND_NAMESPACE(load)();
1701 checkSymbolFonts(familyName);
1704 QList<WritingSystem> list;
1705 QtFontFamily *f = d->family(familyName);
1706 if (!f || f->count == 0)
1709 for (int x = Latin; x < WritingSystemsCount; ++x) {
1710 const WritingSystem writingSystem = WritingSystem(x);
1711 if (f->writingSystems[writingSystem] & QtFontFamily::Supported)
1712 list.append(writingSystem);
1719 Returns a sorted list of the available font families which support
1720 the \a writingSystem.
1722 If a family exists in several foundries, the returned name for
1723 that font is in the form "family [foundry]". Examples: "Times
1724 [Adobe]", "Times [Cronyx]", "Palatino".
1726 \sa writingSystems()
1728 QStringList QFontDatabase::families(WritingSystem writingSystem) const
1730 QMutexLocker locker(fontDatabaseMutex());
1732 QT_PREPEND_NAMESPACE(load)();
1734 if (writingSystem != Any)
1739 for (int i = 0; i < d->count; i++) {
1740 QtFontFamily *f = d->families[i];
1743 if (writingSystem != Any && (f->writingSystems[writingSystem] != QtFontFamily::Supported))
1745 if (f->count == 1) {
1746 flist.append(f->name);
1748 for (int j = 0; j < f->count; j++) {
1749 QString str = f->name;
1750 QString foundry = f->foundries[j]->name;
1751 if (!foundry.isEmpty()) {
1752 str += QLatin1String(" [");
1754 str += QLatin1Char(']');
1764 Returns a list of the styles available for the font family \a
1765 family. Some example styles: "Light", "Light Italic", "Bold",
1766 "Oblique", "Demi". The list may be empty.
1770 QStringList QFontDatabase::styles(const QString &family) const
1772 QString familyName, foundryName;
1773 parseFontName(family, foundryName, familyName);
1775 QMutexLocker locker(fontDatabaseMutex());
1777 QT_PREPEND_NAMESPACE(load)(familyName);
1780 QtFontFamily *f = d->family(familyName);
1784 QtFontFoundry allStyles(foundryName);
1785 for (int j = 0; j < f->count; j++) {
1786 QtFontFoundry *foundry = f->foundries[j];
1787 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1788 for (int k = 0; k < foundry->count; k++) {
1789 QtFontStyle::Key ke(foundry->styles[k]->key);
1791 allStyles.style(ke, true);
1796 for (int i = 0; i < allStyles.count; i++)
1797 l.append(styleStringHelper(allStyles.styles[i]->key.weight, (QFont::Style)allStyles.styles[i]->key.style));
1802 Returns true if the font that has family \a family and style \a
1803 style is fixed pitch; otherwise returns false.
1806 bool QFontDatabase::isFixedPitch(const QString &family,
1807 const QString &style) const
1811 QString familyName, foundryName;
1812 parseFontName(family, foundryName, familyName);
1814 QMutexLocker locker(fontDatabaseMutex());
1816 QT_PREPEND_NAMESPACE(load)(familyName);
1818 QtFontFamily *f = d->family(familyName);
1819 #if !defined(QWS) && defined(Q_OS_MAC)
1820 qt_mac_get_fixed_pitch(f);
1822 return (f && f->fixedPitch);
1826 Returns true if the font that has family \a family and style \a
1827 style is a scalable bitmap font; otherwise returns false. Scaling
1828 a bitmap font usually produces an unattractive hardly readable
1829 result, because the pixels of the font are scaled. If you need to
1830 scale a bitmap font it is better to scale it to one of the fixed
1831 sizes returned by smoothSizes().
1833 \sa isScalable(), isSmoothlyScalable()
1835 bool QFontDatabase::isBitmapScalable(const QString &family,
1836 const QString &style) const
1838 bool bitmapScalable = false;
1839 QString familyName, foundryName;
1840 parseFontName(family, foundryName, familyName);
1842 QMutexLocker locker(fontDatabaseMutex());
1844 QT_PREPEND_NAMESPACE(load)(familyName);
1846 QtFontStyle::Key styleKey(style);
1848 QtFontFamily *f = d->family(familyName);
1849 if (!f) return bitmapScalable;
1851 for (int j = 0; j < f->count; j++) {
1852 QtFontFoundry *foundry = f->foundries[j];
1853 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1854 for (int k = 0; k < foundry->count; k++)
1855 if ((style.isEmpty() || foundry->styles[k]->key == styleKey)
1856 && foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
1857 bitmapScalable = true;
1863 return bitmapScalable;
1868 Returns true if the font that has family \a family and style \a
1869 style is smoothly scalable; otherwise returns false. If this
1870 function returns true, it's safe to scale this font to any size,
1871 and the result will always look attractive.
1873 \sa isScalable(), isBitmapScalable()
1875 bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &style) const
1877 bool smoothScalable = false;
1878 QString familyName, foundryName;
1879 parseFontName(family, foundryName, familyName);
1881 QMutexLocker locker(fontDatabaseMutex());
1883 QT_PREPEND_NAMESPACE(load)(familyName);
1885 QtFontStyle::Key styleKey(style);
1887 QtFontFamily *f = d->family(familyName);
1888 if (!f) return smoothScalable;
1890 for (int j = 0; j < f->count; j++) {
1891 QtFontFoundry *foundry = f->foundries[j];
1892 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1893 for (int k = 0; k < foundry->count; k++)
1894 if ((style.isEmpty() || foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) {
1895 smoothScalable = true;
1901 return smoothScalable;
1905 Returns true if the font that has family \a family and style \a
1906 style is scalable; otherwise returns false.
1908 \sa isBitmapScalable(), isSmoothlyScalable()
1910 bool QFontDatabase::isScalable(const QString &family,
1911 const QString &style) const
1913 QMutexLocker locker(fontDatabaseMutex());
1914 if (isSmoothlyScalable(family, style))
1916 return isBitmapScalable(family, style);
1921 Returns a list of the point sizes available for the font that has
1922 family \a family and style \a style. The list may be empty.
1924 \sa smoothSizes(), standardSizes()
1926 QList<int> QFontDatabase::pointSizes(const QString &family,
1927 const QString &style)
1929 #if defined(Q_WS_WIN)
1930 // windows and macosx are always smoothly scalable
1933 return standardSizes();
1935 bool smoothScalable = false;
1936 QString familyName, foundryName;
1937 parseFontName(family, foundryName, familyName);
1939 QMutexLocker locker(fontDatabaseMutex());
1941 QT_PREPEND_NAMESPACE(load)(familyName);
1943 QtFontStyle::Key styleKey(style);
1947 QtFontFamily *fam = d->family(familyName);
1948 if (!fam) return sizes;
1952 int dpi = QX11Info::appDpiY();
1954 const int dpi = qt_defaultDpiY(); // embedded
1957 for (int j = 0; j < fam->count; j++) {
1958 QtFontFoundry *foundry = fam->foundries[j];
1959 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1960 QtFontStyle *style = foundry->style(styleKey);
1961 if (!style) continue;
1963 if (style->smoothScalable) {
1964 smoothScalable = true;
1967 for (int l = 0; l < style->count; l++) {
1968 const QtFontSize *size = style->pixelSizes + l;
1970 if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) {
1971 const uint pointSize = qRound(size->pixelSize * 72.0 / dpi);
1972 if (! sizes.contains(pointSize))
1973 sizes.append(pointSize);
1980 return standardSizes();
1988 Returns a QFont object that has family \a family, style \a style
1989 and point size \a pointSize. If no matching font could be created,
1990 a QFont object that uses the application's default font is
1993 QFont QFontDatabase::font(const QString &family, const QString &style,
1994 int pointSize) const
1996 QString familyName, foundryName;
1997 parseFontName(family, foundryName, familyName);
1999 QMutexLocker locker(fontDatabaseMutex());
2001 QT_PREPEND_NAMESPACE(load)(familyName);
2003 QtFontFoundry allStyles(foundryName);
2004 QtFontFamily *f = d->family(familyName);
2005 if (!f) return QApplication::font();
2007 for (int j = 0; j < f->count; j++) {
2008 QtFontFoundry *foundry = f->foundries[j];
2009 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
2010 for (int k = 0; k < foundry->count; k++)
2011 allStyles.style(foundry->styles[k]->key, true);
2015 QtFontStyle::Key styleKey(style);
2016 QtFontStyle *s = bestStyle(&allStyles, styleKey);
2018 if (!s) // no styles found?
2019 return QApplication::font();
2020 QFont fnt(family, pointSize, s->key.weight);
2021 fnt.setStyle((QFont::Style)s->key.style);
2027 Returns the point sizes of a font that has family \a family and
2028 style \a style that will look attractive. The list may be empty.
2029 For non-scalable fonts and bitmap scalable fonts, this function
2030 is equivalent to pointSizes().
2032 \sa pointSizes(), standardSizes()
2034 QList<int> QFontDatabase::smoothSizes(const QString &family,
2035 const QString &style)
2040 return QFontDatabase::standardSizes();
2042 bool smoothScalable = false;
2043 QString familyName, foundryName;
2044 parseFontName(family, foundryName, familyName);
2046 QMutexLocker locker(fontDatabaseMutex());
2048 QT_PREPEND_NAMESPACE(load)(familyName);
2050 QtFontStyle::Key styleKey(style);
2054 QtFontFamily *fam = d->family(familyName);
2059 int dpi = QX11Info::appDpiY();
2061 const int dpi = qt_defaultDpiY(); // embedded
2064 for (int j = 0; j < fam->count; j++) {
2065 QtFontFoundry *foundry = fam->foundries[j];
2066 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
2067 QtFontStyle *style = foundry->style(styleKey);
2068 if (!style) continue;
2070 if (style->smoothScalable) {
2071 smoothScalable = true;
2074 for (int l = 0; l < style->count; l++) {
2075 const QtFontSize *size = style->pixelSizes + l;
2077 if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) {
2078 const uint pointSize = qRound(size->pixelSize * 72.0 / dpi);
2079 if (! sizes.contains(pointSize))
2080 sizes.append(pointSize);
2087 return QFontDatabase::standardSizes();
2096 Returns a list of standard font sizes.
2098 \sa smoothSizes(), pointSizes()
2100 QList<int> QFontDatabase::standardSizes()
2103 static const unsigned short standard[] =
2104 { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72, 0 };
2105 const unsigned short *sizes = standard;
2106 while (*sizes) ret << *sizes++;
2112 Returns true if the font that has family \a family and style \a
2113 style is italic; otherwise returns false.
2115 \sa weight(), bold()
2117 bool QFontDatabase::italic(const QString &family, const QString &style) const
2119 QString familyName, foundryName;
2120 parseFontName(family, foundryName, familyName);
2122 QMutexLocker locker(fontDatabaseMutex());
2124 QT_PREPEND_NAMESPACE(load)(familyName);
2126 QtFontFoundry allStyles(foundryName);
2127 QtFontFamily *f = d->family(familyName);
2128 if (!f) return false;
2130 for (int j = 0; j < f->count; j++) {
2131 QtFontFoundry *foundry = f->foundries[j];
2132 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
2133 for (int k = 0; k < foundry->count; k++)
2134 allStyles.style(foundry->styles[k]->key, true);
2138 QtFontStyle::Key styleKey(style);
2139 QtFontStyle *s = allStyles.style(styleKey);
2140 return s && s->key.style == QFont::StyleItalic;
2145 Returns true if the font that has family \a family and style \a
2146 style is bold; otherwise returns false.
2148 \sa italic(), weight()
2150 bool QFontDatabase::bold(const QString &family,
2151 const QString &style) const
2153 QString familyName, foundryName;
2154 parseFontName(family, foundryName, familyName);
2156 QMutexLocker locker(fontDatabaseMutex());
2158 QT_PREPEND_NAMESPACE(load)(familyName);
2160 QtFontFoundry allStyles(foundryName);
2161 QtFontFamily *f = d->family(familyName);
2162 if (!f) return false;
2164 for (int j = 0; j < f->count; j++) {
2165 QtFontFoundry *foundry = f->foundries[j];
2166 if (foundryName.isEmpty() ||
2167 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
2168 for (int k = 0; k < foundry->count; k++)
2169 allStyles.style(foundry->styles[k]->key, true);
2173 QtFontStyle::Key styleKey(style);
2174 QtFontStyle *s = allStyles.style(styleKey);
2175 return s && s->key.weight >= QFont::Bold;
2180 Returns the weight of the font that has family \a family and style
2181 \a style. If there is no such family and style combination,
2184 \sa italic(), bold()
2186 int QFontDatabase::weight(const QString &family,
2187 const QString &style) const
2189 QString familyName, foundryName;
2190 parseFontName(family, foundryName, familyName);
2192 QMutexLocker locker(fontDatabaseMutex());
2194 QT_PREPEND_NAMESPACE(load)(familyName);
2196 QtFontFoundry allStyles(foundryName);
2197 QtFontFamily *f = d->family(familyName);
2200 for (int j = 0; j < f->count; j++) {
2201 QtFontFoundry *foundry = f->foundries[j];
2202 if (foundryName.isEmpty() ||
2203 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
2204 for (int k = 0; k < foundry->count; k++)
2205 allStyles.style(foundry->styles[k]->key, true);
2209 QtFontStyle::Key styleKey(style);
2210 QtFontStyle *s = allStyles.style(styleKey);
2211 return s ? s->key.weight : -1;
2216 Returns the names the \a writingSystem (e.g. for displaying to the
2219 QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
2221 const char *name = 0;
2222 switch (writingSystem) {
2224 name = QT_TRANSLATE_NOOP("QFontDatabase", "Any");
2227 name = QT_TRANSLATE_NOOP("QFontDatabase", "Latin");
2230 name = QT_TRANSLATE_NOOP("QFontDatabase", "Greek");
2233 name = QT_TRANSLATE_NOOP("QFontDatabase", "Cyrillic");
2236 name = QT_TRANSLATE_NOOP("QFontDatabase", "Armenian");
2239 name = QT_TRANSLATE_NOOP("QFontDatabase", "Hebrew");
2242 name = QT_TRANSLATE_NOOP("QFontDatabase", "Arabic");
2245 name = QT_TRANSLATE_NOOP("QFontDatabase", "Syriac");
2248 name = QT_TRANSLATE_NOOP("QFontDatabase", "Thaana");
2251 name = QT_TRANSLATE_NOOP("QFontDatabase", "Devanagari");
2254 name = QT_TRANSLATE_NOOP("QFontDatabase", "Bengali");
2257 name = QT_TRANSLATE_NOOP("QFontDatabase", "Gurmukhi");
2260 name = QT_TRANSLATE_NOOP("QFontDatabase", "Gujarati");
2263 name = QT_TRANSLATE_NOOP("QFontDatabase", "Oriya");
2266 name = QT_TRANSLATE_NOOP("QFontDatabase", "Tamil");
2269 name = QT_TRANSLATE_NOOP("QFontDatabase", "Telugu");
2272 name = QT_TRANSLATE_NOOP("QFontDatabase", "Kannada");
2275 name = QT_TRANSLATE_NOOP("QFontDatabase", "Malayalam");
2278 name = QT_TRANSLATE_NOOP("QFontDatabase", "Sinhala");
2281 name = QT_TRANSLATE_NOOP("QFontDatabase", "Thai");
2284 name = QT_TRANSLATE_NOOP("QFontDatabase", "Lao");
2287 name = QT_TRANSLATE_NOOP("QFontDatabase", "Tibetan");
2290 name = QT_TRANSLATE_NOOP("QFontDatabase", "Myanmar");
2293 name = QT_TRANSLATE_NOOP("QFontDatabase", "Georgian");
2296 name = QT_TRANSLATE_NOOP("QFontDatabase", "Khmer");
2298 case SimplifiedChinese:
2299 name = QT_TRANSLATE_NOOP("QFontDatabase", "Simplified Chinese");
2301 case TraditionalChinese:
2302 name = QT_TRANSLATE_NOOP("QFontDatabase", "Traditional Chinese");
2305 name = QT_TRANSLATE_NOOP("QFontDatabase", "Japanese");
2308 name = QT_TRANSLATE_NOOP("QFontDatabase", "Korean");
2311 name = QT_TRANSLATE_NOOP("QFontDatabase", "Vietnamese");
2314 name = QT_TRANSLATE_NOOP("QFontDatabase", "Symbol");
2317 name = QT_TRANSLATE_NOOP("QFontDatabase", "Ogham");
2320 name = QT_TRANSLATE_NOOP("QFontDatabase", "Runic");
2323 name = QT_TRANSLATE_NOOP("QFontDatabase", "N'Ko");
2326 Q_ASSERT_X(false, "QFontDatabase::writingSystemName", "invalid 'writingSystem' parameter");
2329 return QApplication::translate("QFontDatabase", name);
2334 Returns a string with sample characters from \a writingSystem.
2336 QString QFontDatabase::writingSystemSample(WritingSystem writingSystem)
2339 switch (writingSystem) {
2342 // show only ascii characters
2343 sample += QLatin1String("AaBbzZ");
2346 // This is cheating... we only show latin-1 characters so that we don't
2347 // end up loading lots of fonts - at least on X11...
2348 sample = QLatin1String("Aa");
2349 sample += QChar(0x00C3);
2350 sample += QChar(0x00E1);
2351 sample += QLatin1String("Zz");
2354 sample += QChar(0x0393);
2355 sample += QChar(0x03B1);
2356 sample += QChar(0x03A9);
2357 sample += QChar(0x03C9);
2360 sample += QChar(0x0414);
2361 sample += QChar(0x0434);
2362 sample += QChar(0x0436);
2363 sample += QChar(0x044f);
2366 sample += QChar(0x053f);
2367 sample += QChar(0x054f);
2368 sample += QChar(0x056f);
2369 sample += QChar(0x057f);
2372 sample += QChar(0x05D0);
2373 sample += QChar(0x05D1);
2374 sample += QChar(0x05D2);
2375 sample += QChar(0x05D3);
2378 sample += QChar(0x0628);
2379 sample += QChar(0x0629);
2380 sample += QChar(0x062A);
2381 sample += QChar(0x063A);
2384 sample += QChar(0x0715);
2385 sample += QChar(0x0725);
2386 sample += QChar(0x0716);
2387 sample += QChar(0x0726);
2390 sample += QChar(0x0784);
2391 sample += QChar(0x0794);
2392 sample += QChar(0x078c);
2393 sample += QChar(0x078d);
2396 sample += QChar(0x0905);
2397 sample += QChar(0x0915);
2398 sample += QChar(0x0925);
2399 sample += QChar(0x0935);
2402 sample += QChar(0x0986);
2403 sample += QChar(0x0996);
2404 sample += QChar(0x09a6);
2405 sample += QChar(0x09b6);
2408 sample += QChar(0x0a05);
2409 sample += QChar(0x0a15);
2410 sample += QChar(0x0a25);
2411 sample += QChar(0x0a35);
2414 sample += QChar(0x0a85);
2415 sample += QChar(0x0a95);
2416 sample += QChar(0x0aa5);
2417 sample += QChar(0x0ab5);
2420 sample += QChar(0x0b06);
2421 sample += QChar(0x0b16);
2422 sample += QChar(0x0b2b);
2423 sample += QChar(0x0b36);
2426 sample += QChar(0x0b89);
2427 sample += QChar(0x0b99);
2428 sample += QChar(0x0ba9);
2429 sample += QChar(0x0bb9);
2432 sample += QChar(0x0c05);
2433 sample += QChar(0x0c15);
2434 sample += QChar(0x0c25);
2435 sample += QChar(0x0c35);
2438 sample += QChar(0x0c85);
2439 sample += QChar(0x0c95);
2440 sample += QChar(0x0ca5);
2441 sample += QChar(0x0cb5);
2444 sample += QChar(0x0d05);
2445 sample += QChar(0x0d15);
2446 sample += QChar(0x0d25);
2447 sample += QChar(0x0d35);
2450 sample += QChar(0x0d90);
2451 sample += QChar(0x0da0);
2452 sample += QChar(0x0db0);
2453 sample += QChar(0x0dc0);
2456 sample += QChar(0x0e02);
2457 sample += QChar(0x0e12);
2458 sample += QChar(0x0e22);
2459 sample += QChar(0x0e32);
2462 sample += QChar(0x0e8d);
2463 sample += QChar(0x0e9d);
2464 sample += QChar(0x0ead);
2465 sample += QChar(0x0ebd);
2468 sample += QChar(0x0f00);
2469 sample += QChar(0x0f01);
2470 sample += QChar(0x0f02);
2471 sample += QChar(0x0f03);
2474 sample += QChar(0x1000);
2475 sample += QChar(0x1001);
2476 sample += QChar(0x1002);
2477 sample += QChar(0x1003);
2480 sample += QChar(0x10a0);
2481 sample += QChar(0x10b0);
2482 sample += QChar(0x10c0);
2483 sample += QChar(0x10d0);
2486 sample += QChar(0x1780);
2487 sample += QChar(0x1790);
2488 sample += QChar(0x17b0);
2489 sample += QChar(0x17c0);
2491 case SimplifiedChinese:
2492 sample += QChar(0x4e2d);
2493 sample += QChar(0x6587);
2494 sample += QChar(0x8303);
2495 sample += QChar(0x4f8b);
2497 case TraditionalChinese:
2498 sample += QChar(0x4e2d);
2499 sample += QChar(0x6587);
2500 sample += QChar(0x7bc4);
2501 sample += QChar(0x4f8b);
2504 sample += QChar(0x30b5);
2505 sample += QChar(0x30f3);
2506 sample += QChar(0x30d7);
2507 sample += QChar(0x30eb);
2508 sample += QChar(0x3067);
2509 sample += QChar(0x3059);
2512 sample += QChar(0xac00);
2513 sample += QChar(0xac11);
2514 sample += QChar(0xac1a);
2515 sample += QChar(0xac2f);
2519 static const char vietnameseUtf8[] = {
2520 char(0xef), char(0xbb), char(0xbf), char(0xe1), char(0xbb), char(0x97),
2521 char(0xe1), char(0xbb), char(0x99),
2522 char(0xe1), char(0xbb), char(0x91),
2523 char(0xe1), char(0xbb), char(0x93),
2525 sample += QString::fromUtf8(vietnameseUtf8, sizeof(vietnameseUtf8));
2529 sample += QChar(0x1681);
2530 sample += QChar(0x1682);
2531 sample += QChar(0x1683);
2532 sample += QChar(0x1684);
2535 sample += QChar(0x16a0);
2536 sample += QChar(0x16a1);
2537 sample += QChar(0x16a2);
2538 sample += QChar(0x16a3);
2541 sample += QChar(0x7ca);
2542 sample += QChar(0x7cb);
2543 sample += QChar(0x7cc);
2544 sample += QChar(0x7cd);
2553 void QFontDatabase::parseFontName(const QString &name, QString &foundry, QString &family)
2555 QT_PREPEND_NAMESPACE(parseFontName)(name, foundry, family);
2558 void QFontDatabase::createDatabase()
2561 // used from qfontengine_ft.cpp
2562 Q_GUI_EXPORT QByteArray qt_fontdata_from_index(int index)
2564 QMutexLocker locker(fontDatabaseMutex());
2565 return privateDb()->applicationFonts.value(index).data;
2568 int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &fileName)
2570 QFontDatabasePrivate::ApplicationFont font;
2571 font.data = fontData;
2572 font.fileName = fileName;
2575 for (i = 0; i < applicationFonts.count(); ++i)
2576 if (applicationFonts.at(i).families.isEmpty())
2578 if (i >= applicationFonts.count()) {
2579 applicationFonts.append(ApplicationFont());
2580 i = applicationFonts.count() - 1;
2583 if (font.fileName.isEmpty() && !fontData.isEmpty())
2584 font.fileName = QString::fromLatin1(":qmemoryfonts/") + QString::number(i);
2586 registerFont(&font);
2587 if (font.families.isEmpty())
2590 applicationFonts[i] = font;
2596 bool QFontDatabasePrivate::isApplicationFont(const QString &fileName)
2598 for (int i = 0; i < applicationFonts.count(); ++i)
2599 if (applicationFonts.at(i).fileName == fileName)
2607 Loads the font from the file specified by \a fileName and makes it available to
2608 the application. An ID is returned that can be used to remove the font again
2609 with removeApplicationFont() or to retrieve the list of family names contained
2612 The function returns -1 if the font could not be loaded.
2614 Currently only TrueType fonts, TrueType font collections, and OpenType fonts are
2617 \note Adding application fonts on Unix/X11 platforms without fontconfig is
2618 currently not supported.
2620 \note On Symbian, the font family names get truncated to a length of 20 characters.
2622 \sa addApplicationFontFromData(), applicationFontFamilies(), removeApplicationFont()
2624 int QFontDatabase::addApplicationFont(const QString &fileName)
2628 if (!(f.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) {
2629 if (!f.open(QIODevice::ReadOnly))
2633 QMutexLocker locker(fontDatabaseMutex());
2634 return privateDb()->addAppFont(data, fileName);
2640 Loads the font from binary data specified by \a fontData and makes it available to
2641 the application. An ID is returned that can be used to remove the font again
2642 with removeApplicationFont() or to retrieve the list of family names contained
2645 The function returns -1 if the font could not be loaded.
2647 Currently only TrueType fonts and TrueType font collections are supported.
2649 \bold{Note:} Adding application fonts on Unix/X11 platforms without fontconfig is
2650 currently not supported.
2652 \note On Symbian, the font family names get truncated to a length of 20 characters.
2654 \sa addApplicationFont(), applicationFontFamilies(), removeApplicationFont()
2656 int QFontDatabase::addApplicationFontFromData(const QByteArray &fontData)
2658 QMutexLocker locker(fontDatabaseMutex());
2659 return privateDb()->addAppFont(fontData, QString() /* fileName */);
2665 Returns a list of font families for the given application font identified by
2668 \sa addApplicationFont(), addApplicationFontFromData()
2670 QStringList QFontDatabase::applicationFontFamilies(int id)
2672 QMutexLocker locker(fontDatabaseMutex());
2673 return privateDb()->applicationFonts.value(id).families;
2677 \fn bool QFontDatabase::removeApplicationFont(int id)
2680 Removes the previously loaded application font identified by \a
2681 id. Returns true if unloading of the font succeeded; otherwise
2684 \sa removeAllApplicationFonts(), addApplicationFont(),
2685 addApplicationFontFromData()
2689 \fn bool QFontDatabase::removeAllApplicationFonts()
2692 Removes all application-local fonts previously added using addApplicationFont()
2693 and addApplicationFontFromData().
2695 Returns true if unloading of the fonts succeeded; otherwise
2698 \sa removeApplicationFont(), addApplicationFont(), addApplicationFontFromData()
2702 \fn bool QFontDatabase::supportsThreadedFontRendering()
2705 Returns true if font rendering is supported outside the GUI
2706 thread, false otherwise. In other words, a return value of false
2707 means that all QPainter::drawText() calls outside the GUI thread
2708 will not produce readable output.
2710 \sa {Thread-Support in Qt Modules#Painting In Threads}{Painting In Threads}