OSDN Git Service

use only special character to find font for scripts
authorIvailo Monev <xakepa10@gmail.com>
Thu, 20 Jan 2022 13:58:42 +0000 (15:58 +0200)
committerIvailo Monev <xakepa10@gmail.com>
Thu, 20 Jan 2022 13:58:42 +0000 (15:58 +0200)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
src/gui/text/qfontdatabase.cpp
src/gui/text/qfontdatabase.h
src/gui/text/qfontdatabase_x11_p.h

index dd2f49a..e1c9d59 100644 (file)
@@ -74,16 +74,9 @@ bool QtFontFamily::operator<(const QtFontFamily &other) const
     return (preference >= other.preference);
 }
 
-class QFontDatabasePrivate
-{
-public:
-#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
-    QString systemLang;
-#endif
-    QVector<QtFontFamily> families;
-};
+typedef QVector<QtFontFamily> QtFontFamilyList;
 
-Q_GLOBAL_STATIC(QFontDatabasePrivate, qGlobalFontDatabase)
+Q_GLOBAL_STATIC(QtFontFamilyList, qGlobalFontDatabase)
 Q_GLOBAL_STATIC(QMutex, qGlobalFontDatabaseMutex)
 
 /*!
@@ -224,7 +217,9 @@ static inline QString styleStringHelper(const QString &family, int weight, QFont
     }
 
     if (result.isEmpty()) {
-        foreach (const QtFontFamily &fontfamily, qGlobalFontDatabase()->families) {
+        const QtFontFamilyList* db = qGlobalFontDatabase();
+        for (int i = 0; i < db->size(); i++) {
+            const QtFontFamily &fontfamily = db->at(i);
             if (fontfamily.family.compare(family, Qt::CaseInsensitive) != 0) {
                 continue;
             }
@@ -320,8 +315,8 @@ QFontDatabase::QFontDatabase()
     {
         QMutexLocker locker(qGlobalFontDatabaseMutex());
 
-        d = qGlobalFontDatabase();
-        if (!d || d->families.size() > 0)
+        QtFontFamilyList* db = qGlobalFontDatabase();
+        if (!db || db->size() > 0)
             return;
 
 #ifndef QT_NO_FONTCONFIG
@@ -341,24 +336,14 @@ QFontDatabase::QFontDatabase()
                 "QFontDatabase", "New scripts have been added.");
 
         FcFontSet *fonts;
-
+        FcObjectSet *os = FcObjectSetCreate();
         FcPattern *pattern = FcPatternCreate();
-        FcDefaultSubstitute(pattern);
-        FcChar8 *lang = nullptr;
-        if (FcPatternGetString(pattern, FC_LANG, 0, &lang) == FcResultMatch)
-            d->systemLang = QString::fromUtf8((const char *) lang);
-        FcPatternDestroy(pattern);
-
-        {
-            FcObjectSet *os = FcObjectSetCreate();
-            FcPattern *pattern = FcPatternCreate();
-            for (qint16 i = 0; i < PatternPropertiesTblSize; i++) {
-                FcObjectSetAdd(os, PatternPropertiesTbl[i]);
-            }
-            fonts = FcFontList(0, pattern, os);
-            FcObjectSetDestroy(os);
-            FcPatternDestroy(pattern);
+        for (qint16 i = 0; i < PatternPropertiesTblSize; i++) {
+            FcObjectSetAdd(os, PatternPropertiesTbl[i]);
         }
+        fonts = FcFontList(0, pattern, os);
+        FcObjectSetDestroy(os);
+        FcPatternDestroy(pattern);
 
         for (int i = 0; i < fonts->nfont; i++) {
             FcChar8 *family_value = nullptr;
@@ -411,12 +396,12 @@ QFontDatabase::QFontDatabase()
                 fontfamily.preference += 800;
             }
 
-            d->families.append(fontfamily);
+            db->append(fontfamily);
         }
 
         FcFontSetDestroy(fonts);
 
-        qStableSort(d->families);
+        qStableSort(db->begin(), db->end());
 
 #ifdef QFONTDATABASE_DEBUG
         FD_DEBUG("QFontDatabase: loaded FontConfig: %d ms", int(elapsedtimer.elapsed()));
@@ -438,7 +423,9 @@ QStringList QFontDatabase::families() const
 {
     QStringList result;
     QMap<QString,QStringList> familieswithfoundry;
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         familieswithfoundry[fontfamily.family].append(fontfamily.foundry);
     }
     foreach (const QString &family, familieswithfoundry.keys()) {
@@ -473,7 +460,9 @@ QStringList QFontDatabase::styles(const QString &family) const
     parseFontName(family, parsedfoundry, parsedfamily);
 
     QStringList result;
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         if (fontfamily.family.compare(parsedfamily, Qt::CaseInsensitive) != 0
             || (!parsedfoundry.isEmpty() && fontfamily.foundry.compare(parsedfoundry, Qt::CaseInsensitive) != 0)) {
             continue;
@@ -495,7 +484,9 @@ bool QFontDatabase::isFixedPitch(const QString &family, const QString &style) co
     parseFontName(family, parsedfoundry, parsedfamily);
 
     bool result = false;
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         if (fontfamily.family.compare(parsedfamily, Qt::CaseInsensitive) != 0
             || (!parsedfoundry.isEmpty() && fontfamily.foundry.compare(parsedfoundry, Qt::CaseInsensitive) != 0)
             || (!style.isEmpty() && !isStyleMatch(fontfamily.style, style))) {
@@ -521,7 +512,9 @@ bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &sty
     parseFontName(family, parsedfoundry, parsedfamily);
 
     bool result = false;
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         if (fontfamily.family.compare(parsedfamily, Qt::CaseInsensitive) != 0
             || (!parsedfoundry.isEmpty() && fontfamily.foundry.compare(parsedfoundry, Qt::CaseInsensitive) != 0)
             || (!style.isEmpty() && !isStyleMatch(fontfamily.style, style))) {
@@ -558,7 +551,9 @@ QList<int> QFontDatabase::pointSizes(const QString &family, const QString &style
     parseFontName(family, parsedfoundry, parsedfamily);
 
     QList<int> result;
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         if (fontfamily.family.compare(parsedfamily, Qt::CaseInsensitive) != 0
             || (!parsedfoundry.isEmpty() && fontfamily.foundry.compare(parsedfoundry, Qt::CaseInsensitive) != 0)
             || !isStyleMatch(fontfamily.style, style)) {
@@ -584,7 +579,9 @@ QFont QFontDatabase::font(const QString &family, const QString &style,
     parseFontName(family, parsedfoundry, parsedfamily);
 
     QFont result = QApplication::font();
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         if (fontfamily.family.compare(parsedfamily, Qt::CaseInsensitive) != 0
             || (!parsedfoundry.isEmpty() && fontfamily.foundry.compare(parsedfoundry, Qt::CaseInsensitive) != 0)
             || !isStyleMatch(fontfamily.style, style)) {
@@ -615,7 +612,9 @@ QList<int> QFontDatabase::smoothSizes(const QString &family, const QString &styl
     parseFontName(family, parsedfoundry, parsedfamily);
 
     QList<int> result;
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         if (fontfamily.family.compare(parsedfamily, Qt::CaseInsensitive) != 0
             || (!parsedfoundry.isEmpty() && fontfamily.foundry.compare(parsedfoundry, Qt::CaseInsensitive) != 0)
             || !isStyleMatch(fontfamily.style, style)) {
@@ -671,7 +670,9 @@ bool QFontDatabase::italic(const QString &family, const QString &style) const
     parseFontName(family, parsedfoundry, parsedfamily);
 
     bool result = false;
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         if (fontfamily.family.compare(parsedfamily, Qt::CaseInsensitive) != 0
             || (!parsedfoundry.isEmpty() && fontfamily.foundry.compare(parsedfoundry, Qt::CaseInsensitive) != 0)
             || !isStyleMatch(fontfamily.style, style)) {
@@ -696,7 +697,9 @@ bool QFontDatabase::bold(const QString &family, const QString &style) const
     parseFontName(family, parsedfoundry, parsedfamily);
 
     bool result = false;
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         if (fontfamily.family.compare(parsedfamily, Qt::CaseInsensitive) != 0
             || (!parsedfoundry.isEmpty() && fontfamily.foundry.compare(parsedfoundry, Qt::CaseInsensitive) != 0)
             || !isStyleMatch(fontfamily.style, style)) {
@@ -722,7 +725,9 @@ int QFontDatabase::weight(const QString &family, const QString &style) const
     parseFontName(family, parsedfoundry, parsedfamily);
 
     int result = -1;
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         if (fontfamily.family.compare(parsedfamily, Qt::CaseInsensitive) != 0
             || (!parsedfoundry.isEmpty() && fontfamily.foundry.compare(parsedfoundry, Qt::CaseInsensitive) != 0)
             || !isStyleMatch(fontfamily.style, style)) {
@@ -747,7 +752,9 @@ bool QFontDatabase::hasFamily(const QString &family) const
     const QString familyalias = resolveFontFamilyAlias(parsedfamily);
 
     bool result = false;
-    foreach (const QtFontFamily &fontfamily, d->families) {
+    const QtFontFamilyList* db = qGlobalFontDatabase();
+    for (int i = 0; i < db->size(); i++) {
+        const QtFontFamily &fontfamily = db->at(i);
         if (fontfamily.family.compare(familyalias, Qt::CaseInsensitive) != 0
             || (!parsedfoundry.isEmpty() && fontfamily.foundry.compare(parsedfoundry, Qt::CaseInsensitive) != 0)) {
             continue;
@@ -785,4 +792,3 @@ bool QFontDatabase::supportsThreadedFontRendering()
 QT_END_NAMESPACE
 
 #include "moc_qfontdatabase.h"
-
index 7f4cd82..96cf134 100644 (file)
@@ -34,8 +34,6 @@ class QStringList;
 template <class T> class QList;
 class QFontEngine;
 
-class QFontDatabasePrivate;
-
 class Q_GUI_EXPORT QFontDatabase
 {
     Q_GADGET
@@ -74,8 +72,6 @@ private:
     friend class QFontPrivate;
     friend class QFontDialog;
     friend class QFontDialogPrivate;
-
-    QFontDatabasePrivate *d;
 };
 
 QT_END_NAMESPACE
index 755a407..8650d9a 100644 (file)
@@ -147,172 +147,6 @@ QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &request)
     return fontDef;
 }
 
-// values are from likelySubtags.xml distributed with Unicode CLDR data
-static const char *specialLanguagesTbl[] = {
-    "en", // Common
-    "ff-gn", // Adlam
-    "aho-in", // Ahom
-    "hlu-tr", // AnatolianHieroglyphs
-    "ar", // Arabic
-    "hy", // Armenian
-    "ae-ir", // Avestan
-    "ban-id", // Balinese
-    "bax-cm", // Bamum
-    "bsq-lr", // BassaVah
-    "bbc-id", // Batak
-    "bn", // Bengali
-    "sa-in", // Bhaiksuki
-    "zh-tw", // Bopomofo
-    "pka-in", // Brahmi
-    "fr-fr", // Braille
-    "bug-id", // Buginese
-    "bku-ph", // Buhid
-    "en-ca", // CanadianAboriginal
-    "xcr-tr", // Carian
-    "sq", // CaucasianAlbanian
-    "ccp-bd", // Chakma
-    "cjm-vn", // Cham
-    "chr-us", // Cherokee
-    "xco-uz", // Chorasmian
-    "cop-eg", // Coptic
-    "akk-iq", // Cuneiform
-    "grc-cy", // Cypriot
-    0, // CyproMinoan
-    "ru", // Cyrillic
-    0, // Deseret
-    "hi", // Devanagari
-    "dv-mv", // DivesAkuru
-    "doi-in", // Dogra
-    "fr-fr", // Duployan
-    "ar-eg", // EgyptianHieroglyphs
-    "sq-al", // Elbasan
-    "arc-ir", // Elymaic
-    0, // Ethiopic
-    "ka", // Georgian
-    "cu-bg", // Glagolitic
-    "got-ua", // Gothic
-    "sa-in", // Grantha
-    "el", // Greek
-    "gu", // Gujarati
-    "wsg-in", // GunjalaGondi
-    "pa", // Gurmukhi
-    "zh-tw", // Han
-    "ko", // Hangul
-    "rhg-mm", // HanifiRohingya
-    "hnn-ph", // Hanunoo
-    "mis-iq", // Hatran
-    "he", // Hebrew
-    "ja-jp", // Hiragana
-    "arc-ir", // ImperialAramaic
-    0, // Inherited
-    "pal-ir", // InscriptionalPahlavi
-    "xpr-ir", // InscriptionalParthian
-    "jv-id", // Javanese
-    "bho-in", // Kaithi
-    "kn", // Kannada
-    "ja-jp", // Katakana
-    "eky-mm", // KayahLi
-    "pra-pk", // Kharoshthi
-    "zkt-cn", // KhitanSmallScript
-    "km", // Khmer
-    "sd-in", // Khojki
-    "sd-in", // Khudawadi
-    "lo", // Lao
-    "la", // Latin
-    "lep-in", // Lepcha
-    "lif", // Limbu
-    "lab-gr", // LinearA
-    "lab-gr", // LinearB
-    "lis-cn", // Lisu
-    "xlc-tr", // Lycian
-    "xld-tr", // Lydian
-    "hi-in", // Mahajani
-    "mak-id", // Makasar
-    "ml", // Malayalam
-    "myz-ir", // Mandaic
-    "xmn-cn", // Manichaean
-    "bo-cn", // Marchen
-    "esg-in", // MasaramGondi
-    "mis-ng", // Medefaidrin
-    "mni-in", // MeeteiMayek
-    0, // MendeKikakui
-    "xmr-sd", // MeroiticCursive
-    "xmr-sd", // MeroiticHieroglyphs
-    "hmd-cn", // Miao
-    "mr-in", // Modi
-    "mn", // Mongolian
-    "mro-bd", // Mro
-    "skr-pk", // Multani
-    "my", // Myanmar
-    "arc-jo", // Nabataean
-    "sa-in", // Nandinagari
-    "new-np", // Newa
-    "khb-cn", // NewTaiLue
-    "nqo-gn", // Nko
-    "zhx-cn", // Nushu
-    "mww-us", // NyiakengPuachueHmong
-    "sga-ie", // Ogham
-    "sat-in", // OlChiki
-    "hu-hu", // OldHungarian
-    "ett-it", // OldItalic
-    "ar", // OldNorthArabian
-    "kv-ru", // OldPermic
-    "peo-ir", // OldPersian
-    "sog-uz", // OldSogdian
-    "ar", // OldSouthArabian
-    "otk-mn", // OldTurkic
-    "ug-cn", // OldUyghur
-    "or", // Oriya
-    "osa-us", // Osage
-    "so-so", // Osmanya
-    "hnj-la", // PahawhHmong
-    "arc-sy", // Palmyrene
-    "ctd-mm", // PauCinHau
-    "lzh-cn", // PhagsPa
-    "phn-lb", // Phoenician
-    "pal-cn", // PsalterPahlavi
-    "rej-id", // Rejang
-    "non-se", // Runic
-    "smp-il", // Samaritan
-    "saz-in", // Saurashtra
-    "sa-in", // Sharada
-    "en-gb", // Shavian
-    "sa-in", // Siddham
-    "ase-us", // SignWriting
-    "si", // Sinhala
-    "sog-uz", // Sogdian
-    "srb-in", // SoraSompeng
-    "cmg-mn", // Soyombo
-    "su-id", // Sundanese
-    "syl-bd", // SylotiNagri
-    "syr", // Syriac
-    "tl-ph", // Tagalog
-    "tbw-ph", // Tagbanwa
-    "tdd-cn", // TaiLe
-    0, // TaiTham
-    "blt-vn", // TaiViet
-    "doi-in", // Takri
-    "ta", // Tamil
-    "ntm-in", // Tangsa
-    "txg-cn", // Tangut
-    "te", // Telugu
-    "div", // Thaana
-    "th", // Thai
-    "bo", // Tibetan
-    0, // Tifinagh
-    "mai-in", // Tirhuta
-    "txo-in", // Toto
-    "uga-sy", // Ugaritic
-    "vai-lr", // Vai
-    "sq-al", // Vithkuqi
-    "npp-in", // Wancho
-    0, // WarangCiti
-    "ku-ge", // Yezidi
-    "yi", // Yi
-    "cmg-mn", // ZanabazarSquare
-};
-enum { SpecialLanguageCount = sizeof(specialLanguagesTbl) / sizeof(const char *) };
-
 // values obtained via genutf script
 static const uint specialCharsTbl[] = {
     0x0, // Common
@@ -504,15 +338,6 @@ static void qt_addPatternProps(FcPattern *pattern, int screen, QUnicodeTables::S
     FcPatternDel(pattern, FC_PIXEL_SIZE);
     FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);
 
-    if (script != QUnicodeTables::Common && specialLanguagesTbl[script]) {
-        Q_ASSERT(script < QUnicodeTables::ScriptCount);
-        FcLangSet *ls = FcLangSetCreate();
-        FcLangSetAdd(ls, (const FcChar8*)specialLanguagesTbl[script]);
-        FcPatternDel(pattern, FC_LANG);
-        FcPatternAddLangSet(pattern, FC_LANG, ls);
-        FcLangSetDestroy(ls);
-    }
-
     if (!request.styleName.isEmpty()) {
         QByteArray cs = request.styleName.toUtf8();
         FcPatternAddString(pattern, FC_STYLE, (const FcChar8 *) cs.constData());
@@ -622,17 +447,8 @@ static QFontEngine *tryPatternLoad(FcPattern *match, int screen,
         return nullptr;
 
     if (script != QUnicodeTables::Common) {
-        // skip font if it doesn't support the language we want
-        if (specialLanguagesTbl[script]){
-            FcLangSet *langSet = 0;
-            if (FcPatternGetLangSet(match, FC_LANG, 0, &langSet) != FcResultMatch)
-                goto special_char;
-            if (FcLangSetHasLang(langSet, (const FcChar8*)specialLanguagesTbl[script]) != FcLangEqual)
-                goto special_char;
-        }
-special_char:
+        // need to check the charset, as the langset doesn't work for some scripts
         if (specialCharsTbl[script]) {
-            // need to check the charset, as the langset doesn't work for some scripts
             FcCharSet *cs;
             if (FcPatternGetCharSet(match, FC_CHARSET, 0, &cs) != FcResultMatch)
                 return nullptr;