1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qfontdatabase.h"
44 #include "qalgorithms.h"
45 #include "qguiapplication.h"
46 #include "qvarlengtharray.h" // here or earlier - workaround for VC++6
50 #include "qfileinfo.h"
51 #include "private/qunicodetables_p.h"
52 #include "qfontengine_p.h"
53 #include <qpa/qplatformintegration.h>
55 #include <QtGui/private/qguiapplication_p.h>
56 #include <qpa/qplatformfontdatabase.h>
62 // #define QFONTDATABASE_DEBUG
63 #ifdef QFONTDATABASE_DEBUG
64 # define FD_DEBUG qDebug
66 # define FD_DEBUG if (false) qDebug
69 // #define FONT_MATCH_DEBUG
70 #ifdef FONT_MATCH_DEBUG
71 # define FM_DEBUG qDebug
73 # define FM_DEBUG if (false) qDebug
79 #define SMOOTH_SCALABLE 0xffff
81 bool qt_enable_test_font = false;
83 Q_AUTOTEST_EXPORT void qt_setQtEnableTestFont(bool value)
85 qt_enable_test_font = value;
88 static int getFontWeight(const QString &weightString)
90 QString s = weightString.toLower();
92 // Test in decreasing order of commonness
93 if (s == QLatin1String("medium") ||
94 s == QLatin1String("normal")
95 || s.compare(QCoreApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0)
97 if (s == QLatin1String("bold")
98 || s.compare(QCoreApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0)
100 if (s == QLatin1String("demibold") || s == QLatin1String("demi bold")
101 || s.compare(QCoreApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0)
102 return QFont::DemiBold;
103 if (s == QLatin1String("black")
104 || s.compare(QCoreApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
106 if (s == QLatin1String("light"))
109 if (s.contains(QLatin1String("bold"))
110 || s.contains(QCoreApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) {
111 if (s.contains(QLatin1String("demi"))
112 || s.compare(QCoreApplication::translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0)
113 return (int) QFont::DemiBold;
114 return (int) QFont::Bold;
117 if (s.contains(QLatin1String("light"))
118 || s.compare(QCoreApplication::translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0)
119 return (int) QFont::Light;
121 if (s.contains(QLatin1String("black"))
122 || s.compare(QCoreApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
123 return (int) QFont::Black;
125 return (int) QFont::Normal;
128 // convert 0 ~ 1000 integer to QFont::Weight
129 QFont::Weight weightFromInteger(int weight)
133 else if (weight < 600)
134 return QFont::Normal;
135 else if (weight < 700)
136 return QFont::DemiBold;
137 else if (weight < 800)
143 struct QtFontEncoding
145 signed int encoding : 16;
159 unsigned short pixelSize : 16;
167 Key(const QString &styleString);
168 Key() : style(QFont::StyleNormal),
169 weight(QFont::Normal), stretch(0) { }
170 Key(const Key &o) : style(o.style), weight(o.weight), stretch(o.stretch) { }
172 signed int weight : 8;
173 signed int stretch : 12;
175 bool operator==(const Key & other) {
176 return (style == other.style && weight == other.weight &&
177 (stretch == 0 || other.stretch == 0 || stretch == other.stretch));
179 bool operator!=(const Key &other) {
180 return !operator==(other);
182 bool operator <(const Key &o) {
183 int x = (style << 12) + (weight << 14) + stretch;
184 int y = (o.style << 12) + (o.weight << 14) + o.stretch;
189 QtFontStyle(const Key &k)
190 : key(k), bitmapScalable(false), smoothScalable(false),
191 count(0), pixelSizes(0)
197 // bitfield count-- in while condition does not work correctly in mwccsym2
199 QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
201 integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
208 bool bitmapScalable : 1;
209 bool smoothScalable : 1;
210 signed int count : 30;
211 QtFontSize *pixelSizes;
216 QtFontSize *pixelSize(unsigned short size, bool = false);
219 QtFontStyle::Key::Key(const QString &styleString)
220 : style(QFont::StyleNormal), weight(QFont::Normal), stretch(0)
222 weight = getFontWeight(styleString);
224 if (styleString.contains(QLatin1String("Italic"))
225 || styleString.contains(QCoreApplication::translate("QFontDatabase", "Italic")))
226 style = QFont::StyleItalic;
227 else if (styleString.contains(QLatin1String("Oblique"))
228 || styleString.contains(QCoreApplication::translate("QFontDatabase", "Oblique")))
229 style = QFont::StyleOblique;
232 QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add)
234 for (int i = 0; i < count; i++) {
235 if (pixelSizes[i].pixelSize == size)
236 return pixelSizes + i;
242 // Most style have only one font size, we avoid waisting memory
243 QtFontSize *newPixelSizes = (QtFontSize *)malloc(sizeof(QtFontSize));
244 Q_CHECK_PTR(newPixelSizes);
245 pixelSizes = newPixelSizes;
246 } else if (!(count % 8) || count == 1) {
247 QtFontSize *newPixelSizes = (QtFontSize *)
249 (((count+8) >> 3) << 3) * sizeof(QtFontSize));
250 Q_CHECK_PTR(newPixelSizes);
251 pixelSizes = newPixelSizes;
253 pixelSizes[count].pixelSize = size;
254 pixelSizes[count].handle = 0;
255 return pixelSizes + (count++);
260 QtFontFoundry(const QString &n) : name(n), count(0), styles(0) {}
263 delete styles[count];
270 QtFontStyle **styles;
271 QtFontStyle *style(const QtFontStyle::Key &, const QString & = QString(), bool = false);
274 QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, const QString &styleName, bool create)
278 // if styleName for searching first if possible
279 if (!styleName.isEmpty()) {
280 for (; pos < count; pos++) {
281 if (styles[pos]->styleName == styleName)
289 if (styles[pos]->key == key)
291 if (styles[pos]->key < key)
295 pos = (high + low) / 2;
302 // qDebug("adding key (weight=%d, style=%d, oblique=%d stretch=%d) at %d", key.weight, key.style, key.oblique, key.stretch, pos);
304 QtFontStyle **newStyles = (QtFontStyle **)
305 realloc(styles, (((count+8) >> 3) << 3) * sizeof(QtFontStyle *));
306 Q_CHECK_PTR(newStyles);
310 QtFontStyle *style = new QtFontStyle(key);
311 style->styleName = styleName;
312 memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *));
321 enum WritingSystemStatus {
325 Unsupported = UnsupportedFT
328 QtFontFamily(const QString &n)
331 #if !defined(QWS) && defined(Q_OS_MAC)
332 fixedPitchComputed(false),
334 name(n), count(0), foundries(0)
335 , bogusWritingSystems(false)
336 , askedForFallback(false)
338 memset(writingSystems, 0, sizeof(writingSystems));
342 delete foundries[count];
347 #if !defined(QWS) && defined(Q_OS_MAC)
348 bool fixedPitchComputed : 1;
354 QtFontFoundry **foundries;
356 bool bogusWritingSystems;
357 QStringList fallbackFamilies;
358 bool askedForFallback;
359 unsigned char writingSystems[QFontDatabase::WritingSystemsCount];
361 QtFontFoundry *foundry(const QString &f, bool = false);
364 #if !defined(QWS) && defined(Q_OS_MAC)
365 inline static void qt_mac_get_fixed_pitch(QtFontFamily *f)
367 if(f && !f->fixedPitchComputed) {
368 QFontMetrics fm(f->name);
369 f->fixedPitch = fm.width(QLatin1Char('i')) == fm.width(QLatin1Char('m'));
370 f->fixedPitchComputed = true;
376 QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create)
378 if (f.isNull() && count == 1)
381 for (int i = 0; i < count; i++) {
382 if (foundries[i]->name.compare(f, Qt::CaseInsensitive) == 0)
389 QtFontFoundry **newFoundries = (QtFontFoundry **)
391 (((count+8) >> 3) << 3) * sizeof(QtFontFoundry *));
392 Q_CHECK_PTR(newFoundries);
393 foundries = newFoundries;
396 foundries[count] = new QtFontFoundry(f);
397 return foundries[count++];
400 // ### copied to tools/makeqpf/qpf2.cpp
402 // see the Unicode subset bitfields in the MSDN docs
403 static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
454 // SimplifiedChinese,
456 // TraditionalChinese,
463 { 0, 127 }, // same as latin1
474 #define SimplifiedChineseCsbBit 18
475 #define TraditionalChineseCsbBit 20
476 #define JapaneseCsbBit 17
477 #define KoreanCsbBit 21
479 QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_truetype_bits(quint32 unicodeRange[4], quint32 codePageRange[2])
481 QList<QFontDatabase::WritingSystem> writingSystems;
482 bool hasScript = false;
485 for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
486 int bit = requiredUnicodeBits[i][0];
488 int flag = 1 << (bit&31);
489 if (bit != 126 && unicodeRange[index] & flag) {
490 bit = requiredUnicodeBits[i][1];
493 flag = 1 << (bit&31);
494 if (bit == 127 || unicodeRange[index] & flag) {
495 writingSystems.append(QFontDatabase::WritingSystem(i));
497 // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
501 if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
502 writingSystems.append(QFontDatabase::SimplifiedChinese);
504 //qDebug("font %s supports Simplified Chinese", familyName.latin1());
506 if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
507 writingSystems.append(QFontDatabase::TraditionalChinese);
509 //qDebug("font %s supports Traditional Chinese", familyName.latin1());
511 if(codePageRange[0] & (1 << JapaneseCsbBit)) {
512 writingSystems.append(QFontDatabase::Japanese);
514 //qDebug("font %s supports Japanese", familyName.latin1());
516 if(codePageRange[0] & (1 << KoreanCsbBit)) {
517 writingSystems.append(QFontDatabase::Korean);
519 //qDebug("font %s supports Korean", familyName.latin1());
522 writingSystems.append(QFontDatabase::Symbol);
524 return writingSystems;
528 class QFontDatabasePrivate
531 QFontDatabasePrivate()
532 : count(0), families(0), reregisterAppFonts(false)
535 ~QFontDatabasePrivate() {
538 QtFontFamily *family(const QString &f, bool = false);
541 delete families[count];
545 // don't clear the memory fonts!
549 QtFontFamily **families;
553 struct ApplicationFont {
556 QStringList families;
558 QVector<ApplicationFont> applicationFonts;
559 int addAppFont(const QByteArray &fontData, const QString &fileName);
560 bool reregisterAppFonts;
561 bool isApplicationFont(const QString &fileName);
565 QStringList fallbackFamilies;
568 void QFontDatabasePrivate::invalidate()
570 QFontCache::instance()->clear();
572 emit static_cast<QGuiApplication *>(QCoreApplication::instance())->fontDatabaseChanged();
575 QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create)
582 while ((res = families[pos]->name.compare(f, Qt::CaseInsensitive)) && pos != low) {
587 pos = (high + low) / 2;
590 return families[pos];
598 // qDebug("adding family %s at %d total=%d", f.latin1(), pos, count);
600 QtFontFamily **newFamilies = (QtFontFamily **)
602 (((count+8) >> 3) << 3) * sizeof(QtFontFamily *));
603 Q_CHECK_PTR(newFamilies);
604 families = newFamilies;
607 QtFontFamily *family = new QtFontFamily(f);
608 memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *));
609 families[pos] = family;
611 return families[pos];
616 static const int scriptForWritingSystem[] = {
617 QUnicodeTables::Common, // Any
618 QUnicodeTables::Latin, // Latin
619 QUnicodeTables::Greek, // Greek
620 QUnicodeTables::Cyrillic, // Cyrillic
621 QUnicodeTables::Armenian, // Armenian
622 QUnicodeTables::Hebrew, // Hebrew
623 QUnicodeTables::Arabic, // Arabic
624 QUnicodeTables::Syriac, // Syriac
625 QUnicodeTables::Thaana, // Thaana
626 QUnicodeTables::Devanagari, // Devanagari
627 QUnicodeTables::Bengali, // Bengali
628 QUnicodeTables::Gurmukhi, // Gurmukhi
629 QUnicodeTables::Gujarati, // Gujarati
630 QUnicodeTables::Oriya, // Oriya
631 QUnicodeTables::Tamil, // Tamil
632 QUnicodeTables::Telugu, // Telugu
633 QUnicodeTables::Kannada, // Kannada
634 QUnicodeTables::Malayalam, // Malayalam
635 QUnicodeTables::Sinhala, // Sinhala
636 QUnicodeTables::Thai, // Thai
637 QUnicodeTables::Lao, // Lao
638 QUnicodeTables::Tibetan, // Tibetan
639 QUnicodeTables::Myanmar, // Myanmar
640 QUnicodeTables::Georgian, // Georgian
641 QUnicodeTables::Khmer, // Khmer
642 QUnicodeTables::Common, // SimplifiedChinese
643 QUnicodeTables::Common, // TraditionalChinese
644 QUnicodeTables::Common, // Japanese
645 QUnicodeTables::Hangul, // Korean
646 QUnicodeTables::Common, // Vietnamese
647 QUnicodeTables::Common, // Yi
648 QUnicodeTables::Common, // Tagalog
649 QUnicodeTables::Common, // Hanunoo
650 QUnicodeTables::Common, // Buhid
651 QUnicodeTables::Common, // Tagbanwa
652 QUnicodeTables::Common, // Limbu
653 QUnicodeTables::Common, // TaiLe
654 QUnicodeTables::Common, // Braille
655 QUnicodeTables::Common, // Symbol
656 QUnicodeTables::Ogham, // Ogham
657 QUnicodeTables::Runic, // Runic
658 QUnicodeTables::Nko // Nko
661 int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem)
663 return scriptForWritingSystem[writingSystem];
672 This makes sense of the font family name:
674 if the family name contains a '[' and a ']', then we take the text
675 between the square brackets as the foundry, and the text before the
676 square brackets as the family (ie. "Arial [Monotype]")
678 static void parseFontName(const QString &name, QString &foundry, QString &family)
680 int i = name.indexOf(QLatin1Char('['));
681 int li = name.lastIndexOf(QLatin1Char(']'));
682 if (i >= 0 && li >= 0 && i < li) {
683 foundry = name.mid(i + 1, li - i - 1);
684 if (i > 0 && name[i - 1] == QLatin1Char(' '))
686 family = name.left(i);
692 // capitalize the family/foundry names
694 QChar *s = family.data();
695 int len = family.length();
697 if (space) *s = s->toUpper();
698 space = s->isSpace();
704 len = foundry.length();
706 if (space) *s = s->toUpper();
707 space = s->isSpace();
715 inline QtFontDesc() : family(0), foundry(0), style(0), size(0), encoding(0), familyIndex(-1) {}
716 QtFontFamily *family;
717 QtFontFoundry *foundry;
720 QtFontEncoding *encoding;
724 static void match(int script, const QFontDef &request,
725 const QString &family_name, const QString &foundry_name, int force_encoding_id,
726 QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>());
728 static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef, bool multi)
730 fontDef->family = desc.family->name;
731 if (! desc.foundry->name.isEmpty() && desc.family->count > 1) {
732 fontDef->family += QString::fromLatin1(" [");
733 fontDef->family += desc.foundry->name;
734 fontDef->family += QLatin1Char(']');
737 if (desc.style->smoothScalable
738 || QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable()
739 || (desc.style->bitmapScalable && (request.styleStrategy & QFont::PreferMatch))) {
740 fontDef->pixelSize = request.pixelSize;
742 fontDef->pixelSize = desc.size->pixelSize;
745 fontDef->styleHint = request.styleHint;
746 fontDef->styleStrategy = request.styleStrategy;
749 fontDef->weight = desc.style->key.weight;
751 fontDef->style = desc.style->key.style;
752 fontDef->fixedPitch = desc.family->fixedPitch;
753 fontDef->stretch = desc.style->key.stretch;
754 fontDef->ignorePitch = false;
757 static void getEngineData(const QFontPrivate *d, const QFontDef &def)
759 // look for the requested font in the engine data cache
760 d->engineData = QFontCache::instance()->findEngineData(def);
761 if (!d->engineData) {
763 d->engineData = new QFontEngineData;
764 QFontCache::instance()->insertEngineData(def, d->engineData);
766 d->engineData->ref.ref();
770 static QStringList familyList(const QFontDef &req)
772 // list of families to try
773 QStringList family_list;
774 if (req.family.isEmpty())
777 QStringList list = req.family.split(QLatin1Char(','));
778 for (int i = 0; i < list.size(); ++i) {
779 QString str = list.at(i).trimmed();
780 if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
781 || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
782 str = str.mid(1, str.length() - 2);
786 // append the substitute list for each family in family_list
787 QStringList subs_list;
788 QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
789 for (; it != end; ++it)
790 subs_list += QFont::substitutes(*it);
791 // qDebug() << "adding substs: " << subs_list;
793 family_list += subs_list;
798 Q_GLOBAL_STATIC(QFontDatabasePrivate, privateDb)
799 Q_GLOBAL_STATIC_WITH_ARGS(QMutex, fontDatabaseMutex, (QMutex::Recursive))
801 // used in qguiapplication.cpp
802 void qt_cleanupFontDatabase()
804 QFontDatabasePrivate *db = privateDb();
809 // used in qfontengine_x11.cpp
810 QMutex *qt_fontdatabase_mutex()
812 return fontDatabaseMutex();
815 QT_BEGIN_INCLUDE_NAMESPACE
816 # include "qfontdatabase_qpa.cpp"
817 QT_END_INCLUDE_NAMESPACE
819 static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey,
820 const QString &styleName = QString())
825 for ( int i = 0; i < foundry->count; i++ ) {
826 QtFontStyle *style = foundry->styles[i];
828 if (!styleName.isEmpty() && styleName == style->styleName) {
834 int d = qAbs( styleKey.weight - style->key.weight );
836 if ( styleKey.stretch != 0 && style->key.stretch != 0 ) {
837 d += qAbs( styleKey.stretch - style->key.stretch );
840 if (styleKey.style != style->key.style) {
841 if (styleKey.style != QFont::StyleNormal && style->key.style != QFont::StyleNormal)
842 // one is italic, the other oblique
854 FM_DEBUG( " best style has distance 0x%x", dist );
855 return foundry->styles[best];
860 unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
861 const QtFontFamily *family, const QString &foundry_name,
862 QtFontStyle::Key styleKey, int pixelSize, char pitch,
863 QtFontDesc *desc, int force_encoding_id)
865 Q_UNUSED(force_encoding_id);
875 FM_DEBUG(" REMARK: looking for best foundry for family '%s' [%d]", family->name.toLatin1().constData(), family->count);
877 for (int x = 0; x < family->count; ++x) {
878 QtFontFoundry *foundry = family->foundries[x];
879 if (!foundry_name.isEmpty() && foundry->name.compare(foundry_name, Qt::CaseInsensitive) != 0)
882 FM_DEBUG(" looking for matching style in foundry '%s' %d",
883 foundry->name.isEmpty() ? "-- none --" : foundry->name.toLatin1().constData(), foundry->count);
885 QtFontStyle *style = bestStyle(foundry, styleKey);
887 if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) {
888 FM_DEBUG(" ForceOutline set, but not smoothly scalable");
893 QtFontSize *size = 0;
895 // 1. see if we have an exact matching size
896 if (!(styleStrategy & QFont::ForceOutline)) {
897 size = style->pixelSize(pixelSize);
899 FM_DEBUG(" found exact size match (%d pixels)", size->pixelSize);
900 px = size->pixelSize;
904 // 2. see if we have a smoothly scalable font
905 if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
906 size = style->pixelSize(SMOOTH_SCALABLE);
908 FM_DEBUG(" found smoothly scalable font (%d pixels)", pixelSize);
913 // 3. see if we have a bitmap scalable font
914 if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
915 size = style->pixelSize(0);
917 FM_DEBUG(" found bitmap scalable font (%d pixels)", pixelSize);
923 // 4. find closest size match
925 unsigned int distance = ~0u;
926 for (int x = 0; x < style->count; ++x) {
929 if (style->pixelSizes[x].pixelSize < pixelSize) {
930 // penalize sizes that are smaller than the
931 // requested size, due to truncation from floating
932 // point to integer conversions
933 d = pixelSize - style->pixelSizes[x].pixelSize + 1;
935 d = style->pixelSizes[x].pixelSize - pixelSize;
940 size = style->pixelSizes + x;
941 FM_DEBUG(" best size so far: %3d (%d)", size->pixelSize, pixelSize);
946 FM_DEBUG(" no size supports the script we want");
950 if (style->bitmapScalable && ! (styleStrategy & QFont::PreferQuality) &&
951 (distance * 10 / pixelSize) >= 2) {
952 // the closest size is not close enough, go ahead and
953 // use a bitmap scaled font
954 size = style->pixelSize(0);
957 px = size->pixelSize;
962 unsigned int this_score = 0x0000;
964 PitchMismatch = 0x4000,
965 StyleMismatch = 0x2000,
966 BitmapScaledPenalty = 0x1000,
967 EncodingMismatch = 0x0002
970 #if !defined(QWS) && defined(Q_OS_MAC)
971 qt_mac_get_fixed_pitch(const_cast<QtFontFamily*>(family));
973 if ((pitch == 'm' && !family->fixedPitch)
974 || (pitch == 'p' && family->fixedPitch))
975 this_score += PitchMismatch;
977 if (styleKey != style->key)
978 this_score += StyleMismatch;
979 if (!style->smoothScalable && px != size->pixelSize) // bitmap scaled
980 this_score += BitmapScaledPenalty;
981 if (px != pixelSize) // close, but not exact, size match
982 this_score += qAbs(px - pixelSize);
984 if (this_score < score) {
985 FM_DEBUG(" found a match: score %x best score so far %x",
989 desc->foundry = foundry;
993 FM_DEBUG(" score %x no better than best %x", this_score, score);
1000 static bool matchFamilyName(const QString &familyName, QtFontFamily *f)
1002 if (familyName.isEmpty())
1005 if (f->name.compare(familyName, Qt::CaseInsensitive) == 0)
1008 QStringList::const_iterator it = f->aliases.constBegin();
1009 while (it != f->aliases.constEnd()) {
1010 if ((*it).compare(familyName, Qt::CaseInsensitive) == 0)
1022 Tries to find the best match for a given request and family/foundry
1024 static void match(int script, const QFontDef &request,
1025 const QString &family_name, const QString &foundry_name, int force_encoding_id,
1026 QtFontDesc *desc, const QList<int> &blacklistedFamilies)
1028 Q_UNUSED(force_encoding_id);
1030 QtFontStyle::Key styleKey;
1031 styleKey.style = request.style;
1032 styleKey.weight = request.weight;
1033 styleKey.stretch = request.stretch;
1034 char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';
1037 FM_DEBUG("QFontDatabase::match\n"
1039 " family: %s [%s], script: %d\n"
1040 " weight: %d, style: %d\n"
1044 family_name.isEmpty() ? "-- first in script --" : family_name.toLatin1().constData(),
1045 foundry_name.isEmpty() ? "-- any --" : foundry_name.toLatin1().constData(),
1046 script, request.weight, request.style, request.stretch, request.pixelSize, pitch);
1053 desc->familyIndex = -1;
1055 unsigned int score = ~0u;
1057 load(family_name, script);
1059 QFontDatabasePrivate *db = privateDb();
1060 for (int x = 0; x < db->count; ++x) {
1061 if (blacklistedFamilies.contains(x))
1064 test.family = db->families[x];
1065 test.familyIndex = x;
1067 if (!matchFamilyName(family_name, test.family))
1070 if (family_name.isEmpty())
1071 load(test.family->name, script);
1073 uint score_adjust = 0;
1075 bool supported = (script == QUnicodeTables::Common);
1076 for (int ws = 1; !supported && ws < QFontDatabase::WritingSystemsCount; ++ws) {
1077 if (scriptForWritingSystem[ws] != script)
1079 if (test.family->writingSystems[ws] & QtFontFamily::Supported)
1083 // family not supported in the script we want
1087 // as we know the script is supported, we can be sure
1088 // to find a matching font here.
1089 unsigned int newscore =
1090 bestFoundry(script, score, request.styleStrategy,
1091 test.family, foundry_name, styleKey, request.pixelSize, pitch,
1092 &test, force_encoding_id);
1093 if (test.foundry == 0) {
1094 // the specific foundry was not found, so look for
1095 // any foundry matching our requirements
1096 newscore = bestFoundry(script, score, request.styleStrategy, test.family,
1097 QString(), styleKey, request.pixelSize,
1098 pitch, &test, force_encoding_id);
1100 newscore += score_adjust;
1102 if (newscore < score) {
1106 if (newscore < 10) // xlfd instead of FT... just accept it
1111 static QString styleStringHelper(int weight, QFont::Style style)
1114 if (weight >= QFont::Black)
1115 result = QCoreApplication::translate("QFontDatabase", "Black");
1116 else if (weight >= QFont::Bold)
1117 result = QCoreApplication::translate("QFontDatabase", "Bold");
1118 else if (weight >= QFont::DemiBold)
1119 result = QCoreApplication::translate("QFontDatabase", "Demi Bold");
1120 else if (weight < QFont::Normal)
1121 result = QCoreApplication::translate("QFontDatabase", "Light");
1123 if (style == QFont::StyleItalic)
1124 result += QLatin1Char(' ') + QCoreApplication::translate("QFontDatabase", "Italic");
1125 else if (style == QFont::StyleOblique)
1126 result += QLatin1Char(' ') + QCoreApplication::translate("QFontDatabase", "Oblique");
1128 if (result.isEmpty())
1129 result = QCoreApplication::translate("QFontDatabase", "Normal");
1131 return result.simplified();
1135 Returns a string that describes the style of the \a font. For
1136 example, "Bold Italic", "Bold", "Italic" or "Normal". An empty
1137 string may be returned.
1139 QString QFontDatabase::styleString(const QFont &font)
1141 return font.styleName().isEmpty() ? styleStringHelper(font.weight(), font.style())
1146 Returns a string that describes the style of the \a fontInfo. For
1147 example, "Bold Italic", "Bold", "Italic" or "Normal". An empty
1148 string may be returned.
1150 QString QFontDatabase::styleString(const QFontInfo &fontInfo)
1152 return fontInfo.styleName().isEmpty() ? styleStringHelper(fontInfo.weight(), fontInfo.style())
1153 : fontInfo.styleName();
1158 \class QFontDatabase
1162 \brief The QFontDatabase class provides information about the fonts available in the underlying window system.
1166 The most common uses of this class are to query the database for
1167 the list of font families() and for the pointSizes() and styles()
1168 that are available for each family. An alternative to pointSizes()
1169 is smoothSizes() which returns the sizes at which a given family
1170 and style will look attractive.
1172 If the font family is available from two or more foundries the
1173 foundry name is included in the family name; for example:
1174 "Helvetica [Adobe]" and "Helvetica [Cronyx]". When you specify a
1175 family, you can either use the old hyphenated "foundry-family"
1176 format or the bracketed "family [foundry]" format; for example:
1177 "Cronyx-Helvetica" or "Helvetica [Cronyx]". If the family has a
1178 foundry it is always returned using the bracketed format, as is
1179 the case with the value returned by families().
1181 The font() function returns a QFont given a family, style and
1184 A family and style combination can be checked to see if it is
1185 italic() or bold(), and to retrieve its weight(). Similarly we can
1186 call isBitmapScalable(), isSmoothlyScalable(), isScalable() and
1189 Use the styleString() to obtain a text version of a style.
1191 The QFontDatabase class also supports some static functions, for
1192 example, standardSizes(). You can retrieve the description of a
1193 writing system using writingSystemName(), and a sample of
1194 characters in a writing system with writingSystemSample().
1198 \snippet qfontdatabase/main.cpp 0
1199 \snippet qfontdatabase/main.cpp 1
1201 This example gets the list of font families, the list of
1202 styles for each family, and the point sizes that are available for
1203 each combination of family and style, displaying this information
1206 \sa QFont, QFontInfo, QFontMetrics, QFontComboBox, {Character Map Example}
1210 Creates a font database object.
1212 QFontDatabase::QFontDatabase()
1214 QMutexLocker locker(fontDatabaseMutex());
1220 \enum QFontDatabase::WritingSystem
1247 \value SimplifiedChinese
1248 \value TraditionalChinese
1253 \value Other (the same as Symbol)
1258 \omitvalue WritingSystemsCount
1262 Returns a sorted list of the available writing systems. This is
1263 list generated from information about all installed fonts on the
1268 QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems() const
1270 QMutexLocker locker(fontDatabaseMutex());
1272 QT_PREPEND_NAMESPACE(load)();
1274 QList<WritingSystem> list;
1275 for (int i = 0; i < d->count; ++i) {
1276 QtFontFamily *family = d->families[i];
1277 if (family->count == 0)
1279 for (int x = Latin; x < WritingSystemsCount; ++x) {
1280 const WritingSystem writingSystem = WritingSystem(x);
1281 if (!(family->writingSystems[writingSystem] & QtFontFamily::Supported))
1283 if (!list.contains(writingSystem))
1284 list.append(writingSystem);
1293 Returns a sorted list of the writing systems supported by a given
1298 QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems(const QString &family) const
1300 QString familyName, foundryName;
1301 parseFontName(family, foundryName, familyName);
1303 QMutexLocker locker(fontDatabaseMutex());
1305 QT_PREPEND_NAMESPACE(load)();
1307 QList<WritingSystem> list;
1308 QtFontFamily *f = d->family(familyName);
1309 if (!f || f->count == 0)
1312 for (int x = Latin; x < WritingSystemsCount; ++x) {
1313 const WritingSystem writingSystem = WritingSystem(x);
1314 if (f->writingSystems[writingSystem] & QtFontFamily::Supported)
1315 list.append(writingSystem);
1322 Returns a sorted list of the available font families which support
1323 the \a writingSystem.
1325 If a family exists in several foundries, the returned name for
1326 that font is in the form "family [foundry]". Examples: "Times
1327 [Adobe]", "Times [Cronyx]", "Palatino".
1329 \sa writingSystems()
1331 QStringList QFontDatabase::families(WritingSystem writingSystem) const
1333 QMutexLocker locker(fontDatabaseMutex());
1335 QT_PREPEND_NAMESPACE(load)();
1338 for (int i = 0; i < d->count; i++) {
1339 QtFontFamily *f = d->families[i];
1342 if (writingSystem != Any && (f->writingSystems[writingSystem] != QtFontFamily::Supported))
1344 if (f->count == 1) {
1345 flist.append(f->name);
1347 for (int j = 0; j < f->count; j++) {
1348 QString str = f->name;
1349 QString foundry = f->foundries[j]->name;
1350 if (!foundry.isEmpty()) {
1351 str += QLatin1String(" [");
1353 str += QLatin1Char(']');
1363 Returns a list of the styles available for the font family \a
1364 family. Some example styles: "Light", "Light Italic", "Bold",
1365 "Oblique", "Demi". The list may be empty.
1369 QStringList QFontDatabase::styles(const QString &family) const
1371 QString familyName, foundryName;
1372 parseFontName(family, foundryName, familyName);
1374 QMutexLocker locker(fontDatabaseMutex());
1376 QT_PREPEND_NAMESPACE(load)(familyName);
1379 QtFontFamily *f = d->family(familyName);
1383 QtFontFoundry allStyles(foundryName);
1384 for (int j = 0; j < f->count; j++) {
1385 QtFontFoundry *foundry = f->foundries[j];
1386 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1387 for (int k = 0; k < foundry->count; k++) {
1388 QtFontStyle::Key ke(foundry->styles[k]->key);
1390 allStyles.style(ke, foundry->styles[k]->styleName, true);
1395 for (int i = 0; i < allStyles.count; i++) {
1396 l.append(allStyles.styles[i]->styleName.isEmpty() ?
1397 styleStringHelper(allStyles.styles[i]->key.weight,
1398 (QFont::Style)allStyles.styles[i]->key.style) :
1399 allStyles.styles[i]->styleName);
1405 Returns true if the font that has family \a family and style \a
1406 style is fixed pitch; otherwise returns false.
1409 bool QFontDatabase::isFixedPitch(const QString &family,
1410 const QString &style) const
1414 QString familyName, foundryName;
1415 parseFontName(family, foundryName, familyName);
1417 QMutexLocker locker(fontDatabaseMutex());
1419 QT_PREPEND_NAMESPACE(load)(familyName);
1421 QtFontFamily *f = d->family(familyName);
1422 #if !defined(QWS) && defined(Q_OS_MAC)
1423 qt_mac_get_fixed_pitch(f);
1425 return (f && f->fixedPitch);
1429 Returns true if the font that has family \a family and style \a
1430 style is a scalable bitmap font; otherwise returns false. Scaling
1431 a bitmap font usually produces an unattractive hardly readable
1432 result, because the pixels of the font are scaled. If you need to
1433 scale a bitmap font it is better to scale it to one of the fixed
1434 sizes returned by smoothSizes().
1436 \sa isScalable(), isSmoothlyScalable()
1438 bool QFontDatabase::isBitmapScalable(const QString &family,
1439 const QString &style) const
1441 bool bitmapScalable = false;
1442 QString familyName, foundryName;
1443 parseFontName(family, foundryName, familyName);
1445 QMutexLocker locker(fontDatabaseMutex());
1447 QT_PREPEND_NAMESPACE(load)(familyName);
1449 QtFontStyle::Key styleKey(style);
1451 QtFontFamily *f = d->family(familyName);
1452 if (!f) return bitmapScalable;
1454 for (int j = 0; j < f->count; j++) {
1455 QtFontFoundry *foundry = f->foundries[j];
1456 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1457 for (int k = 0; k < foundry->count; k++)
1458 if ((style.isEmpty() ||
1459 foundry->styles[k]->styleName == style ||
1460 foundry->styles[k]->key == styleKey)
1461 && foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
1462 bitmapScalable = true;
1468 return bitmapScalable;
1473 Returns true if the font that has family \a family and style \a
1474 style is smoothly scalable; otherwise returns false. If this
1475 function returns true, it's safe to scale this font to any size,
1476 and the result will always look attractive.
1478 \sa isScalable(), isBitmapScalable()
1480 bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &style) const
1482 bool smoothScalable = false;
1483 QString familyName, foundryName;
1484 parseFontName(family, foundryName, familyName);
1486 QMutexLocker locker(fontDatabaseMutex());
1488 QT_PREPEND_NAMESPACE(load)(familyName);
1490 QtFontStyle::Key styleKey(style);
1492 QtFontFamily *f = d->family(familyName);
1493 if (!f) return smoothScalable;
1495 for (int j = 0; j < f->count; j++) {
1496 QtFontFoundry *foundry = f->foundries[j];
1497 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1498 for (int k = 0; k < foundry->count; k++)
1499 if ((style.isEmpty() ||
1500 foundry->styles[k]->styleName == style ||
1501 foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) {
1502 smoothScalable = true;
1508 return smoothScalable;
1512 Returns true if the font that has family \a family and style \a
1513 style is scalable; otherwise returns false.
1515 \sa isBitmapScalable(), isSmoothlyScalable()
1517 bool QFontDatabase::isScalable(const QString &family,
1518 const QString &style) const
1520 QMutexLocker locker(fontDatabaseMutex());
1521 if (isSmoothlyScalable(family, style))
1523 return isBitmapScalable(family, style);
1528 Returns a list of the point sizes available for the font that has
1529 family \a family and style \a style. The list may be empty.
1531 \sa smoothSizes(), standardSizes()
1533 QList<int> QFontDatabase::pointSizes(const QString &family,
1534 const QString &styleName)
1536 if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable())
1537 return standardSizes();
1539 bool smoothScalable = false;
1540 QString familyName, foundryName;
1541 parseFontName(family, foundryName, familyName);
1543 QMutexLocker locker(fontDatabaseMutex());
1545 QT_PREPEND_NAMESPACE(load)(familyName);
1547 QtFontStyle::Key styleKey(styleName);
1551 QtFontFamily *fam = d->family(familyName);
1552 if (!fam) return sizes;
1555 const int dpi = qt_defaultDpiY(); // embedded
1557 for (int j = 0; j < fam->count; j++) {
1558 QtFontFoundry *foundry = fam->foundries[j];
1559 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1560 QtFontStyle *style = foundry->style(styleKey, styleName);
1561 if (!style) continue;
1563 if (style->smoothScalable) {
1564 smoothScalable = true;
1567 for (int l = 0; l < style->count; l++) {
1568 const QtFontSize *size = style->pixelSizes + l;
1570 if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) {
1571 const uint pointSize = qRound(size->pixelSize * 72.0 / dpi);
1572 if (! sizes.contains(pointSize))
1573 sizes.append(pointSize);
1580 return standardSizes();
1587 Returns a QFont object that has family \a family, style \a style
1588 and point size \a pointSize. If no matching font could be created,
1589 a QFont object that uses the application's default font is
1592 QFont QFontDatabase::font(const QString &family, const QString &style,
1593 int pointSize) const
1595 QString familyName, foundryName;
1596 parseFontName(family, foundryName, familyName);
1598 QMutexLocker locker(fontDatabaseMutex());
1600 QT_PREPEND_NAMESPACE(load)(familyName);
1602 QtFontFoundry allStyles(foundryName);
1603 QtFontFamily *f = d->family(familyName);
1604 if (!f) return QGuiApplication::font();
1606 for (int j = 0; j < f->count; j++) {
1607 QtFontFoundry *foundry = f->foundries[j];
1608 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1609 for (int k = 0; k < foundry->count; k++)
1610 allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
1614 QtFontStyle::Key styleKey(style);
1615 QtFontStyle *s = bestStyle(&allStyles, styleKey, style);
1617 if (!s) // no styles found?
1618 return QGuiApplication::font();
1620 QFont fnt(family, pointSize, s->key.weight);
1621 fnt.setStyle((QFont::Style)s->key.style);
1622 if (!s->styleName.isEmpty())
1623 fnt.setStyleName(s->styleName);
1629 Returns the point sizes of a font that has family \a family and
1630 style \a style that will look attractive. The list may be empty.
1631 For non-scalable fonts and bitmap scalable fonts, this function
1632 is equivalent to pointSizes().
1634 \sa pointSizes(), standardSizes()
1636 QList<int> QFontDatabase::smoothSizes(const QString &family,
1637 const QString &styleName)
1639 if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable())
1640 return standardSizes();
1642 bool smoothScalable = false;
1643 QString familyName, foundryName;
1644 parseFontName(family, foundryName, familyName);
1646 QMutexLocker locker(fontDatabaseMutex());
1648 QT_PREPEND_NAMESPACE(load)(familyName);
1650 QtFontStyle::Key styleKey(styleName);
1654 QtFontFamily *fam = d->family(familyName);
1658 const int dpi = qt_defaultDpiY(); // embedded
1660 for (int j = 0; j < fam->count; j++) {
1661 QtFontFoundry *foundry = fam->foundries[j];
1662 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1663 QtFontStyle *style = foundry->style(styleKey, styleName);
1664 if (!style) continue;
1666 if (style->smoothScalable) {
1667 smoothScalable = true;
1670 for (int l = 0; l < style->count; l++) {
1671 const QtFontSize *size = style->pixelSizes + l;
1673 if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) {
1674 const uint pointSize = qRound(size->pixelSize * 72.0 / dpi);
1675 if (! sizes.contains(pointSize))
1676 sizes.append(pointSize);
1683 return QFontDatabase::standardSizes();
1691 Returns a list of standard font sizes.
1693 \sa smoothSizes(), pointSizes()
1695 QList<int> QFontDatabase::standardSizes()
1697 return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->standardSizes();
1702 Returns true if the font that has family \a family and style \a
1703 style is italic; otherwise returns false.
1705 \sa weight(), bold()
1707 bool QFontDatabase::italic(const QString &family, const QString &style) const
1709 QString familyName, foundryName;
1710 parseFontName(family, foundryName, familyName);
1712 QMutexLocker locker(fontDatabaseMutex());
1714 QT_PREPEND_NAMESPACE(load)(familyName);
1716 QtFontFoundry allStyles(foundryName);
1717 QtFontFamily *f = d->family(familyName);
1718 if (!f) return false;
1720 for (int j = 0; j < f->count; j++) {
1721 QtFontFoundry *foundry = f->foundries[j];
1722 if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1723 for (int k = 0; k < foundry->count; k++)
1724 allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
1728 QtFontStyle::Key styleKey(style);
1729 QtFontStyle *s = allStyles.style(styleKey, style);
1730 return s && s->key.style == QFont::StyleItalic;
1735 Returns true if the font that has family \a family and style \a
1736 style is bold; otherwise returns false.
1738 \sa italic(), weight()
1740 bool QFontDatabase::bold(const QString &family,
1741 const QString &style) const
1743 QString familyName, foundryName;
1744 parseFontName(family, foundryName, familyName);
1746 QMutexLocker locker(fontDatabaseMutex());
1748 QT_PREPEND_NAMESPACE(load)(familyName);
1750 QtFontFoundry allStyles(foundryName);
1751 QtFontFamily *f = d->family(familyName);
1752 if (!f) return false;
1754 for (int j = 0; j < f->count; j++) {
1755 QtFontFoundry *foundry = f->foundries[j];
1756 if (foundryName.isEmpty() ||
1757 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1758 for (int k = 0; k < foundry->count; k++)
1759 allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
1763 QtFontStyle::Key styleKey(style);
1764 QtFontStyle *s = allStyles.style(styleKey, style);
1765 return s && s->key.weight >= QFont::Bold;
1770 Returns the weight of the font that has family \a family and style
1771 \a style. If there is no such family and style combination,
1774 \sa italic(), bold()
1776 int QFontDatabase::weight(const QString &family,
1777 const QString &style) const
1779 QString familyName, foundryName;
1780 parseFontName(family, foundryName, familyName);
1782 QMutexLocker locker(fontDatabaseMutex());
1784 QT_PREPEND_NAMESPACE(load)(familyName);
1786 QtFontFoundry allStyles(foundryName);
1787 QtFontFamily *f = d->family(familyName);
1790 for (int j = 0; j < f->count; j++) {
1791 QtFontFoundry *foundry = f->foundries[j];
1792 if (foundryName.isEmpty() ||
1793 foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
1794 for (int k = 0; k < foundry->count; k++)
1795 allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
1799 QtFontStyle::Key styleKey(style);
1800 QtFontStyle *s = allStyles.style(styleKey, style);
1801 return s ? s->key.weight : -1;
1806 bool QFontDatabase::hasFamily(const QString &family) const
1808 QString parsedFamily, foundry;
1809 parseFontName(family, foundry, parsedFamily);
1810 const QString familyAlias = resolveFontFamilyAlias(parsedFamily);
1811 return families().contains(familyAlias, Qt::CaseInsensitive);
1816 Returns the names the \a writingSystem (e.g. for displaying to the
1819 QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
1821 const char *name = 0;
1822 switch (writingSystem) {
1824 name = QT_TRANSLATE_NOOP("QFontDatabase", "Any");
1827 name = QT_TRANSLATE_NOOP("QFontDatabase", "Latin");
1830 name = QT_TRANSLATE_NOOP("QFontDatabase", "Greek");
1833 name = QT_TRANSLATE_NOOP("QFontDatabase", "Cyrillic");
1836 name = QT_TRANSLATE_NOOP("QFontDatabase", "Armenian");
1839 name = QT_TRANSLATE_NOOP("QFontDatabase", "Hebrew");
1842 name = QT_TRANSLATE_NOOP("QFontDatabase", "Arabic");
1845 name = QT_TRANSLATE_NOOP("QFontDatabase", "Syriac");
1848 name = QT_TRANSLATE_NOOP("QFontDatabase", "Thaana");
1851 name = QT_TRANSLATE_NOOP("QFontDatabase", "Devanagari");
1854 name = QT_TRANSLATE_NOOP("QFontDatabase", "Bengali");
1857 name = QT_TRANSLATE_NOOP("QFontDatabase", "Gurmukhi");
1860 name = QT_TRANSLATE_NOOP("QFontDatabase", "Gujarati");
1863 name = QT_TRANSLATE_NOOP("QFontDatabase", "Oriya");
1866 name = QT_TRANSLATE_NOOP("QFontDatabase", "Tamil");
1869 name = QT_TRANSLATE_NOOP("QFontDatabase", "Telugu");
1872 name = QT_TRANSLATE_NOOP("QFontDatabase", "Kannada");
1875 name = QT_TRANSLATE_NOOP("QFontDatabase", "Malayalam");
1878 name = QT_TRANSLATE_NOOP("QFontDatabase", "Sinhala");
1881 name = QT_TRANSLATE_NOOP("QFontDatabase", "Thai");
1884 name = QT_TRANSLATE_NOOP("QFontDatabase", "Lao");
1887 name = QT_TRANSLATE_NOOP("QFontDatabase", "Tibetan");
1890 name = QT_TRANSLATE_NOOP("QFontDatabase", "Myanmar");
1893 name = QT_TRANSLATE_NOOP("QFontDatabase", "Georgian");
1896 name = QT_TRANSLATE_NOOP("QFontDatabase", "Khmer");
1898 case SimplifiedChinese:
1899 name = QT_TRANSLATE_NOOP("QFontDatabase", "Simplified Chinese");
1901 case TraditionalChinese:
1902 name = QT_TRANSLATE_NOOP("QFontDatabase", "Traditional Chinese");
1905 name = QT_TRANSLATE_NOOP("QFontDatabase", "Japanese");
1908 name = QT_TRANSLATE_NOOP("QFontDatabase", "Korean");
1911 name = QT_TRANSLATE_NOOP("QFontDatabase", "Vietnamese");
1914 name = QT_TRANSLATE_NOOP("QFontDatabase", "Symbol");
1917 name = QT_TRANSLATE_NOOP("QFontDatabase", "Ogham");
1920 name = QT_TRANSLATE_NOOP("QFontDatabase", "Runic");
1923 name = QT_TRANSLATE_NOOP("QFontDatabase", "N'Ko");
1926 Q_ASSERT_X(false, "QFontDatabase::writingSystemName", "invalid 'writingSystem' parameter");
1929 return QCoreApplication::translate("QFontDatabase", name);
1934 Returns a string with sample characters from \a writingSystem.
1936 QString QFontDatabase::writingSystemSample(WritingSystem writingSystem)
1939 switch (writingSystem) {
1942 // show only ascii characters
1943 sample += QLatin1String("AaBbzZ");
1946 // This is cheating... we only show latin-1 characters so that we don't
1947 // end up loading lots of fonts - at least on X11...
1948 sample = QLatin1String("Aa");
1949 sample += QChar(0x00C3);
1950 sample += QChar(0x00E1);
1951 sample += QLatin1String("Zz");
1954 sample += QChar(0x0393);
1955 sample += QChar(0x03B1);
1956 sample += QChar(0x03A9);
1957 sample += QChar(0x03C9);
1960 sample += QChar(0x0414);
1961 sample += QChar(0x0434);
1962 sample += QChar(0x0436);
1963 sample += QChar(0x044f);
1966 sample += QChar(0x053f);
1967 sample += QChar(0x054f);
1968 sample += QChar(0x056f);
1969 sample += QChar(0x057f);
1972 sample += QChar(0x05D0);
1973 sample += QChar(0x05D1);
1974 sample += QChar(0x05D2);
1975 sample += QChar(0x05D3);
1978 sample += QChar(0x0628);
1979 sample += QChar(0x0629);
1980 sample += QChar(0x062A);
1981 sample += QChar(0x063A);
1984 sample += QChar(0x0715);
1985 sample += QChar(0x0725);
1986 sample += QChar(0x0716);
1987 sample += QChar(0x0726);
1990 sample += QChar(0x0784);
1991 sample += QChar(0x0794);
1992 sample += QChar(0x078c);
1993 sample += QChar(0x078d);
1996 sample += QChar(0x0905);
1997 sample += QChar(0x0915);
1998 sample += QChar(0x0925);
1999 sample += QChar(0x0935);
2002 sample += QChar(0x0986);
2003 sample += QChar(0x0996);
2004 sample += QChar(0x09a6);
2005 sample += QChar(0x09b6);
2008 sample += QChar(0x0a05);
2009 sample += QChar(0x0a15);
2010 sample += QChar(0x0a25);
2011 sample += QChar(0x0a35);
2014 sample += QChar(0x0a85);
2015 sample += QChar(0x0a95);
2016 sample += QChar(0x0aa5);
2017 sample += QChar(0x0ab5);
2020 sample += QChar(0x0b06);
2021 sample += QChar(0x0b16);
2022 sample += QChar(0x0b2b);
2023 sample += QChar(0x0b36);
2026 sample += QChar(0x0b89);
2027 sample += QChar(0x0b99);
2028 sample += QChar(0x0ba9);
2029 sample += QChar(0x0bb9);
2032 sample += QChar(0x0c05);
2033 sample += QChar(0x0c15);
2034 sample += QChar(0x0c25);
2035 sample += QChar(0x0c35);
2038 sample += QChar(0x0c85);
2039 sample += QChar(0x0c95);
2040 sample += QChar(0x0ca5);
2041 sample += QChar(0x0cb5);
2044 sample += QChar(0x0d05);
2045 sample += QChar(0x0d15);
2046 sample += QChar(0x0d25);
2047 sample += QChar(0x0d35);
2050 sample += QChar(0x0d90);
2051 sample += QChar(0x0da0);
2052 sample += QChar(0x0db0);
2053 sample += QChar(0x0dc0);
2056 sample += QChar(0x0e02);
2057 sample += QChar(0x0e12);
2058 sample += QChar(0x0e22);
2059 sample += QChar(0x0e32);
2062 sample += QChar(0x0e8d);
2063 sample += QChar(0x0e9d);
2064 sample += QChar(0x0ead);
2065 sample += QChar(0x0ebd);
2068 sample += QChar(0x0f00);
2069 sample += QChar(0x0f01);
2070 sample += QChar(0x0f02);
2071 sample += QChar(0x0f03);
2074 sample += QChar(0x1000);
2075 sample += QChar(0x1001);
2076 sample += QChar(0x1002);
2077 sample += QChar(0x1003);
2080 sample += QChar(0x10a0);
2081 sample += QChar(0x10b0);
2082 sample += QChar(0x10c0);
2083 sample += QChar(0x10d0);
2086 sample += QChar(0x1780);
2087 sample += QChar(0x1790);
2088 sample += QChar(0x17b0);
2089 sample += QChar(0x17c0);
2091 case SimplifiedChinese:
2092 sample += QChar(0x4e2d);
2093 sample += QChar(0x6587);
2094 sample += QChar(0x8303);
2095 sample += QChar(0x4f8b);
2097 case TraditionalChinese:
2098 sample += QChar(0x4e2d);
2099 sample += QChar(0x6587);
2100 sample += QChar(0x7bc4);
2101 sample += QChar(0x4f8b);
2104 sample += QChar(0x30b5);
2105 sample += QChar(0x30f3);
2106 sample += QChar(0x30d7);
2107 sample += QChar(0x30eb);
2108 sample += QChar(0x3067);
2109 sample += QChar(0x3059);
2112 sample += QChar(0xac00);
2113 sample += QChar(0xac11);
2114 sample += QChar(0xac1a);
2115 sample += QChar(0xac2f);
2119 static const char vietnameseUtf8[] = {
2120 char(0xef), char(0xbb), char(0xbf), char(0xe1), char(0xbb), char(0x97),
2121 char(0xe1), char(0xbb), char(0x99),
2122 char(0xe1), char(0xbb), char(0x91),
2123 char(0xe1), char(0xbb), char(0x93),
2125 sample += QString::fromUtf8(vietnameseUtf8, sizeof(vietnameseUtf8));
2129 sample += QChar(0x1681);
2130 sample += QChar(0x1682);
2131 sample += QChar(0x1683);
2132 sample += QChar(0x1684);
2135 sample += QChar(0x16a0);
2136 sample += QChar(0x16a1);
2137 sample += QChar(0x16a2);
2138 sample += QChar(0x16a3);
2141 sample += QChar(0x7ca);
2142 sample += QChar(0x7cb);
2143 sample += QChar(0x7cc);
2144 sample += QChar(0x7cd);
2153 void QFontDatabase::parseFontName(const QString &name, QString &foundry, QString &family)
2155 QT_PREPEND_NAMESPACE(parseFontName)(name, foundry, family);
2158 void QFontDatabase::createDatabase()
2161 // used from qfontengine_ft.cpp
2162 Q_GUI_EXPORT QByteArray qt_fontdata_from_index(int index)
2164 QMutexLocker locker(fontDatabaseMutex());
2165 return privateDb()->applicationFonts.value(index).data;
2168 int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &fileName)
2170 QFontDatabasePrivate::ApplicationFont font;
2171 font.data = fontData;
2172 font.fileName = fileName;
2175 for (i = 0; i < applicationFonts.count(); ++i)
2176 if (applicationFonts.at(i).families.isEmpty())
2178 if (i >= applicationFonts.count()) {
2179 applicationFonts.append(ApplicationFont());
2180 i = applicationFonts.count() - 1;
2183 if (font.fileName.isEmpty() && !fontData.isEmpty())
2184 font.fileName = QString::fromLatin1(":qmemoryfonts/") + QString::number(i);
2186 registerFont(&font);
2187 if (font.families.isEmpty())
2190 applicationFonts[i] = font;
2196 bool QFontDatabasePrivate::isApplicationFont(const QString &fileName)
2198 for (int i = 0; i < applicationFonts.count(); ++i)
2199 if (applicationFonts.at(i).fileName == fileName)
2207 Loads the font from the file specified by \a fileName and makes it available to
2208 the application. An ID is returned that can be used to remove the font again
2209 with removeApplicationFont() or to retrieve the list of family names contained
2212 The function returns -1 if the font could not be loaded.
2214 Currently only TrueType fonts, TrueType font collections, and OpenType fonts are
2217 \note Adding application fonts on Unix/X11 platforms without fontconfig is
2218 currently not supported.
2220 \sa addApplicationFontFromData(), applicationFontFamilies(), removeApplicationFont()
2222 int QFontDatabase::addApplicationFont(const QString &fileName)
2225 if (!QFileInfo(fileName).isNativePath()) {
2227 if (!f.open(QIODevice::ReadOnly))
2231 QMutexLocker locker(fontDatabaseMutex());
2232 return privateDb()->addAppFont(data, fileName);
2238 Loads the font from binary data specified by \a fontData and makes it available to
2239 the application. An ID is returned that can be used to remove the font again
2240 with removeApplicationFont() or to retrieve the list of family names contained
2243 The function returns -1 if the font could not be loaded.
2245 Currently only TrueType fonts and TrueType font collections are supported.
2247 \b{Note:} Adding application fonts on Unix/X11 platforms without fontconfig is
2248 currently not supported.
2250 \sa addApplicationFont(), applicationFontFamilies(), removeApplicationFont()
2252 int QFontDatabase::addApplicationFontFromData(const QByteArray &fontData)
2254 QMutexLocker locker(fontDatabaseMutex());
2255 return privateDb()->addAppFont(fontData, QString() /* fileName */);
2261 Returns a list of font families for the given application font identified by
2264 \sa addApplicationFont(), addApplicationFontFromData()
2266 QStringList QFontDatabase::applicationFontFamilies(int id)
2268 QMutexLocker locker(fontDatabaseMutex());
2269 return privateDb()->applicationFonts.value(id).families;
2273 \fn bool QFontDatabase::removeApplicationFont(int id)
2276 Removes the previously loaded application font identified by \a
2277 id. Returns true if unloading of the font succeeded; otherwise
2280 \sa removeAllApplicationFonts(), addApplicationFont(),
2281 addApplicationFontFromData()
2285 \fn bool QFontDatabase::removeAllApplicationFonts()
2288 Removes all application-local fonts previously added using addApplicationFont()
2289 and addApplicationFontFromData().
2291 Returns true if unloading of the fonts succeeded; otherwise
2294 \sa removeApplicationFont(), addApplicationFont(), addApplicationFontFromData()
2298 \fn bool QFontDatabase::supportsThreadedFontRendering()
2301 Returns true if font rendering is supported outside the GUI
2302 thread, false otherwise. In other words, a return value of false
2303 means that all QPainter::drawText() calls outside the GUI thread
2304 will not produce readable output.
2306 \sa {Thread-Support in Qt Modules#Painting In Threads}{Painting In Threads}