📄 qfontdatabase.cpp
字号:
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::Common, // Latin QUnicodeTables::Common, // Greek QUnicodeTables::Common, // Cyrillic QUnicodeTables::Common, // 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::Common, // 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 // Other};#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('['); int li = name.lastIndexOf(']'); if (i >= 0 && li >= 0 && i < li) { foundry = name.mid(i + 1, li - i - 1); if (name[i - 1] == ' ') 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;};static void match(int script, const QFontDef &request, const QString &family_name, const QString &foundry_name, int force_encoding_id, QtFontDesc *desc);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;}#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(','); for (int i = 0; i < list.size(); ++i) { QString str = list.at(i).trimmed(); if ((str.startsWith('"') && str.endsWith('"')) || (str.startsWith('\'') && str.endsWith('\''))) 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);#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){ int best = 0; int dist = 0xffff; for ( int i = 0; i < foundry->count; i++ ) { QtFontStyle *style = foundry->styles[i]; int d = qAbs( styleKey.weight - style->key.weight ); if ( styleKey.stretch != 0 && style->key.stretch != 0 ) { d += qAbs( styleKey.stretch - style->key.stretch ); } if (styleKey.style != style->key.style) { if (styleKey.style != QFont::StyleNormal && style->key.style != QFont::StyleNormal) // one is italic, the other oblique d += 0x0001; else d += 0x1000; } if ( d < dist ) { best = i; dist = d; } } FM_DEBUG( " best style has distance 0x%x", dist ); return foundry->styles[best];}#if defined(Q_WS_X11)static QtFontEncoding *findEncoding(int script, int styleStrategy, QtFontSize *size, int force_encoding_id){ QtFontEncoding *encoding = 0; if (force_encoding_id >= 0) { encoding = size->encodingID(force_encoding_id); if (!encoding) FM_DEBUG(" required encoding_id not available"); return encoding; } if (styleStrategy & (QFont::OpenGLCompatible | QFont::PreferBitmap)) { FM_DEBUG(" PreferBitmap and/or OpenGL set, skipping Freetype"); } else { encoding = size->encodingID(-1); // -1 == prefer Freetype if (encoding) return encoding; } // FT not available, find an XLFD font, trying the default encoding first encoding = size->encodingID(QFontPrivate::defaultEncodingID); if (encoding) { // does it support the requested script? bool supportsScript = false; for (int ws = 1; !supportsScript && ws < QFontDatabase::WritingSystemsCount; ++ws) { if (scriptForWritingSystem[ws] != script) continue; supportsScript = writingSystems_for_xlfd_encoding[encoding->encoding][ws]; } if (!supportsScript) encoding = 0; } // find the first encoding that supports the requested script for (int ws = 1; !encoding && ws < QFontDatabase::WritingSystemsCount; ++ws) { if (scriptForWritingSystem[ws] != script) continue; for (int x = 0; !encoding && x < size->count; ++x) { const int enc = size->encodings[x].encoding; if (writingSystems_for_xlfd_encoding[enc][ws]) encoding = size->encodings + x; } } return encoding;}#endif // Q_WS_X11staticunsigned int bestFoundry(int script, unsigned int score, int styleStrategy, const QtFontFamily *family, const QString &foundry_name, QtFontStyle::Key styleKey, int pixelSize, char pitch, QtFontDesc *desc, int force_encoding_id){ Q_UNUSED(force_encoding_id); Q_UNUSED(script); Q_UNUSED(pitch); desc->foundry = 0; desc->style = 0; desc->size = 0; desc->encoding = 0; FM_DEBUG(" REMARK: looking for best foundry for family '%s' [%d]", family->name.toLatin1().constData(), family->count); for (int x = 0; x < family->count; ++x) { QtFontFoundry *foundry = family->foundries[x]; if (!foundry_name.isEmpty() && ucstricmp(foundry->name, foundry_name) != 0) continue; FM_DEBUG(" looking for matching style in foundry '%s' %d", foundry->name.isEmpty() ? "-- none --" : foundry->name.toLatin1().constData(), foundry->count); QtFontStyle *style = bestStyle(foundry, styleKey); if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) { FM_DEBUG(" ForceOutline set, but not smoothly scalable"); continue; } int px = -1; QtFontSize *size = 0; // 1. see if we have an exact matching size if (!(styleStrategy & QFont::ForceOutline)) { size = style->pixelSize(pixelSize); if (size) { FM_DEBUG(" found exact size match (%d pixels)", size->pixelSize); px = size->pixelSize; } } // 2. see if we have a smoothly scalable font if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) { size = style->pixelSize(SMOOTH_SCALABLE); if (size) { FM_DEBUG(" found smoothly scalable font (%d pixels)", pixelSize); px = pixelSize; } } // 3. see if we have a bitmap scalable font if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) { size = style->pixelSize(0); if (size) { FM_DEBUG(" found bitmap scalable font (%d pixels)", pixelSize); px = pixelSize; } }#ifdef Q_WS_X11 QtFontEncoding *encoding = 0;#endif // 4. find closest size match if (! size) { unsigned int distance = ~0u; for (int x = 0; x < style->count; ++x) {#ifdef Q_WS_X11 encoding = findEncoding(script, styleStrategy, style->pixelSizes + x, force_encoding_id); if (!encoding) { FM_DEBUG(" size %3d does not support the script we want", style->pixelSizes[x].pixelSize); continue; }#endif unsigned int d; if (style->pixelSizes[x].pixelSize < pixelSize) { // penalize sizes that are smaller than the // requested size, due to truncation from floating // point to integer conversions d = pixelSize - style->pixelSizes[x].pixelSize + 1; } else { d = style->pixelSizes[x].pixelSize - pixelSize; } if (d < distance) { distance = d; size = style->pixelSizes + x; FM_DEBUG(" best size so far: %3d (%d)", size->pixelSize, pixelSize); } } if (!size) { FM_DEBUG(" no size supports the script we want"); continue; } if (style->bitmapScalable && ! (styleStrategy & QFont::PreferQuality) && (distance * 10 / pixelSize) >= 2) { // the closest size is not close enough, go ahead and // use a bitmap scaled font size = style->pixelSize(0); px = pixelSize; } else { px = size->pixelSize; } }#ifdef Q_WS_X11 if (size) { encoding = findEncoding(script, styleStrategy, size, force_encoding_id); if (!encoding) size = 0; } if (! encoding) { FM_DEBUG(" foundry doesn't support the script we want"); continue; }#endif // Q_WS_X11 unsigned int this_score = 0x0000; enum {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -