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 "qguiapplication.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/qguiapplication_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(QCoreApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0)
107 return QFont::Normal;
108 if (s == QLatin1String("bold")
109 || s.compare(QCoreApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0)
111 if (s == QLatin1String("demibold") || s == QLatin1String("demi bold")
112 || s.compare(QCoreApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0)
113 return QFont::DemiBold;
114 if (s == QLatin1String("black")
115 || s.compare(QCoreApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
117 if (s == QLatin1String("light"))
120 if (s.contains(QLatin1String("bold"))
121 || s.contains(QCoreApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) {
122 if (s.contains(QLatin1String("demi"))
123 || s.compare(QCoreApplication::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(QCoreApplication::translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0)
130 return (int) QFont::Light;
132 if (s.contains(QLatin1String("black"))
133 || s.compare(QCoreApplication::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), weight(o.weight), stretch(o.stretch) { }
223 signed int weight : 8;
224 signed int stretch : 12;
226 bool operator==(const Key & other) {
227 return (style == other.style && weight == other.weight &&
228 (stretch == 0 || other.stretch == 0 || stretch == other.stretch));
230 bool operator!=(const Key &other) {
231 return !operator==(other);
233 bool operator <(const Key &o) {
234 int x = (style << 12) + (weight << 14) + stretch;
235 int y = (o.style << 12) + (o.weight << 14) + o.stretch;
240 QtFontStyle(const Key &k)
241 : key(k), bitmapScalable(false), smoothScalable(false),
242 count(0), pixelSizes(0)
244 #if defined(Q_WS_X11)
245 weightName = setwidthName = 0;
251 delete [] weightName;
252 delete [] setwidthName;
254 #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
256 // bitfield count-- in while condition does not work correctly in mwccsym2
259 free(pixelSizes[count].encodings);
261 #if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
262 pixelSizes[count].fileName.~QByteArray();
264 #if defined (Q_WS_QPA)
265 QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
266 if (integration) { //on shut down there will be some that we don't release.
267 integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
276 bool bitmapScalable : 1;
277 bool smoothScalable : 1;
278 signed int count : 30;
279 QtFontSize *pixelSizes;
283 const char *weightName;
284 const char *setwidthName;
286 #if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
290 QtFontSize *pixelSize(unsigned short size, bool = false);
293 QtFontStyle::Key::Key(const QString &styleString)
294 : style(QFont::StyleNormal), weight(QFont::Normal), stretch(0)
296 weight = getFontWeight(styleString);
298 if (styleString.contains(QLatin1String("Italic"))
299 || styleString.contains(QCoreApplication::translate("QFontDatabase", "Italic")))
300 style = QFont::StyleItalic;
301 else if (styleString.contains(QLatin1String("Oblique"))
302 || styleString.contains(QCoreApplication::translate("QFontDatabase", "Oblique")))
303 style = QFont::StyleOblique;
306 QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add)
308 for (int i = 0; i < count; i++) {
309 if (pixelSizes[i].pixelSize == size)
310 return pixelSizes + i;
316 // Most style have only one font size, we avoid waisting memory
317 QtFontSize *newPixelSizes = (QtFontSize *)malloc(sizeof(QtFontSize));
318 Q_CHECK_PTR(newPixelSizes);
319 pixelSizes = newPixelSizes;
320 } else if (!(count % 8) || count == 1) {
321 QtFontSize *newPixelSizes = (QtFontSize *)
323 (((count+8) >> 3) << 3) * sizeof(QtFontSize));
324 Q_CHECK_PTR(newPixelSizes);
325 pixelSizes = newPixelSizes;
327 pixelSizes[count].pixelSize = size;
329 pixelSizes[count].count = 0;
330 pixelSizes[count].encodings = 0;
332 #if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
333 new (&pixelSizes[count].fileName) QByteArray;
334 pixelSizes[count].fileIndex = 0;
336 #if defined(Q_WS_QPA)
337 pixelSizes[count].handle = 0;
339 return pixelSizes + (count++);
344 QtFontFoundry(const QString &n) : name(n), count(0), styles(0) {}
347 delete styles[count];
354 QtFontStyle **styles;
355 QtFontStyle *style(const QtFontStyle::Key &, const QString & = QString(), bool = false);
358 QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, const QString &styleName, bool create)
362 // if styleName for searching first if possible
363 if (!styleName.isEmpty()) {
364 for (; pos < count; pos++) {
365 if (styles[pos]->styleName == styleName)
373 if (styles[pos]->key == key)
375 if (styles[pos]->key < key)
379 pos = (high + low) / 2;
386 // qDebug("adding key (weight=%d, style=%d, oblique=%d stretch=%d) at %d", key.weight, key.style, key.oblique, key.stretch, pos);
388 QtFontStyle **newStyles = (QtFontStyle **)
389 realloc(styles, (((count+8) >> 3) << 3) * sizeof(QtFontStyle *));
390 Q_CHECK_PTR(newStyles);
394 QtFontStyle *style = new QtFontStyle(key);
395 style->styleName = styleName;
396 memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *));
405 enum WritingSystemStatus {
410 Unsupported = UnsupportedFT | UnsupportedXLFD
413 QtFontFamily(const QString &n)
416 fixedPitch(true), ftWritingSystemCheck(false),
417 xlfdLoaded(false), synthetic(false), symbol_checked(false),
422 writingSystemCheck(false),
425 #if !defined(QWS) && defined(Q_OS_MAC)
426 fixedPitchComputed(false),
428 name(n), count(0), foundries(0)
429 #if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
430 , bogusWritingSystems(false)
432 #if defined(Q_WS_QPA)
433 , askedForFallback(false)
436 memset(writingSystems, 0, sizeof(writingSystems));
440 delete foundries[count];
446 bool ftWritingSystemCheck : 1;
451 bool writingSystemCheck : 1;
454 #if !defined(QWS) && defined(Q_OS_MAC)
455 bool fixedPitchComputed : 1;
458 bool symbol_checked : 1;
462 #if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
463 QByteArray fontFilename;
467 QString english_name;
470 QtFontFoundry **foundries;
472 #if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
473 bool bogusWritingSystems;
474 QStringList fallbackFamilies;
476 #if defined (Q_WS_QPA)
477 bool askedForFallback;
479 unsigned char writingSystems[QFontDatabase::WritingSystemsCount];
481 QtFontFoundry *foundry(const QString &f, bool = false);
484 #if !defined(QWS) && defined(Q_OS_MAC)
485 inline static void qt_mac_get_fixed_pitch(QtFontFamily *f)
487 if(f && !f->fixedPitchComputed) {
488 QFontMetrics fm(f->name);
489 f->fixedPitch = fm.width(QLatin1Char('i')) == fm.width(QLatin1Char('m'));
490 f->fixedPitchComputed = true;
496 QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create)
498 if (f.isNull() && count == 1)
501 for (int i = 0; i < count; i++) {
502 if (foundries[i]->name.compare(f, Qt::CaseInsensitive) == 0)
509 QtFontFoundry **newFoundries = (QtFontFoundry **)
511 (((count+8) >> 3) << 3) * sizeof(QtFontFoundry *));
512 Q_CHECK_PTR(newFoundries);
513 foundries = newFoundries;
516 foundries[count] = new QtFontFoundry(f);
517 return foundries[count++];
520 // ### copied to tools/makeqpf/qpf2.cpp
522 // see the Unicode subset bitfields in the MSDN docs
523 static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
574 // SimplifiedChinese,
576 // TraditionalChinese,
583 { 0, 127 }, // same as latin1
594 #define SimplifiedChineseCsbBit 18
595 #define TraditionalChineseCsbBit 20
596 #define JapaneseCsbBit 17
597 #define KoreanCsbBit 21
599 QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_truetype_bits(quint32 unicodeRange[4], quint32 codePageRange[2])
601 QList<QFontDatabase::WritingSystem> writingSystems;
602 bool hasScript = false;
605 for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
606 int bit = requiredUnicodeBits[i][0];
608 int flag = 1 << (bit&31);
609 if (bit != 126 && unicodeRange[index] & flag) {
610 bit = requiredUnicodeBits[i][1];
613 flag = 1 << (bit&31);
614 if (bit == 127 || unicodeRange[index] & flag) {
615 writingSystems.append(QFontDatabase::WritingSystem(i));
617 // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
621 if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
622 writingSystems.append(QFontDatabase::SimplifiedChinese);
624 //qDebug("font %s supports Simplified Chinese", familyName.latin1());
626 if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
627 writingSystems.append(QFontDatabase::TraditionalChinese);
629 //qDebug("font %s supports Traditional Chinese", familyName.latin1());
631 if(codePageRange[0] & (1 << JapaneseCsbBit)) {
632 writingSystems.append(QFontDatabase::Japanese);
634 //qDebug("font %s supports Japanese", familyName.latin1());
636 if(codePageRange[0] & (1 << KoreanCsbBit)) {
637 writingSystems.append(QFontDatabase::Korean);
639 //qDebug("font %s supports Korean", familyName.latin1());
642 writingSystems.append(QFontDatabase::Symbol);
644 return writingSystems;
647 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
648 // class with virtual destructor, derived in qfontdatabase_s60.cpp
649 class QSymbianFontDatabaseExtras
652 virtual ~QSymbianFontDatabaseExtras() {}
656 class QFontDatabasePrivate
659 QFontDatabasePrivate()
660 : count(0), families(0), reregisterAppFonts(false)
661 #if defined(Q_WS_QWS)
664 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
667 #if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
668 , directWriteFactory(0)
669 , directWriteGdiInterop(0)
673 ~QFontDatabasePrivate() {
675 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
677 delete symbianExtras;
679 #if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
680 if (directWriteGdiInterop)
681 directWriteGdiInterop->Release();
682 if (directWriteFactory != 0)
683 directWriteFactory->Release();
686 QtFontFamily *family(const QString &f, bool = false);
689 delete families[count];
693 // don't clear the memory fonts!
697 #if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
700 QtFontFamily **families;
702 #if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
703 IDWriteFactory *directWriteFactory;
704 IDWriteGdiInterop *directWriteGdiInterop;
708 struct ApplicationFont {
711 #if defined(Q_OS_WIN)
714 QVector<FONTSIGNATURE> signatures;
715 #elif defined(Q_WS_MAC)
716 ATSFontContainerRef handle;
717 #elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
718 QString temporaryFileName;
719 TInt screenDeviceFontFileId;
720 TUid fontStoreFontFileUid;
722 QStringList families;
724 QVector<ApplicationFont> applicationFonts;
725 int addAppFont(const QByteArray &fontData, const QString &fileName);
726 bool reregisterAppFonts;
727 bool isApplicationFont(const QString &fileName);
731 #if defined(Q_WS_QWS)
732 bool loadFromCache(const QString &fontPath);
733 void addQPF2File(const QByteArray &file);
735 #if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
736 void addFont(const QString &familyname, const char *foundryname, int weight,
737 bool italic, int pixelSize, const QByteArray &file, int fileIndex,
739 const QList<QFontDatabase::WritingSystem> &writingSystems = QList<QFontDatabase::WritingSystem>());
740 #ifndef QT_NO_FREETYPE
741 QStringList addTTFile(const QByteArray &file, const QByteArray &fontData = QByteArray());
742 #endif // QT_NO_FREETYPE
744 #if defined(Q_WS_QWS)
746 #elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
747 QSymbianFontDatabaseExtras *symbianExtras;
749 #if defined(Q_WS_QWS) || defined(Q_WS_QPA)
750 QStringList fallbackFamilies;
754 void QFontDatabasePrivate::invalidate()
756 QFontCache::instance()->clear();
758 emit static_cast<QGuiApplication *>(QCoreApplication::instance())->fontDatabaseChanged();
761 QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create)
768 while ((res = families[pos]->name.compare(f, Qt::CaseInsensitive)) && pos != low) {
773 pos = (high + low) / 2;
776 return families[pos];
784 // qDebug("adding family %s at %d total=%d", f.latin1(), pos, count);
786 QtFontFamily **newFamilies = (QtFontFamily **)
788 (((count+8) >> 3) << 3) * sizeof(QtFontFamily *));
789 Q_CHECK_PTR(newFamilies);
790 families = newFamilies;
793 QtFontFamily *family = new QtFontFamily(f);
794 memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *));
795 families[pos] = family;
797 return families[pos];
800 #if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
801 void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundryname, int weight, bool italic, int pixelSize,
802 const QByteArray &file, int fileIndex, bool antialiased,
803 const QList<QFontDatabase::WritingSystem> &writingSystems)
805 // qDebug() << "Adding font" << familyname << weight << italic << pixelSize << file << fileIndex << antialiased;
806 QtFontStyle::Key styleKey;
807 styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal;
808 styleKey.weight = weight;
809 styleKey.stretch = 100;
810 QtFontFamily *f = family(familyname, true);
812 if (writingSystems.isEmpty()) {
813 for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) {
814 f->writingSystems[ws] = QtFontFamily::Supported;
816 f->bogusWritingSystems = true;
818 for (int i = 0; i < writingSystems.count(); ++i) {
819 f->writingSystems[writingSystems.at(i)] = QtFontFamily::Supported;
823 QtFontFoundry *foundry = f->foundry(QString::fromLatin1(foundryname), true);
824 QtFontStyle *style = foundry->style(styleKey, QString(), true);
825 style->smoothScalable = (pixelSize == 0);
826 style->antialiased = antialiased;
827 QtFontSize *size = style->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true);
828 size->fileName = file;
829 size->fileIndex = fileIndex;
831 #if defined(Q_WS_QWS)
833 *stream << familyname << foundry->name << weight << quint8(italic) << pixelSize
834 << file << fileIndex << quint8(antialiased);
835 *stream << quint8(writingSystems.count());
836 for (int i = 0; i < writingSystems.count(); ++i)
837 *stream << quint8(writingSystems.at(i));
839 #else // ..in case of defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
840 f->fontFilename = file;
841 f->fontFileIndex = fileIndex;
846 #if (defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
847 QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteArray &fontData)
849 QStringList families;
850 extern FT_Library qt_getFreetype();
851 FT_Library library = qt_getFreetype();
858 if (!fontData.isEmpty()) {
859 error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
861 error = FT_New_Face(library, file, index, &face);
863 if (error != FT_Err_Ok) {
864 qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
867 numFaces = face->num_faces;
869 int weight = QFont::Normal;
870 bool italic = face->style_flags & FT_STYLE_FLAG_ITALIC;
872 if (face->style_flags & FT_STYLE_FLAG_BOLD)
873 weight = QFont::Bold;
875 QList<QFontDatabase::WritingSystem> writingSystems;
876 // detect symbol fonts
877 for (int i = 0; i < face->num_charmaps; ++i) {
878 FT_CharMap cm = face->charmaps[i];
879 if (cm->encoding == ft_encoding_adobe_custom
880 || cm->encoding == ft_encoding_symbol) {
881 writingSystems.append(QFontDatabase::Symbol);
885 if (writingSystems.isEmpty()) {
886 TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
888 quint32 unicodeRange[4] = {
889 static_cast<quint32>(os2->ulUnicodeRange1), static_cast<quint32>(os2->ulUnicodeRange2), static_cast<quint32>(os2->ulUnicodeRange3), static_cast<quint32>(os2->ulUnicodeRange4)
891 quint32 codePageRange[2] = {
892 static_cast<quint32>(os2->ulCodePageRange1), static_cast<quint32>(os2->ulCodePageRange2)
895 writingSystems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange);
896 //for (int i = 0; i < writingSystems.count(); ++i)
897 // qDebug() << QFontDatabase::writingSystemName(writingSystems.at(i));
901 QString family = QString::fromAscii(face->family_name);
902 families.append(family);
903 addFont(family, /*foundry*/ "", weight, italic,
904 /*pixelsize*/ 0, file, index, /*antialias*/ true, writingSystems);
908 } while (index < numFaces);
913 static const int scriptForWritingSystem[] = {
914 QUnicodeTables::Common, // Any
915 QUnicodeTables::Latin, // Latin
916 QUnicodeTables::Greek, // Greek
917 QUnicodeTables::Cyrillic, // Cyrillic
918 QUnicodeTables::Armenian, // Armenian
919 QUnicodeTables::Hebrew, // Hebrew
920 QUnicodeTables::Arabic, // Arabic
921 QUnicodeTables::Syriac, // Syriac
922 QUnicodeTables::Thaana, // Thaana
923 QUnicodeTables::Devanagari, // Devanagari
924 QUnicodeTables::Bengali, // Bengali
925 QUnicodeTables::Gurmukhi, // Gurmukhi
926 QUnicodeTables::Gujarati, // Gujarati
927 QUnicodeTables::Oriya, // Oriya
928 QUnicodeTables::Tamil, // Tamil
929 QUnicodeTables::Telugu, // Telugu
930 QUnicodeTables::Kannada, // Kannada
931 QUnicodeTables::Malayalam, // Malayalam
932 QUnicodeTables::Sinhala, // Sinhala
933 QUnicodeTables::Thai, // Thai
934 QUnicodeTables::Lao, // Lao
935 QUnicodeTables::Tibetan, // Tibetan
936 QUnicodeTables::Myanmar, // Myanmar
937 QUnicodeTables::Georgian, // Georgian
938 QUnicodeTables::Khmer, // Khmer
939 QUnicodeTables::Common, // SimplifiedChinese
940 QUnicodeTables::Common, // TraditionalChinese
941 QUnicodeTables::Common, // Japanese
942 QUnicodeTables::Hangul, // Korean
943 QUnicodeTables::Common, // Vietnamese
944 QUnicodeTables::Common, // Yi
945 QUnicodeTables::Common, // Tagalog
946 QUnicodeTables::Common, // Hanunoo
947 QUnicodeTables::Common, // Buhid
948 QUnicodeTables::Common, // Tagbanwa
949 QUnicodeTables::Common, // Limbu
950 QUnicodeTables::Common, // TaiLe
951 QUnicodeTables::Common, // Braille
952 QUnicodeTables::Common, // Symbol
953 QUnicodeTables::Ogham, // Ogham
954 QUnicodeTables::Runic, // Runic
955 QUnicodeTables::Nko // Nko
958 int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem)
960 return scriptForWritingSystem[writingSystem];
964 #if defined Q_WS_QWS || (defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)) || defined(Q_WS_WIN)
965 static inline bool requiresOpenType(int writingSystem)
967 return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
968 || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
970 static inline bool scriptRequiresOpenType(int script)
972 return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
973 || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
981 This makes sense of the font family name:
983 if the family name contains a '[' and a ']', then we take the text
984 between the square brackets as the foundry, and the text before the
985 square brackets as the family (ie. "Arial [Monotype]")
987 static void parseFontName(const QString &name, QString &foundry, QString &family)
989 int i = name.indexOf(QLatin1Char('['));
990 int li = name.lastIndexOf(QLatin1Char(']'));
991 if (i >= 0 && li >= 0 && i < li) {
992 foundry = name.mid(i + 1, li - i - 1);
993 if (i > 0 && name[i - 1] == QLatin1Char(' '))
995 family = name.left(i);
1001 // capitalize the family/foundry names
1003 QChar *s = family.data();
1004 int len = family.length();
1006 if (space) *s = s->toUpper();
1007 space = s->isSpace();
1013 len = foundry.length();
1015 if (space) *s = s->toUpper();
1016 space = s->isSpace();
1024 inline QtFontDesc() : family(0), foundry(0), style(0), size(0), encoding(0), familyIndex(-1) {}
1025 QtFontFamily *family;
1026 QtFontFoundry *foundry;
1029 QtFontEncoding *encoding;
1033 #if !defined(Q_WS_MAC)
1034 static void match(int script, const QFontDef &request,
1035 const QString &family_name, const QString &foundry_name, int force_encoding_id,
1036 QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>(), bool forceXLFD=false);
1038 #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_QPA)
1039 static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef)
1041 fontDef->family = desc.family->name;
1042 if (! desc.foundry->name.isEmpty() && desc.family->count > 1) {
1043 fontDef->family += QString::fromLatin1(" [");
1044 fontDef->family += desc.foundry->name;
1045 fontDef->family += QLatin1Char(']');
1048 if (desc.style->smoothScalable)
1049 fontDef->pixelSize = request.pixelSize;
1050 else if ((desc.style->bitmapScalable && (request.styleStrategy & QFont::PreferMatch)))
1051 fontDef->pixelSize = request.pixelSize;
1053 fontDef->pixelSize = desc.size->pixelSize;
1055 fontDef->styleHint = request.styleHint;
1056 fontDef->styleStrategy = request.styleStrategy;
1058 fontDef->weight = desc.style->key.weight;
1059 fontDef->style = desc.style->key.style;
1060 fontDef->fixedPitch = desc.family->fixedPitch;
1061 fontDef->stretch = desc.style->key.stretch;
1062 fontDef->ignorePitch = false;
1067 #if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) || defined(Q_WS_QPA)
1068 static void getEngineData(const QFontPrivate *d, const QFontCache::Key &key)
1070 // look for the requested font in the engine data cache
1071 d->engineData = QFontCache::instance()->findEngineData(key);
1072 if (!d->engineData) {
1074 d->engineData = new QFontEngineData;
1075 QFontCache::instance()->insertEngineData(key, d->engineData);
1077 d->engineData->ref.ref();
1082 static QStringList familyList(const QFontDef &req)
1084 // list of families to try
1085 QStringList family_list;
1086 if (req.family.isEmpty())
1089 QStringList list = req.family.split(QLatin1Char(','));
1090 for (int i = 0; i < list.size(); ++i) {
1091 QString str = list.at(i).trimmed();
1092 if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
1093 || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
1094 str = str.mid(1, str.length() - 2);
1098 // append the substitute list for each family in family_list
1099 QStringList subs_list;
1100 QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
1101 for (; it != end; ++it)
1102 subs_list += QFont::substitutes(*it);
1103 // qDebug() << "adding substs: " << subs_list;
1105 family_list += subs_list;
1110 Q_GLOBAL_STATIC(QFontDatabasePrivate, privateDb)
1111 Q_GLOBAL_STATIC_WITH_ARGS(QMutex, fontDatabaseMutex, (QMutex::Recursive))
1113 // used in qfontengine_x11.cpp
1114 QMutex *qt_fontdatabase_mutex()
1116 return fontDatabaseMutex();
1119 QT_BEGIN_INCLUDE_NAMESPACE
1120 #if defined(Q_WS_X11)
1121 # include "qfontdatabase_x11.cpp"
1122 #elif defined(Q_WS_MAC)
1123 # include "qfontdatabase_mac.cpp"
1124 #elif defined(Q_WS_WIN)
1125 # include "qfontdatabase_win.cpp"
1126 #elif defined(Q_WS_QWS)
1127 # include "qfontdatabase_qws.cpp"
1128 #elif defined(Q_WS_QPA)
1129 # include "qfontdatabase_qpa.cpp"
1130 #elif defined(Q_OS_SYMBIAN)
1131 # include "qfontdatabase_s60.cpp"
1133 QT_END_INCLUDE_NAMESPACE
1134 #if !defined(Q_WS_X11)
1135 QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
1141 static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey,
1142 const QString &styleName = QString())
1147 for ( int i = 0; i < foundry->count; i++ ) {
1148 QtFontStyle *style = foundry->styles[i];
1150 if (!styleName.isEmpty() && styleName == style->styleName) {
1156 int d = qAbs( styleKey.weight - style->key.weight );
1158 if ( styleKey.stretch != 0 && style->key.stretch != 0 ) {
1159 d += qAbs( styleKey.stretch - style->key.stretch );
1162 if (styleKey.style != style->key.style) {
1163 if (styleKey.style != QFont::StyleNormal && style->key.style != QFont::StyleNormal)
1164 // one is italic, the other oblique
1176 FM_DEBUG( " best style has distance 0x%x", dist );
1177 return foundry->styles[best];
1180 #if defined(Q_WS_X11)
1181 static QtFontEncoding *findEncoding(int script, int styleStrategy,
1182 QtFontSize *size, int force_encoding_id)
1184 QtFontEncoding *encoding = 0;
1186 if (force_encoding_id >= 0) {
1187 encoding = size->encodingID(force_encoding_id);
1189 FM_DEBUG(" required encoding_id not available");
1193 if (styleStrategy & (QFont::OpenGLCompatible | QFont::PreferBitmap)) {
1194 FM_DEBUG(" PreferBitmap and/or OpenGL set, skipping Freetype");
1196 encoding = size->encodingID(-1); // -1 == prefer Freetype
1201 // FT not available, find an XLFD font, trying the default encoding first
1202 encoding = size->encodingID(QFontPrivate::defaultEncodingID);
1204 // does it support the requested script?
1205 bool supportsScript = false;
1206 for (int ws = 1; !supportsScript && ws < QFontDatabase::WritingSystemsCount; ++ws) {
1207 if (scriptForWritingSystem[ws] != script)
1209 supportsScript = writingSystems_for_xlfd_encoding[encoding->encoding][ws];
1211 if (!supportsScript)
1214 // find the first encoding that supports the requested script
1215 for (int ws = 1; !encoding && ws < QFontDatabase::WritingSystemsCount; ++ws) {
1216 if (scriptForWritingSystem[ws] != script)
1218 for (int x = 0; !encoding && x < size->count; ++x) {
1219 const int enc = size->encodings[x].encoding;
1220 if (writingSystems_for_xlfd_encoding[enc][ws])
1221 encoding = size->encodings + x;
1229 #if !defined(Q_WS_MAC)
1231 unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
1232 const QtFontFamily *family, const QString &foundry_name,
1233 QtFontStyle::Key styleKey, int pixelSize, char pitch,
1234 QtFontDesc *desc, int force_encoding_id)
1236 Q_UNUSED(force_encoding_id);
1246 FM_DEBUG(" REMARK: looking for best foundry for family '%s' [%d]", family->name.toLatin1().constData(), family->count);
1248 for (int x = 0; x < family->count; ++x) {
1249 QtFontFoundry *foundry = family->foundries[x];
1250 if (!foundry_name.isEmpty() && foundry->name.compare(foundry_name, Qt::CaseInsensitive) != 0)
1253 FM_DEBUG(" looking for matching style in foundry '%s' %d",
1254 foundry->name.isEmpty() ? "-- none --" : foundry->name.toLatin1().constData(), foundry->count);
1256 QtFontStyle *style = bestStyle(foundry, styleKey);
1258 if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) {
1259 FM_DEBUG(" ForceOutline set, but not smoothly scalable");
1264 QtFontSize *size = 0;
1266 // 1. see if we have an exact matching size
1267 if (!(styleStrategy & QFont::ForceOutline)) {
1268 size = style->pixelSize(pixelSize);
1270 FM_DEBUG(" found exact size match (%d pixels)", size->pixelSize);
1271 px = size->pixelSize;
1275 // 2. see if we have a smoothly scalable font
1276 if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
1277 size = style->pixelSize(SMOOTH_SCALABLE);
1279 FM_DEBUG(" found smoothly scalable font (%d pixels)", pixelSize);
1284 // 3. see if we have a bitmap scalable font
1285 if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
1286 size = style->pixelSize(0);
1288 FM_DEBUG(" found bitmap scalable font (%d pixels)", pixelSize);
1294 QtFontEncoding *encoding = 0;
1297 // 4. find closest size match
1299 unsigned int distance = ~0u;
1300 for (int x = 0; x < style->count; ++x) {
1303 findEncoding(script, styleStrategy, style->pixelSizes + x, force_encoding_id);
1305 FM_DEBUG(" size %3d does not support the script we want",
1306 style->pixelSizes[x].pixelSize);
1312 if (style->pixelSizes[x].pixelSize < pixelSize) {
1313 // penalize sizes that are smaller than the
1314 // requested size, due to truncation from floating
1315 // point to integer conversions
1316 d = pixelSize - style->pixelSizes[x].pixelSize + 1;
1318 d = style->pixelSizes[x].pixelSize - pixelSize;
1323 size = style->pixelSizes + x;
1324 FM_DEBUG(" best size so far: %3d (%d)", size->pixelSize, pixelSize);
1329 FM_DEBUG(" no size supports the script we want");
1333 if (style->bitmapScalable && ! (styleStrategy & QFont::PreferQuality) &&
1334 (distance * 10 / pixelSize) >= 2) {
1335 // the closest size is not close enough, go ahead and
1336 // use a bitmap scaled font
1337 size = style->pixelSize(0);
1340 px = size->pixelSize;
1346 encoding = findEncoding(script, styleStrategy, size, force_encoding_id);
1347 if (!encoding) size = 0;
1350 FM_DEBUG(" foundry doesn't support the script we want");
1355 unsigned int this_score = 0x0000;
1357 PitchMismatch = 0x4000,
1358 StyleMismatch = 0x2000,
1359 BitmapScaledPenalty = 0x1000,
1360 EncodingMismatch = 0x0002,
1361 XLFDPenalty = 0x0001
1364 if (encoding->encoding != -1) {
1365 this_score += XLFDPenalty;
1366 if (encoding->encoding != QFontPrivate::defaultEncodingID)
1367 this_score += EncodingMismatch;
1370 if (!(pitch == 'm' && encoding->pitch == 'c') && pitch != encoding->pitch)
1371 this_score += PitchMismatch;
1375 #if !defined(QWS) && defined(Q_OS_MAC)
1376 qt_mac_get_fixed_pitch(const_cast<QtFontFamily*>(family));
1378 if ((pitch == 'm' && !family->fixedPitch)
1379 || (pitch == 'p' && family->fixedPitch))
1380 this_score += PitchMismatch;
1383 if (styleKey != style->key)
1384 this_score += StyleMismatch;
1385 if (!style->smoothScalable && px != size->pixelSize) // bitmap scaled
1386 this_score += BitmapScaledPenalty;
1387 if (px != pixelSize) // close, but not exact, size match
1388 this_score += qAbs(px - pixelSize);
1390 if (this_score < score) {
1391 FM_DEBUG(" found a match: score %x best score so far %x",
1395 desc->foundry = foundry;
1396 desc->style = style;
1399 desc->encoding = encoding;
1402 FM_DEBUG(" score %x no better than best %x", this_score, score);
1410 #if !defined(Q_WS_MAC)
1414 Tries to find the best match for a given request and family/foundry
1416 static void match(int script, const QFontDef &request,
1417 const QString &family_name, const QString &foundry_name, int force_encoding_id,
1418 QtFontDesc *desc, const QList<int> &blacklistedFamilies, bool forceXLFD)
1420 Q_UNUSED(force_encoding_id);
1422 QtFontStyle::Key styleKey;
1423 styleKey.style = request.style;
1424 styleKey.weight = request.weight;
1425 styleKey.stretch = request.stretch;
1426 char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';
1429 FM_DEBUG("QFontDatabase::match\n"
1431 " family: %s [%s], script: %d\n"
1432 " weight: %d, style: %d\n"
1436 family_name.isEmpty() ? "-- first in script --" : family_name.toLatin1().constData(),
1437 foundry_name.isEmpty() ? "-- any --" : foundry_name.toLatin1().constData(),
1438 script, request.weight, request.style, request.stretch, request.pixelSize, pitch);
1439 #if defined(FONT_MATCH_DEBUG) && defined(Q_WS_X11)
1440 if (force_encoding_id >= 0) {
1441 FM_DEBUG(" required encoding: %d", force_encoding_id);
1450 desc->familyIndex = -1;
1452 unsigned int score = ~0u;
1455 load(family_name, script, forceXLFD);
1457 Q_UNUSED(forceXLFD);
1458 load(family_name, script);
1461 QFontDatabasePrivate *db = privateDb();
1462 for (int x = 0; x < db->count; ++x) {
1463 if (blacklistedFamilies.contains(x))
1466 test.family = db->families[x];
1467 test.familyIndex = x;
1469 if (!family_name.isEmpty()
1470 && test.family->name.compare(family_name, Qt::CaseInsensitive) != 0
1472 && test.family->english_name.compare(family_name, Qt::CaseInsensitive) != 0
1477 if (family_name.isEmpty())
1478 load(test.family->name, script);
1480 uint score_adjust = 0;
1482 bool supported = (script == QUnicodeTables::Common);
1483 for (int ws = 1; !supported && ws < QFontDatabase::WritingSystemsCount; ++ws) {
1484 if (scriptForWritingSystem[ws] != script)
1486 if (test.family->writingSystems[ws] & QtFontFamily::Supported)
1490 // family not supported in the script we want
1494 // as we know the script is supported, we can be sure
1495 // to find a matching font here.
1496 unsigned int newscore =
1497 bestFoundry(script, score, request.styleStrategy,
1498 test.family, foundry_name, styleKey, request.pixelSize, pitch,
1499 &test, force_encoding_id);
1500 if (test.foundry == 0) {
1501 // the specific foundry was not found, so look for
1502 // any foundry matching our requirements
1503 newscore = bestFoundry(script, score, request.styleStrategy, test.family,
1504 QString(), styleKey, request.pixelSize,
1505 pitch, &test, force_encoding_id);
1507 newscore += score_adjust;
1509 if (newscore < score) {
1513 if (newscore < 10) // xlfd instead of FT... just accept it
1519 static QString styleStringHelper(int weight, QFont::Style style)
1522 if (weight >= QFont::Black)
1523 result = QCoreApplication::translate("QFontDatabase", "Black");
1524 else if (weight >= QFont::Bold)
1525 result = QCoreApplication::translate("QFontDatabase", "Bold");
1526 else if (weight >= QFont::DemiBold)
1527 result = QCoreApplication::translate("QFontDatabase", "Demi Bold");
1528 else if (weight < QFont::Normal)
1529 result = QCoreApplication::translate("QFontDatabase", "Light");
1531 if (style == QFont::StyleItalic)
1532 result += QLatin1Char(' ') + QCoreApplication::translate("QFontDatabase", "Italic");
1533 else if (style == QFont::StyleOblique)
1534 result += QLatin1Char(' ') + QCoreApplication::translate("QFontDatabase", "Oblique");
1536 if (result.isEmpty())
1537 result = QCoreApplication::translate("QFontDatabase", "Normal");
1539 return result.simplified();
1543 Returns a string that describes the style of the \a font. For
1544 example, "Bold Italic", "Bold", "Italic" or "Normal". An empty
1545 string may be returned.
1547 QString QFontDatabase::styleString(const QFont &font)
1549 return font.styleName().isEmpty() ? styleStringHelper(font.weight(), font.style())
1554 Returns a string that describes the style of the \a fontInfo. For
1555 example, "Bold Italic", "Bold", "Italic" or "Normal". An empty
1556 string may be returned.
1558 QString QFontDatabase::styleString(const QFontInfo &fontInfo)
1560 return fontInfo.styleName().isEmpty() ? styleStringHelper(fontInfo.weight(), fontInfo.style())
1561 : fontInfo.styleName();
1566 \class QFontDatabase
1569 \brief The QFontDatabase class provides information about the fonts available in the underlying window system.
1573 The most common uses of this class are to query the database for
1574 the list of font families() and for the pointSizes() and styles()
1575 that are available for each family. An alternative to pointSizes()
1576 is smoothSizes() which returns the sizes at which a given family
1577 and style will look attractive.
1579 If the font family is available from two or more foundries the
1580 foundry name is included in the family name; for example:
1581 "Helvetica [Adobe]" and "Helvetica [Cronyx]". When you specify a
1582 family, you can either use the old hyphenated "foundry-family"
1583 format or the bracketed "family [foundry]" format; for example:
1584 "Cronyx-Helvetica" or "Helvetica [Cronyx]". If the family has a
1585 foundry it is always returned using the bracketed format, as is
1586 the case with the value returned by families().
1588 The font() function returns a QFont given a family, style and
1591 A family and style combination can be checked to see if it is
1592 italic() or bold(), and to retrieve its weight(). Similarly we can
1593 call isBitmapScalable(), isSmoothlyScalable(), isScalable() and
1596 Use the styleString() to obtain a text version of a style.
1598 The QFontDatabase class also supports some static functions, for
1599 example, standardSizes(). You can retrieve the description of a
1600 writing system using writingSystemName(), and a sample of
1601 characters in a writing system with writingSystemSample().
1605 \snippet doc/src/snippets/qfontdatabase/main.cpp 0
1606 \snippet doc/src/snippets/qfontdatabase/main.cpp 1
1608 This example gets the list of font families, the list of
1609 styles for each family, and the point sizes that are available for
1610 each combination of family and style, displaying this information
1613 \sa QFont, QFontInfo, QFontMetrics, QFontComboBox, {Character Map Example}
1617 Creates a font database object.
1619 QFontDatabase::QFontDatabase()
1621 QMutexLocker locker(fontDatabaseMutex());
1627 \enum QFontDatabase::WritingSystem
1654 \value SimplifiedChinese
1655 \value TraditionalChinese
1660 \value Other (the same as Symbol)
1665 \omitvalue WritingSystemsCount
1669 Returns a sorted list of the available writing systems. This is
1670 list generated from information about all installed fonts on the
1675 QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems() const
1677 QMutexLocker locker(fontDatabaseMutex());
1679 QT_PREPEND_NAMESPACE(load)();
1684 QList<WritingSystem> list;
1685 for (int i = 0; i < d->count; ++i) {
1686 QtFontFamily *family = d->families[i];
1687 if (family->count == 0)
1689 for (int x = Latin; x < WritingSystemsCount; ++x) {
1690 const WritingSystem writingSystem = WritingSystem(x);
1691 if (!(family->writingSystems[writingSystem] & QtFontFamily::Supported))
1693 if (!list.contains(writingSystem))
1694 list.append(writingSystem);
1703 Returns a sorted list of the writing systems supported by a given
1708 QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems(const QString &family) const
1710 QString familyName, foundryName;
1711 parseFontName(family, foundryName, familyName);
1713 QMutexLocker locker(fontDatabaseMutex());
1715 QT_PREPEND_NAMESPACE(load)();
1717 checkSymbolFonts(familyName);
1720 QList<WritingSystem> list;
1721 QtFontFamily *f = d->family(familyName);
1722 if (!f || f->count == 0)
1725 for (int x = Latin; x < WritingSystemsCount; ++x) {
1726 const WritingSystem writingSystem = WritingSystem(x);
1727 if (f->writingSystems[writingSystem] & QtFontFamily::Supported)
1728 list.append(writingSystem);
1735 Returns a sorted list of the available font families which support
1736 the \a writingSystem.
1738 If a family exists in several foundries, the returned name for
1739 that font is in the form "family [foundry]". Examples: "Times
1740 [Adobe]", "Times [Cronyx]", "Palatino".
1742 \sa writingSystems()
1744 QStringList QFontDatabase::families(WritingSystem writingSystem) const
1746 QMutexLocker locker(fontDatabaseMutex());
1748 QT_PREPEND_NAMESPACE(load)();
1750 if (writingSystem != Any)
1755 for (int i = 0; i < d->count; i++) {
1756 QtFontFamily *f = d->families[i];
1759 if (writingSystem != Any && (f->writingSystems[writingSystem] != QtFontFamily::Supported))
1761 if (f->count == 1) {
1762 flist.append(f->name);
1764 for (int j = 0; j < f->count; j++) {
1765 QString str = f->name;
1766 QString foundry = f->foundries[j]->name;
1767 if (!foundry.isEmpty()) {
1768 str += QLatin1String(" [");
1770 str += QLatin1Char(']');
1780 Returns a list of the styles available for the font family \a
1781 family. Some example styles: "Light", "Light Italic", "Bold",
1782 "Oblique", "Demi". The list may be empty.
1786 QStringList QFontDatabase::styles(const QString &family) const
1788 QString familyName, foundryName;
1789 parseFontName(family, foundryName, familyName);
1791 QMutexLocker locker(fontDatabaseMutex());
1793 QT_PREPEND_NAMESPACE(load)(familyName);
1796 QtFontFamily *f = d->family(familyName);
1800 QtFontFoundry allStyles(foundryName);
1801 for (int j = 0; j < f->count; j++) {
1802 QtFontFoundry *foundry = f->foundries[j];
1803 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1804 for (int k = 0; k < foundry->count; k++) {
1805 QtFontStyle::Key ke(foundry->styles[k]->key);
1807 allStyles.style(ke, foundry->styles[k]->styleName, true);
1812 for (int i = 0; i < allStyles.count; i++) {
1813 l.append(allStyles.styles[i]->styleName.isEmpty() ?
1814 styleStringHelper(allStyles.styles[i]->key.weight,
1815 (QFont::Style)allStyles.styles[i]->key.style) :
1816 allStyles.styles[i]->styleName);
1822 Returns true if the font that has family \a family and style \a
1823 style is fixed pitch; otherwise returns false.
1826 bool QFontDatabase::isFixedPitch(const QString &family,
1827 const QString &style) const
1831 QString familyName, foundryName;
1832 parseFontName(family, foundryName, familyName);
1834 QMutexLocker locker(fontDatabaseMutex());
1836 QT_PREPEND_NAMESPACE(load)(familyName);
1838 QtFontFamily *f = d->family(familyName);
1839 #if !defined(QWS) && defined(Q_OS_MAC)
1840 qt_mac_get_fixed_pitch(f);
1842 return (f && f->fixedPitch);
1846 Returns true if the font that has family \a family and style \a
1847 style is a scalable bitmap font; otherwise returns false. Scaling
1848 a bitmap font usually produces an unattractive hardly readable
1849 result, because the pixels of the font are scaled. If you need to
1850 scale a bitmap font it is better to scale it to one of the fixed
1851 sizes returned by smoothSizes().
1853 \sa isScalable(), isSmoothlyScalable()
1855 bool QFontDatabase::isBitmapScalable(const QString &family,
1856 const QString &style) const
1858 bool bitmapScalable = false;
1859 QString familyName, foundryName;
1860 parseFontName(family, foundryName, familyName);
1862 QMutexLocker locker(fontDatabaseMutex());
1864 QT_PREPEND_NAMESPACE(load)(familyName);
1866 QtFontStyle::Key styleKey(style);
1868 QtFontFamily *f = d->family(familyName);
1869 if (!f) return bitmapScalable;
1871 for (int j = 0; j < f->count; j++) {
1872 QtFontFoundry *foundry = f->foundries[j];
1873 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1874 for (int k = 0; k < foundry->count; k++)
1875 if ((style.isEmpty() ||
1876 foundry->styles[k]->styleName == style ||
1877 foundry->styles[k]->key == styleKey)
1878 && foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
1879 bitmapScalable = true;
1885 return bitmapScalable;
1890 Returns true if the font that has family \a family and style \a
1891 style is smoothly scalable; otherwise returns false. If this
1892 function returns true, it's safe to scale this font to any size,
1893 and the result will always look attractive.
1895 \sa isScalable(), isBitmapScalable()
1897 bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &style) const
1899 bool smoothScalable = false;
1900 QString familyName, foundryName;
1901 parseFontName(family, foundryName, familyName);
1903 QMutexLocker locker(fontDatabaseMutex());
1905 QT_PREPEND_NAMESPACE(load)(familyName);
1907 QtFontStyle::Key styleKey(style);
1909 QtFontFamily *f = d->family(familyName);
1910 if (!f) return smoothScalable;
1912 for (int j = 0; j < f->count; j++) {
1913 QtFontFoundry *foundry = f->foundries[j];
1914 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1915 for (int k = 0; k < foundry->count; k++)
1916 if ((style.isEmpty() ||
1917 foundry->styles[k]->styleName == style ||
1918 foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) {
1919 smoothScalable = true;
1925 return smoothScalable;
1929 Returns true if the font that has family \a family and style \a
1930 style is scalable; otherwise returns false.
1932 \sa isBitmapScalable(), isSmoothlyScalable()
1934 bool QFontDatabase::isScalable(const QString &family,
1935 const QString &style) const
1937 QMutexLocker locker(fontDatabaseMutex());
1938 if (isSmoothlyScalable(family, style))
1940 return isBitmapScalable(family, style);
1945 Returns a list of the point sizes available for the font that has
1946 family \a family and style \a style. The list may be empty.
1948 \sa smoothSizes(), standardSizes()
1950 QList<int> QFontDatabase::pointSizes(const QString &family,
1951 const QString &styleName)
1953 #if defined(Q_WS_WIN)
1954 // windows and macosx are always smoothly scalable
1956 Q_UNUSED(styleName);
1957 return standardSizes();
1959 bool smoothScalable = false;
1960 QString familyName, foundryName;
1961 parseFontName(family, foundryName, familyName);
1963 QMutexLocker locker(fontDatabaseMutex());
1965 QT_PREPEND_NAMESPACE(load)(familyName);
1967 QtFontStyle::Key styleKey(styleName);
1971 QtFontFamily *fam = d->family(familyName);
1972 if (!fam) return sizes;
1976 int dpi = QX11Info::appDpiY();
1978 const int dpi = qt_defaultDpiY(); // embedded
1981 for (int j = 0; j < fam->count; j++) {
1982 QtFontFoundry *foundry = fam->foundries[j];
1983 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1984 QtFontStyle *style = foundry->style(styleKey, styleName);
1985 if (!style) continue;
1987 if (style->smoothScalable) {
1988 smoothScalable = true;
1991 for (int l = 0; l < style->count; l++) {
1992 const QtFontSize *size = style->pixelSizes + l;
1994 if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) {
1995 const uint pointSize = qRound(size->pixelSize * 72.0 / dpi);
1996 if (! sizes.contains(pointSize))
1997 sizes.append(pointSize);
2004 return standardSizes();
2012 Returns a QFont object that has family \a family, style \a style
2013 and point size \a pointSize. If no matching font could be created,
2014 a QFont object that uses the application's default font is
2017 QFont QFontDatabase::font(const QString &family, const QString &style,
2018 int pointSize) const
2020 QString familyName, foundryName;
2021 parseFontName(family, foundryName, familyName);
2023 QMutexLocker locker(fontDatabaseMutex());
2025 QT_PREPEND_NAMESPACE(load)(familyName);
2027 QtFontFoundry allStyles(foundryName);
2028 QtFontFamily *f = d->family(familyName);
2029 if (!f) return QGuiApplication::font();
2031 for (int j = 0; j < f->count; j++) {
2032 QtFontFoundry *foundry = f->foundries[j];
2033 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
2034 for (int k = 0; k < foundry->count; k++)
2035 allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
2039 QtFontStyle::Key styleKey(style);
2040 QtFontStyle *s = bestStyle(&allStyles, styleKey, style);
2042 if (!s) // no styles found?
2043 return QGuiApplication::font();
2045 QFont fnt(family, pointSize, s->key.weight);
2046 fnt.setStyle((QFont::Style)s->key.style);
2047 if (!s->styleName.isEmpty())
2048 fnt.setStyleName(s->styleName);
2054 Returns the point sizes of a font that has family \a family and
2055 style \a style that will look attractive. The list may be empty.
2056 For non-scalable fonts and bitmap scalable fonts, this function
2057 is equivalent to pointSizes().
2059 \sa pointSizes(), standardSizes()
2061 QList<int> QFontDatabase::smoothSizes(const QString &family,
2062 const QString &styleName)
2066 Q_UNUSED(styleName);
2067 return QFontDatabase::standardSizes();
2069 bool smoothScalable = false;
2070 QString familyName, foundryName;
2071 parseFontName(family, foundryName, familyName);
2073 QMutexLocker locker(fontDatabaseMutex());
2075 QT_PREPEND_NAMESPACE(load)(familyName);
2077 QtFontStyle::Key styleKey(styleName);
2081 QtFontFamily *fam = d->family(familyName);
2086 int dpi = QX11Info::appDpiY();
2088 const int dpi = qt_defaultDpiY(); // embedded
2091 for (int j = 0; j < fam->count; j++) {
2092 QtFontFoundry *foundry = fam->foundries[j];
2093 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
2094 QtFontStyle *style = foundry->style(styleKey, styleName);
2095 if (!style) continue;
2097 if (style->smoothScalable) {
2098 smoothScalable = true;
2101 for (int l = 0; l < style->count; l++) {
2102 const QtFontSize *size = style->pixelSizes + l;
2104 if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) {
2105 const uint pointSize = qRound(size->pixelSize * 72.0 / dpi);
2106 if (! sizes.contains(pointSize))
2107 sizes.append(pointSize);
2114 return QFontDatabase::standardSizes();
2123 Returns a list of standard font sizes.
2125 \sa smoothSizes(), pointSizes()
2127 QList<int> QFontDatabase::standardSizes()
2130 static const unsigned short standard[] =
2131 { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72, 0 };
2132 const unsigned short *sizes = standard;
2133 while (*sizes) ret << *sizes++;
2139 Returns true if the font that has family \a family and style \a
2140 style is italic; otherwise returns false.
2142 \sa weight(), bold()
2144 bool QFontDatabase::italic(const QString &family, const QString &style) const
2146 QString familyName, foundryName;
2147 parseFontName(family, foundryName, familyName);
2149 QMutexLocker locker(fontDatabaseMutex());
2151 QT_PREPEND_NAMESPACE(load)(familyName);
2153 QtFontFoundry allStyles(foundryName);
2154 QtFontFamily *f = d->family(familyName);
2155 if (!f) return false;
2157 for (int j = 0; j < f->count; j++) {
2158 QtFontFoundry *foundry = f->foundries[j];
2159 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
2160 for (int k = 0; k < foundry->count; k++)
2161 allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
2165 QtFontStyle::Key styleKey(style);
2166 QtFontStyle *s = allStyles.style(styleKey, style);
2167 return s && s->key.style == QFont::StyleItalic;
2172 Returns true if the font that has family \a family and style \a
2173 style is bold; otherwise returns false.
2175 \sa italic(), weight()
2177 bool QFontDatabase::bold(const QString &family,
2178 const QString &style) const
2180 QString familyName, foundryName;
2181 parseFontName(family, foundryName, familyName);
2183 QMutexLocker locker(fontDatabaseMutex());
2185 QT_PREPEND_NAMESPACE(load)(familyName);
2187 QtFontFoundry allStyles(foundryName);
2188 QtFontFamily *f = d->family(familyName);
2189 if (!f) return false;
2191 for (int j = 0; j < f->count; j++) {
2192 QtFontFoundry *foundry = f->foundries[j];
2193 if (foundryName.isEmpty() ||
2194 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
2195 for (int k = 0; k < foundry->count; k++)
2196 allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
2200 QtFontStyle::Key styleKey(style);
2201 QtFontStyle *s = allStyles.style(styleKey, style);
2202 return s && s->key.weight >= QFont::Bold;
2207 Returns the weight of the font that has family \a family and style
2208 \a style. If there is no such family and style combination,
2211 \sa italic(), bold()
2213 int QFontDatabase::weight(const QString &family,
2214 const QString &style) const
2216 QString familyName, foundryName;
2217 parseFontName(family, foundryName, familyName);
2219 QMutexLocker locker(fontDatabaseMutex());
2221 QT_PREPEND_NAMESPACE(load)(familyName);
2223 QtFontFoundry allStyles(foundryName);
2224 QtFontFamily *f = d->family(familyName);
2227 for (int j = 0; j < f->count; j++) {
2228 QtFontFoundry *foundry = f->foundries[j];
2229 if (foundryName.isEmpty() ||
2230 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
2231 for (int k = 0; k < foundry->count; k++)
2232 allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
2236 QtFontStyle::Key styleKey(style);
2237 QtFontStyle *s = allStyles.style(styleKey, style);
2238 return s ? s->key.weight : -1;
2243 bool QFontDatabase::hasFamily(const QString &family) const
2245 QString parsedFamily, foundry;
2246 parseFontName(family, foundry, parsedFamily);
2247 const QString familyAlias = resolveFontFamilyAlias(parsedFamily);
2248 return families().contains(familyAlias, Qt::CaseInsensitive);
2253 Returns the names the \a writingSystem (e.g. for displaying to the
2256 QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
2258 const char *name = 0;
2259 switch (writingSystem) {
2261 name = QT_TRANSLATE_NOOP("QFontDatabase", "Any");
2264 name = QT_TRANSLATE_NOOP("QFontDatabase", "Latin");
2267 name = QT_TRANSLATE_NOOP("QFontDatabase", "Greek");
2270 name = QT_TRANSLATE_NOOP("QFontDatabase", "Cyrillic");
2273 name = QT_TRANSLATE_NOOP("QFontDatabase", "Armenian");
2276 name = QT_TRANSLATE_NOOP("QFontDatabase", "Hebrew");
2279 name = QT_TRANSLATE_NOOP("QFontDatabase", "Arabic");
2282 name = QT_TRANSLATE_NOOP("QFontDatabase", "Syriac");
2285 name = QT_TRANSLATE_NOOP("QFontDatabase", "Thaana");
2288 name = QT_TRANSLATE_NOOP("QFontDatabase", "Devanagari");
2291 name = QT_TRANSLATE_NOOP("QFontDatabase", "Bengali");
2294 name = QT_TRANSLATE_NOOP("QFontDatabase", "Gurmukhi");
2297 name = QT_TRANSLATE_NOOP("QFontDatabase", "Gujarati");
2300 name = QT_TRANSLATE_NOOP("QFontDatabase", "Oriya");
2303 name = QT_TRANSLATE_NOOP("QFontDatabase", "Tamil");
2306 name = QT_TRANSLATE_NOOP("QFontDatabase", "Telugu");
2309 name = QT_TRANSLATE_NOOP("QFontDatabase", "Kannada");
2312 name = QT_TRANSLATE_NOOP("QFontDatabase", "Malayalam");
2315 name = QT_TRANSLATE_NOOP("QFontDatabase", "Sinhala");
2318 name = QT_TRANSLATE_NOOP("QFontDatabase", "Thai");
2321 name = QT_TRANSLATE_NOOP("QFontDatabase", "Lao");
2324 name = QT_TRANSLATE_NOOP("QFontDatabase", "Tibetan");
2327 name = QT_TRANSLATE_NOOP("QFontDatabase", "Myanmar");
2330 name = QT_TRANSLATE_NOOP("QFontDatabase", "Georgian");
2333 name = QT_TRANSLATE_NOOP("QFontDatabase", "Khmer");
2335 case SimplifiedChinese:
2336 name = QT_TRANSLATE_NOOP("QFontDatabase", "Simplified Chinese");
2338 case TraditionalChinese:
2339 name = QT_TRANSLATE_NOOP("QFontDatabase", "Traditional Chinese");
2342 name = QT_TRANSLATE_NOOP("QFontDatabase", "Japanese");
2345 name = QT_TRANSLATE_NOOP("QFontDatabase", "Korean");
2348 name = QT_TRANSLATE_NOOP("QFontDatabase", "Vietnamese");
2351 name = QT_TRANSLATE_NOOP("QFontDatabase", "Symbol");
2354 name = QT_TRANSLATE_NOOP("QFontDatabase", "Ogham");
2357 name = QT_TRANSLATE_NOOP("QFontDatabase", "Runic");
2360 name = QT_TRANSLATE_NOOP("QFontDatabase", "N'Ko");
2363 Q_ASSERT_X(false, "QFontDatabase::writingSystemName", "invalid 'writingSystem' parameter");
2366 return QCoreApplication::translate("QFontDatabase", name);
2371 Returns a string with sample characters from \a writingSystem.
2373 QString QFontDatabase::writingSystemSample(WritingSystem writingSystem)
2376 switch (writingSystem) {
2379 // show only ascii characters
2380 sample += QLatin1String("AaBbzZ");
2383 // This is cheating... we only show latin-1 characters so that we don't
2384 // end up loading lots of fonts - at least on X11...
2385 sample = QLatin1String("Aa");
2386 sample += QChar(0x00C3);
2387 sample += QChar(0x00E1);
2388 sample += QLatin1String("Zz");
2391 sample += QChar(0x0393);
2392 sample += QChar(0x03B1);
2393 sample += QChar(0x03A9);
2394 sample += QChar(0x03C9);
2397 sample += QChar(0x0414);
2398 sample += QChar(0x0434);
2399 sample += QChar(0x0436);
2400 sample += QChar(0x044f);
2403 sample += QChar(0x053f);
2404 sample += QChar(0x054f);
2405 sample += QChar(0x056f);
2406 sample += QChar(0x057f);
2409 sample += QChar(0x05D0);
2410 sample += QChar(0x05D1);
2411 sample += QChar(0x05D2);
2412 sample += QChar(0x05D3);
2415 sample += QChar(0x0628);
2416 sample += QChar(0x0629);
2417 sample += QChar(0x062A);
2418 sample += QChar(0x063A);
2421 sample += QChar(0x0715);
2422 sample += QChar(0x0725);
2423 sample += QChar(0x0716);
2424 sample += QChar(0x0726);
2427 sample += QChar(0x0784);
2428 sample += QChar(0x0794);
2429 sample += QChar(0x078c);
2430 sample += QChar(0x078d);
2433 sample += QChar(0x0905);
2434 sample += QChar(0x0915);
2435 sample += QChar(0x0925);
2436 sample += QChar(0x0935);
2439 sample += QChar(0x0986);
2440 sample += QChar(0x0996);
2441 sample += QChar(0x09a6);
2442 sample += QChar(0x09b6);
2445 sample += QChar(0x0a05);
2446 sample += QChar(0x0a15);
2447 sample += QChar(0x0a25);
2448 sample += QChar(0x0a35);
2451 sample += QChar(0x0a85);
2452 sample += QChar(0x0a95);
2453 sample += QChar(0x0aa5);
2454 sample += QChar(0x0ab5);
2457 sample += QChar(0x0b06);
2458 sample += QChar(0x0b16);
2459 sample += QChar(0x0b2b);
2460 sample += QChar(0x0b36);
2463 sample += QChar(0x0b89);
2464 sample += QChar(0x0b99);
2465 sample += QChar(0x0ba9);
2466 sample += QChar(0x0bb9);
2469 sample += QChar(0x0c05);
2470 sample += QChar(0x0c15);
2471 sample += QChar(0x0c25);
2472 sample += QChar(0x0c35);
2475 sample += QChar(0x0c85);
2476 sample += QChar(0x0c95);
2477 sample += QChar(0x0ca5);
2478 sample += QChar(0x0cb5);
2481 sample += QChar(0x0d05);
2482 sample += QChar(0x0d15);
2483 sample += QChar(0x0d25);
2484 sample += QChar(0x0d35);
2487 sample += QChar(0x0d90);
2488 sample += QChar(0x0da0);
2489 sample += QChar(0x0db0);
2490 sample += QChar(0x0dc0);
2493 sample += QChar(0x0e02);
2494 sample += QChar(0x0e12);
2495 sample += QChar(0x0e22);
2496 sample += QChar(0x0e32);
2499 sample += QChar(0x0e8d);
2500 sample += QChar(0x0e9d);
2501 sample += QChar(0x0ead);
2502 sample += QChar(0x0ebd);
2505 sample += QChar(0x0f00);
2506 sample += QChar(0x0f01);
2507 sample += QChar(0x0f02);
2508 sample += QChar(0x0f03);
2511 sample += QChar(0x1000);
2512 sample += QChar(0x1001);
2513 sample += QChar(0x1002);
2514 sample += QChar(0x1003);
2517 sample += QChar(0x10a0);
2518 sample += QChar(0x10b0);
2519 sample += QChar(0x10c0);
2520 sample += QChar(0x10d0);
2523 sample += QChar(0x1780);
2524 sample += QChar(0x1790);
2525 sample += QChar(0x17b0);
2526 sample += QChar(0x17c0);
2528 case SimplifiedChinese:
2529 sample += QChar(0x4e2d);
2530 sample += QChar(0x6587);
2531 sample += QChar(0x8303);
2532 sample += QChar(0x4f8b);
2534 case TraditionalChinese:
2535 sample += QChar(0x4e2d);
2536 sample += QChar(0x6587);
2537 sample += QChar(0x7bc4);
2538 sample += QChar(0x4f8b);
2541 sample += QChar(0x30b5);
2542 sample += QChar(0x30f3);
2543 sample += QChar(0x30d7);
2544 sample += QChar(0x30eb);
2545 sample += QChar(0x3067);
2546 sample += QChar(0x3059);
2549 sample += QChar(0xac00);
2550 sample += QChar(0xac11);
2551 sample += QChar(0xac1a);
2552 sample += QChar(0xac2f);
2556 static const char vietnameseUtf8[] = {
2557 char(0xef), char(0xbb), char(0xbf), char(0xe1), char(0xbb), char(0x97),
2558 char(0xe1), char(0xbb), char(0x99),
2559 char(0xe1), char(0xbb), char(0x91),
2560 char(0xe1), char(0xbb), char(0x93),
2562 sample += QString::fromUtf8(vietnameseUtf8, sizeof(vietnameseUtf8));
2566 sample += QChar(0x1681);
2567 sample += QChar(0x1682);
2568 sample += QChar(0x1683);
2569 sample += QChar(0x1684);
2572 sample += QChar(0x16a0);
2573 sample += QChar(0x16a1);
2574 sample += QChar(0x16a2);
2575 sample += QChar(0x16a3);
2578 sample += QChar(0x7ca);
2579 sample += QChar(0x7cb);
2580 sample += QChar(0x7cc);
2581 sample += QChar(0x7cd);
2590 void QFontDatabase::parseFontName(const QString &name, QString &foundry, QString &family)
2592 QT_PREPEND_NAMESPACE(parseFontName)(name, foundry, family);
2595 void QFontDatabase::createDatabase()
2598 // used from qfontengine_ft.cpp
2599 Q_GUI_EXPORT QByteArray qt_fontdata_from_index(int index)
2601 QMutexLocker locker(fontDatabaseMutex());
2602 return privateDb()->applicationFonts.value(index).data;
2605 int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &fileName)
2607 QFontDatabasePrivate::ApplicationFont font;
2608 font.data = fontData;
2609 font.fileName = fileName;
2612 for (i = 0; i < applicationFonts.count(); ++i)
2613 if (applicationFonts.at(i).families.isEmpty())
2615 if (i >= applicationFonts.count()) {
2616 applicationFonts.append(ApplicationFont());
2617 i = applicationFonts.count() - 1;
2620 if (font.fileName.isEmpty() && !fontData.isEmpty())
2621 font.fileName = QString::fromLatin1(":qmemoryfonts/") + QString::number(i);
2623 registerFont(&font);
2624 if (font.families.isEmpty())
2627 applicationFonts[i] = font;
2633 bool QFontDatabasePrivate::isApplicationFont(const QString &fileName)
2635 for (int i = 0; i < applicationFonts.count(); ++i)
2636 if (applicationFonts.at(i).fileName == fileName)
2644 Loads the font from the file specified by \a fileName and makes it available to
2645 the application. An ID is returned that can be used to remove the font again
2646 with removeApplicationFont() or to retrieve the list of family names contained
2649 The function returns -1 if the font could not be loaded.
2651 Currently only TrueType fonts, TrueType font collections, and OpenType fonts are
2654 \note Adding application fonts on Unix/X11 platforms without fontconfig is
2655 currently not supported.
2657 \note On Symbian, the font family names get truncated to a length of 20 characters.
2659 \sa addApplicationFontFromData(), applicationFontFamilies(), removeApplicationFont()
2661 int QFontDatabase::addApplicationFont(const QString &fileName)
2665 if (!(f.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) {
2666 if (!f.open(QIODevice::ReadOnly))
2670 QMutexLocker locker(fontDatabaseMutex());
2671 return privateDb()->addAppFont(data, fileName);
2677 Loads the font from binary data specified by \a fontData and makes it available to
2678 the application. An ID is returned that can be used to remove the font again
2679 with removeApplicationFont() or to retrieve the list of family names contained
2682 The function returns -1 if the font could not be loaded.
2684 Currently only TrueType fonts and TrueType font collections are supported.
2686 \bold{Note:} Adding application fonts on Unix/X11 platforms without fontconfig is
2687 currently not supported.
2689 \note On Symbian, the font family names get truncated to a length of 20 characters.
2691 \sa addApplicationFont(), applicationFontFamilies(), removeApplicationFont()
2693 int QFontDatabase::addApplicationFontFromData(const QByteArray &fontData)
2695 QMutexLocker locker(fontDatabaseMutex());
2696 return privateDb()->addAppFont(fontData, QString() /* fileName */);
2702 Returns a list of font families for the given application font identified by
2705 \sa addApplicationFont(), addApplicationFontFromData()
2707 QStringList QFontDatabase::applicationFontFamilies(int id)
2709 QMutexLocker locker(fontDatabaseMutex());
2710 return privateDb()->applicationFonts.value(id).families;
2714 \fn bool QFontDatabase::removeApplicationFont(int id)
2717 Removes the previously loaded application font identified by \a
2718 id. Returns true if unloading of the font succeeded; otherwise
2721 \sa removeAllApplicationFonts(), addApplicationFont(),
2722 addApplicationFontFromData()
2726 \fn bool QFontDatabase::removeAllApplicationFonts()
2729 Removes all application-local fonts previously added using addApplicationFont()
2730 and addApplicationFontFromData().
2732 Returns true if unloading of the fonts succeeded; otherwise
2735 \sa removeApplicationFont(), addApplicationFont(), addApplicationFontFromData()
2739 \fn bool QFontDatabase::supportsThreadedFontRendering()
2742 Returns true if font rendering is supported outside the GUI
2743 thread, false otherwise. In other words, a return value of false
2744 means that all QPainter::drawText() calls outside the GUI thread
2745 will not produce readable output.
2747 \sa {Thread-Support in Qt Modules#Painting In Threads}{Painting In Threads}