📄 qfontdatabase.cpp
字号:
// see the Unicode subset bitfields in the MSDN docsstatic int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = { // Any, { 127, 127 }, // Latin, { 0, 127 }, // Greek, { 7, 127 }, // Cyrillic, { 9, 127 }, // Armenian, { 10, 127 }, // Hebrew, { 11, 127 }, // Arabic, { 13, 127 }, // Syriac, { 71, 127 }, //Thaana, { 72, 127 }, //Devanagari, { 15, 127 }, //Bengali, { 16, 127 }, //Gurmukhi, { 17, 127 }, //Gujarati, { 18, 127 }, //Oriya, { 19, 127 }, //Tamil, { 20, 127 }, //Telugu, { 21, 127 }, //Kannada, { 22, 127 }, //Malayalam, { 23, 127 }, //Sinhala, { 73, 127 }, //Thai, { 24, 127 }, //Lao, { 25, 127 }, //Tibetan, { 70, 127 }, //Myanmar, { 74, 127 }, // Georgian, { 26, 127 }, // Khmer, { 80, 127 }, // SimplifiedChinese, { 126, 127 }, // TraditionalChinese, { 126, 127 }, // Japanese, { 126, 127 }, // Korean, { 56, 127 }, // Vietnamese, { 0, 127 }, // same as latin1 // Other, { 126, 127 }};#define SimplifiedChineseCsbBit 18#define TraditionalChineseCsbBit 20#define JapaneseCsbBit 17#define KoreanCsbBit 21static QList<QFontDatabase::WritingSystem> determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2]){ QList<QFontDatabase::WritingSystem> writingSystems; bool hasScript = false; int i; for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) { int bit = requiredUnicodeBits[i][0]; int index = bit/32; int flag = 1 << (bit&31); if (bit != 126 && unicodeRange[index] & flag) { bit = requiredUnicodeBits[i][1]; index = bit/32; flag = 1 << (bit&31); if (bit == 127 || unicodeRange[index] & flag) { writingSystems.append(QFontDatabase::WritingSystem(i)); hasScript = true; // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i); } } } if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) { writingSystems.append(QFontDatabase::SimplifiedChinese); hasScript = true; //qDebug("font %s supports Simplified Chinese", familyName.latin1()); } if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) { writingSystems.append(QFontDatabase::TraditionalChinese); hasScript = true; //qDebug("font %s supports Traditional Chinese", familyName.latin1()); } if(codePageRange[0] & (1 << JapaneseCsbBit)) { writingSystems.append(QFontDatabase::Japanese); hasScript = true; //qDebug("font %s supports Japanese", familyName.latin1()); } if(codePageRange[0] & (1 << KoreanCsbBit)) { writingSystems.append(QFontDatabase::Korean); hasScript = true; //qDebug("font %s supports Korean", familyName.latin1()); } if (!hasScript) writingSystems.append(QFontDatabase::Symbol); return writingSystems;}#endifclass QFontDatabasePrivate : public QObject{ Q_OBJECTpublic: QFontDatabasePrivate() : count(0), families(0), reregisterAppFonts(false)#if defined(Q_WS_QWS) , stream(0)#endif { } ~QFontDatabasePrivate() { free(); } QtFontFamily *family(const QString &f, bool = false); void free() { while (count--) delete families[count]; ::free(families); families = 0; count = 0; // don't clear the memory fonts! } int count; QtFontFamily **families; struct ApplicationFont { QString fileName; QByteArray data;#if defined(Q_OS_WIN) HANDLE handle; bool memoryFont;#elif defined(Q_WS_MAC) ATSFontContainerRef handle;#endif QStringList families; }; QVector<ApplicationFont> applicationFonts; int addAppFont(const QByteArray &fontData, const QString &fileName); bool reregisterAppFonts; bool isApplicationFont(const QString &fileName); void invalidate();#if defined(Q_WS_QWS) bool loadFromCache(const QString &fontPath); void addFont(const QString &familyname, const char *foundryname, int weight, bool italic, int pixelSize, const QByteArray &file, int fileIndex, bool antialiased, const QList<QFontDatabase::WritingSystem> &writingSystems = QList<QFontDatabase::WritingSystem>()); void addQPF2File(const QByteArray &file);#ifndef QT_NO_FREETYPE QStringList addTTFile(const QByteArray &file, const QByteArray &fontData = QByteArray());#endif QDataStream *stream; QStringList fallbackFamilies;#endifQ_SIGNALS: void fontDatabaseChanged();};void QFontDatabasePrivate::invalidate(){ if (QFontCache::instance) QFontCache::instance->clear(); free(); emit fontDatabaseChanged();}QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create){ int low = 0; int high = count; int pos = count / 2; int res = 1; if (count) { while ((res = families[pos]->name.compare(f, Qt::CaseInsensitive)) && pos != low) { if (res > 0) high = pos; else low = pos; pos = (high + low) / 2; }; if (!res) return families[pos]; } if (!create) return 0; if (res < 0) pos++; // qDebug("adding family %s at %d total=%d", f.latin1(), pos, count); if (!(count % 8)) families = (QtFontFamily **) realloc(families, (((count+8) >> 3) << 3) * sizeof(QtFontFamily *)); memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *)); families[pos] = new QtFontFamily(f); count++; return families[pos];}static const int scriptForWritingSystem[] = { QUnicodeTables::Common, // Any QUnicodeTables::Latin, // Latin QUnicodeTables::Greek, // Greek QUnicodeTables::Cyrillic, // Cyrillic QUnicodeTables::Armenian, // Armenian QUnicodeTables::Hebrew, // Hebrew QUnicodeTables::Arabic, // Arabic QUnicodeTables::Syriac, // Syriac QUnicodeTables::Thaana, // Thaana QUnicodeTables::Devanagari, // Devanagari QUnicodeTables::Bengali, // Bengali QUnicodeTables::Gurmukhi, // Gurmukhi QUnicodeTables::Gujarati, // Gujarati QUnicodeTables::Oriya, // Oriya QUnicodeTables::Tamil, // Tamil QUnicodeTables::Telugu, // Telugu QUnicodeTables::Kannada, // Kannada QUnicodeTables::Malayalam, // Malayalam QUnicodeTables::Sinhala, // Sinhala QUnicodeTables::Thai, // Thai QUnicodeTables::Lao, // Lao QUnicodeTables::Tibetan, // Tibetan QUnicodeTables::Myanmar, // Myanmar QUnicodeTables::Georgian, // Georgian QUnicodeTables::Khmer, // Khmer QUnicodeTables::Common, // SimplifiedChinese QUnicodeTables::Common, // TraditionalChinese QUnicodeTables::Common, // Japanese QUnicodeTables::Hangul, // Korean QUnicodeTables::Common, // Vietnamese QUnicodeTables::Common, // Yi QUnicodeTables::Common, // Tagalog QUnicodeTables::Common, // Hanunoo QUnicodeTables::Common, // Buhid QUnicodeTables::Common, // Tagbanwa QUnicodeTables::Common, // Limbu QUnicodeTables::Common, // TaiLe QUnicodeTables::Common, // Braille QUnicodeTables::Common, // Symbol QUnicodeTables::Ogham, // Ogham QUnicodeTables::Runic // Runic};#if defined Q_WS_QWS || (defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG))static inline bool requiresOpenType(int writingSystem){ return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala) || writingSystem == QFontDatabase::Khmer);}static inline bool scriptRequiresOpenType(int script){ return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala) || script == QUnicodeTables::Khmer);}#endif/*! \internal This makes sense of the font family name: if the family name contains a '[' and a ']', then we take the text between the square brackets as the foundry, and the text before the square brackets as the family (ie. "Arial [Monotype]")*/static void parseFontName(const QString &name, QString &foundry, QString &family){ int i = name.indexOf(QLatin1Char('[')); int li = name.lastIndexOf(QLatin1Char(']')); if (i >= 0 && li >= 0 && i < li) { foundry = name.mid(i + 1, li - i - 1); if (i > 0 && name[i - 1] == QLatin1Char(' ')) i--; family = name.left(i); } else { foundry.clear(); family = name; } // capitalize the family/foundry names bool space = true; QChar *s = family.data(); int len = family.length(); while(len--) { if (space) *s = s->toUpper(); space = s->isSpace(); ++s; } space = true; s = foundry.data(); len = foundry.length(); while(len--) { if (space) *s = s->toUpper(); space = s->isSpace(); ++s; }}struct QtFontDesc{ inline QtFontDesc() : family(0), foundry(0), style(0), size(0), encoding(0) {} QtFontFamily *family; QtFontFoundry *foundry; QtFontStyle *style; QtFontSize *size; QtFontEncoding *encoding;};#if !defined(Q_WS_MAC)static void match(int script, const QFontDef &request, const QString &family_name, const QString &foundry_name, int force_encoding_id, QtFontDesc *desc);#if defined(Q_WS_X11) || defined(Q_WS_QWS)static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef){ fontDef->family = desc.family->name; if (! desc.foundry->name.isEmpty()) { fontDef->family += QString::fromLatin1(" ["); fontDef->family += desc.foundry->name; fontDef->family += QString::fromLatin1("]"); } if (desc.style->smoothScalable) fontDef->pixelSize = request.pixelSize; else if ((desc.style->bitmapScalable && (request.styleStrategy & QFont::PreferMatch))) fontDef->pixelSize = request.pixelSize; else fontDef->pixelSize = desc.size->pixelSize; fontDef->styleHint = request.styleHint; fontDef->styleStrategy = request.styleStrategy; fontDef->weight = desc.style->key.weight; fontDef->style = desc.style->key.style; fontDef->fixedPitch = desc.family->fixedPitch; fontDef->stretch = desc.style->key.stretch; fontDef->ignorePitch = false;}#endif#endif#if defined(Q_WS_X11) || defined(Q_WS_WIN)static void getEngineData(const QFontPrivate *d, const QFontCache::Key &key){ // look for the requested font in the engine data cache d->engineData = QFontCache::instance->findEngineData(key); if (!d->engineData) { // create a new one d->engineData = new QFontEngineData; QFontCache::instance->insertEngineData(key, d->engineData); } else { d->engineData->ref.ref(); }}static QStringList familyList(const QFontDef &req){ // list of families to try QStringList family_list; if (req.family.isEmpty()) return family_list; QStringList list = req.family.split(QLatin1Char(',')); for (int i = 0; i < list.size(); ++i) { QString str = list.at(i).trimmed(); if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"'))) || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\'')))) str = str.mid(1, str.length() - 2); family_list << str; } // append the substitute list for each family in family_list QStringList subs_list; QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd(); for (; it != end; ++it) subs_list += QFont::substitutes(*it);// qDebug() << "adding substs: " << subs_list; family_list += subs_list; return family_list;}#endifQ_GLOBAL_STATIC(QFontDatabasePrivate, privateDb)// used in qfontcombobox.cppQObject *qt_fontdatabase_private(){ return privateDb();}#define SMOOTH_SCALABLE 0xffff#if defined(Q_WS_X11)# include "qfontdatabase_x11.cpp"#elif defined(Q_WS_MAC)# include "qfontdatabase_mac.cpp"#elif defined(Q_WS_WIN)# include "qfontdatabase_win.cpp"#elif defined(Q_WS_QWS)# include "qfontdatabase_qws.cpp"#endifstatic QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -