QT_BEGIN_NAMESPACE Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &foundryname, int weight, QFont::Style style, int stretch, bool antialiased, bool scalable, int pixelSize, const QSupportedWritingSystems &writingSystems, void *handle) { QFontDatabasePrivate *d = privateDb(); QtFontStyle::Key styleKey; styleKey.style = style; styleKey.weight = weight; styleKey.stretch = stretch; QtFontFamily *f = d->family(familyName, true); for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) { if (writingSystems.supported(QFontDatabase::WritingSystem(i))) { f->writingSystems[i] = QtFontFamily::Supported; } else { f->writingSystems[i] = QtFontFamily::Unsupported; } } QtFontFoundry *foundry = f->foundry(foundryname, true); QtFontStyle *fontStyle = foundry->style(styleKey, QString(), true); fontStyle->smoothScalable = scalable; fontStyle->antialiased = antialiased; QtFontSize *size = fontStyle->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true); size->handle = handle; }
static QFontEngine *loadEngine(int script, const QFontDef &request, QtFontFamily *family, QtFontFoundry *foundry, QtFontStyle *style, QtFontSize *size) { QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size); //make sure that the db has all fallback families if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) { if (family && !family->askedForFallback) { QFont::Style fontStyle = QFont::Style(style->key.style); QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint); if (styleHint == QFont::AnyStyle && request.fixedPitch) styleHint = QFont::TypeWriter; family->fallbackFamilies = fallbackFamilies(family->name,fontStyle,styleHint,QUnicodeTables::Script(script)); family->askedForFallback = true; } QStringList fallbacks = privateDb()->fallbackFamilies; if (family && !family->fallbackFamilies.isEmpty()) fallbacks = family->fallbackFamilies; engine = new QFontEngineMultiQPA(engine, script, fallbacks); } return engine; }
static QFontEngine *loadEngine(int script, const QFontDef &request, QtFontFamily *family, QtFontFoundry *foundry, QtFontStyle *style, QtFontSize *size) { QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size); //make sure that the db has all fallback families if (engine && engine->type() != QFontEngine::Multi && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) { if (family && !family->askedForFallback) { QFont::Style fontStyle = QFont::Style(style->key.style); QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint); if (styleHint == QFont::AnyStyle && request.fixedPitch) styleHint = QFont::TypeWriter; family->fallbackFamilies = fallbackFamilies(family->name,fontStyle,styleHint,QUnicodeTables::Script(script)); family->askedForFallback = true; } QStringList fallbacks = privateDb()->fallbackFamilies; if (family && !family->fallbackFamilies.isEmpty()) fallbacks = family->fallbackFamilies; engine = new QFontEngineMultiQPA(engine, script, fallbacks); // Cache Multi font engine as well in case we got the FT single // font engine when we are actually looking for a Multi one QFontCache::Key key(request, script, 1); QFontCache::instance()->instance()->insertEngine(key, engine); } return engine; }
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) { QFontDatabasePrivate *db = privateDb(); fnt->families = QApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName); db->reregisterAppFonts = true; }
bool QFontDatabase::removeAllApplicationFonts() { QFontDatabasePrivate *db = privateDb(); for(int i = 0; i < db->applicationFonts.count(); ++i) { if(!removeApplicationFont(i)) return false; } return true; }
static QFontEngine *loadFromDatabase(QFontDef &req, const QFontPrivate *d) { #if defined(QT_MAC_USE_COCOA) QCFString fontName = NULL; #else ATSFontFamilyRef familyRef = 0; ATSFontRef fontRef = 0; #endif QStringList family_list = familyList(req); const char *stylehint = styleHint(req); if (stylehint) family_list << QLatin1String(stylehint); // add QFont::defaultFamily() to the list, for compatibility with previous versions family_list << QApplication::font().defaultFamily(); QMutexLocker locker(fontDatabaseMutex()); QFontDatabasePrivate *db = privateDb(); if (!db->count) initializeDb(); for (int i = 0; i < family_list.size(); ++i) { for (int k = 0; k < db->count; ++k) { if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) { QByteArray family_name = db->families[k]->name.toUtf8(); #if defined(QT_MAC_USE_COCOA) QCFType<CTFontRef> ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL); if (ctFont) { fontName = CTFontCopyFullName(ctFont); goto found; } #else familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); if (familyRef) { fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); goto found; } #endif } } } found: #ifdef QT_MAC_USE_COCOA if (fontName) return new QCoreTextFontEngineMulti(fontName, req, d->kerning); #else if (familyRef) { QCFString actualName; if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr) req.family = actualName; return new QFontEngineMacMulti(familyRef, fontRef, req, d->kerning); } #endif return NULL; }
bool QFontDatabase::removeAllApplicationFonts() { QMutexLocker locker(fontDatabaseMutex()); QFontDatabasePrivate *db = privateDb(); for (int i = 0; i < db->applicationFonts.count(); ++i) if (!removeApplicationFont(i)) return false; return true; }
bool QFontDatabase::removeAllApplicationFonts() { QMutexLocker locker(fontDatabaseMutex()); QFontDatabasePrivate *db = privateDb(); if (db->applicationFonts.isEmpty()) return false; db->applicationFonts.clear(); db->invalidate(); return true; }
// called from qapplication_qws.cpp void qt_applyFontDatabaseSettings(const QSettings &settings) { initializeDb(); QFontDatabasePrivate *db = privateDb(); for (int i = 0; i < db->count; ++i) { QtFontFamily *family = db->families[i]; if (settings.contains(family->name)) family->fallbackFamilies = settings.value(family->name).toStringList(); } if (settings.contains(QLatin1String("Global Fallbacks"))) db->fallbackFamilies = settings.value(QLatin1String("Global Fallbacks")).toStringList(); }
void QFontDatabase::load(const QFontPrivate *d, int script) { // sanity checks if (!qApp) qWarning("QFontDatabase::load: Must construct QApplication first"); Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount); // normalize the request to get better caching QFontDef req = d->request; if (req.pixelSize <= 0) req.pixelSize = floor((100.0 * req.pointSize * d->dpi) / 72. + 0.5) / 100; if (req.pixelSize < 1) req.pixelSize = 1; if (req.weight == 0) req.weight = QFont::Normal; if (req.stretch == 0) req.stretch = 100; QFontCache::Key key(req, d->rawMode ? QUnicodeTables::Common : script, d->screen); if (!d->engineData) getEngineData(d, key); // the cached engineData could have already loaded the engine we want if (d->engineData->engines[script]) return; QFontEngine *fe = QFontCache::instance()->findEngine(key); // set it to the actual pointsize, so QFontInfo will do the right thing if (req.pointSize < 0) req.pointSize = req.pixelSize*72./d->dpi; if (!fe) { if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) { fe = new QTestFontEngine(req.pixelSize); fe->fontDef = req; } else { QMutexLocker locker(fontDatabaseMutex()); if (!privateDb()->count) initializeDb(); fe = loadWin(d, script, req); } if (!fe) { fe = new QFontEngineBox(req.pixelSize); fe->fontDef = QFontDef(); } } d->engineData->engines[script] = fe; fe->ref.ref(); QFontCache::instance()->insertEngine(key, fe); }
bool QFontDatabase::removeApplicationFont(int handle) { QMutexLocker locker(fontDatabaseMutex()); QFontDatabasePrivate *db = privateDb(); if (handle < 0 || handle >= db->applicationFonts.count()) return false; db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont(); db->reregisterAppFonts = true; db->invalidate(); return true; }
bool QFontDatabase::removeApplicationFont(int handle) { QFontDatabasePrivate *db = privateDb(); if(handle < 0 || handle >= db->applicationFonts.count()) return false; OSStatus e = ATSFontDeactivate(db->applicationFonts.at(handle).handle, /*iRefCon=*/0, kATSOptionFlagsDefault); if(e != noErr) return false; db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont(); db->invalidate(); return true; }
static void initializeDb() { QFontDatabasePrivate *db = privateDb(); // init by asking for the platformfontdb for the first time or after invalidation if (!db->count) QApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase(); if (db->reregisterAppFonts) { for (int i = 0; i < db->applicationFonts.count(); i++) { if (!db->applicationFonts.at(i).families.isEmpty()) registerFont(&db->applicationFonts[i]); } db->reregisterAppFonts = false; } }
bool QFontDatabase::removeApplicationFont(int handle) { QMutexLocker locker(fontDatabaseMutex()); QFontDatabasePrivate *db = privateDb(); if (handle < 0 || handle >= db->applicationFonts.count()) return false; const QFontDatabasePrivate::ApplicationFont font = db->applicationFonts.at(handle); db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont(); if (font.memoryFont) { #ifdef Q_OS_WINCE bool removeSucceeded = RemoveFontResource((LPCWSTR)font.fileName.utf16()); QFile tempfile(font.fileName); tempfile.remove(); if (!removeSucceeded) return false; #else PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx = (PtrRemoveFontMemResourceEx)QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); if (!ptrRemoveFontMemResourceEx || !ptrRemoveFontMemResourceEx(font.handle)) return false; #endif // Q_OS_WINCE } else { #ifdef Q_OS_WINCE if (!RemoveFontResource((LPCWSTR)font.fileName.utf16())) return false; #else PtrRemoveFontResourceExW ptrRemoveFontResourceExW = (PtrRemoveFontResourceExW)QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontResourceExW"); if (!ptrRemoveFontResourceExW || !ptrRemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0)) return false; #endif // Q_OS_WINCE } db->invalidate(); return true; }
static void initializeDb() { QFontDatabasePrivate *db = privateDb(); if (!db || db->count) return; populate_database(QString()); #ifdef QFONTDATABASE_DEBUG // print the database for (int f = 0; f < db->count; f++) { QtFontFamily *family = db->families[f]; qDebug(" %s: %p", qPrintable(family->name), family); populate_database(family->name); #if 0 qDebug(" scripts supported:"); for (int i = 0; i < QUnicodeTables::ScriptCount; i++) if(family->writingSystems[i] & QtFontFamily::Supported) qDebug(" %d", i); for (int fd = 0; fd < family->count; fd++) { QtFontFoundry *foundry = family->foundries[fd]; qDebug(" %s", foundry->name.latin1()); for (int s = 0; s < foundry->count; s++) { QtFontStyle *style = foundry->styles[s]; qDebug(" style: style=%d weight=%d smooth=%d", style->key.style, style->key.weight, style->smoothScalable ); if(!style->smoothScalable) { for(int i = 0; i < style->count; ++i) { qDebug(" %d", style->pixelSizes[i].pixelSize); } } } } #endif } #endif // QFONTDATABASE_DEBUG }
static QStringList fallbackFamilies(const QString &family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) { QStringList retList = QApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script); QFontDatabasePrivate *db = privateDb(); QStringList::iterator i; for (i = retList.begin(); i != retList.end(); ++i) { bool contains = false; for (int j = 0; j < db->count; j++) { QtFontFamily *qtFamily = db->families[j]; if (!(i->compare(qtFamily->name,Qt::CaseInsensitive))) { contains = true; break; } } if (!contains) { i = retList.erase(i); i--; } } return retList; }
static void initializeDb() { QFontDatabasePrivate *db = privateDb(); if(!db || db->count) return; #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0); if(!collection) return; QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection); if(!fonts) return; QString foundry_name = "CoreText"; const int numFonts = CFArrayGetCount(fonts); for(int i = 0; i < numFonts; ++i) { CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i); QCFString family_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute); QtFontFamily *family = db->family(family_name, true); for(int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) family->writingSystems[ws] = QtFontFamily::Supported; QtFontFoundry *foundry = family->foundry(foundry_name, true); QtFontStyle::Key styleKey; if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) { if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) { Q_ASSERT(CFNumberIsFloatType(weight)); double d; if(CFNumberGetValue(weight, kCFNumberDoubleType, &d)) { //qDebug() << "BOLD" << (QString)family_name << d; styleKey.weight = (d > 0.0) ? QFont::Bold : QFont::Normal; } } if(CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) { Q_ASSERT(CFNumberIsFloatType(italic)); double d; if(CFNumberGetValue(italic, kCFNumberDoubleType, &d)) { //qDebug() << "ITALIC" << (QString)family_name << d; if (d > 0.0) styleKey.style = QFont::StyleItalic; } } } QtFontStyle *style = foundry->style(styleKey, true); style->smoothScalable = true; if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) { //qDebug() << "WHEE"; int pixel_size=0; if(CFNumberIsFloatType(size)) { double d; CFNumberGetValue(size, kCFNumberDoubleType, &d); pixel_size = d; } else { CFNumberGetValue(size, kCFNumberIntType, &pixel_size); } //qDebug() << "SIZE" << (QString)family_name << pixel_size; if(pixel_size) style->pixelSize(pixel_size, true); } else { //qDebug() << "WTF?"; } } } else #endif { FMFontIterator it; if (!FMCreateFontIterator(0, 0, kFMUseGlobalScopeOption, &it)) { while (true) { FMFont fmFont; if (FMGetNextFont(&it, &fmFont) != noErr) break; FMFontFamily fmFamily; FMFontStyle fmStyle; QString familyName; QtFontStyle::Key styleKey; ATSFontRef atsFont = FMGetATSFontRefFromFont(fmFont); if (!FMGetFontFamilyInstanceFromFont(fmFont, &fmFamily, &fmStyle)) { { //sanity check the font, and see if we can use it at all! --Sam ATSUFontID fontID; if(ATSUFONDtoFontID(fmFamily, 0, &fontID) != noErr) continue; } if (fmStyle & ::italic) styleKey.style = QFont::StyleItalic; if (fmStyle & ::bold) styleKey.weight = QFont::Bold; ATSFontFamilyRef familyRef = FMGetATSFontFamilyRefFromFontFamily(fmFamily); QCFString cfFamilyName;; ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &cfFamilyName); familyName = cfFamilyName; } else { QCFString cfFontName; ATSFontGetName(atsFont, kATSOptionFlagsDefault, &cfFontName); familyName = cfFontName; quint16 macStyle = 0; { uchar data[4]; ByteCount len = 4; if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'e', 'a', 'd'), 44, 4, &data, &len) == noErr) macStyle = qFromBigEndian<quint16>(data); } if (macStyle & 1) styleKey.weight = QFont::Bold; if (macStyle & 2) styleKey.style = QFont::StyleItalic; } QtFontFamily *family = db->family(familyName, true); QtFontFoundry *foundry = family->foundry(QString(), true); QtFontStyle *style = foundry->style(styleKey, true); style->pixelSize(0, true); style->smoothScalable = true; initWritingSystems(family, atsFont); } FMDisposeFontIterator(&it); } } }
static inline void load(const QString & = QString(), int = -1) { // Only initialize the database if it has been cleared or not initialized yet if (!privateDb()->count) initializeDb(); }
void QFontDatabase::load(const QFontPrivate *d, int script) { // sanity checks if(!qApp) qWarning("QFont: Must construct a QApplication before a QFont"); Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount); Q_UNUSED(script); QFontDef req = d->request; req.pixelSize = qt_mac_pixelsize(req, d->dpi); // set the point size to 0 to get better caching req.pointSize = 0; QFontCache::Key key = QFontCache::Key(req, QUnicodeTables::Common, d->screen); if(!(d->engineData = QFontCache::instance()->findEngineData(key))) { d->engineData = new QFontEngineData; QFontCache::instance()->insertEngineData(key, d->engineData); } else { d->engineData->ref.ref(); } if(d->engineData->engine) // already loaded return; // set it to the actual pointsize, so QFontInfo will do the right thing req.pointSize = qRound(qt_mac_pointsize(d->request, d->dpi)); QFontEngine *e = QFontCache::instance()->findEngine(key); if(!e && qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) { e = new QTestFontEngine(req.pixelSize); e->fontDef = req; } if(e) { e->ref.ref(); d->engineData->engine = e; return; // the font info and fontdef should already be filled } //find the font QStringList family_list = familyList(req); const char *stylehint = styleHint(req); if (stylehint) family_list << QLatin1String(stylehint); // add QFont::defaultFamily() to the list, for compatibility with // previous versions family_list << QApplication::font().defaultFamily(); ATSFontFamilyRef familyRef = 0; ATSFontRef fontRef = 0; QMutexLocker locker(fontDatabaseMutex()); QFontDatabasePrivate *db = privateDb(); if (!db->count) initializeDb(); for(int i = 0; i < family_list.size(); ++i) { for (int k = 0; k < db->count; ++k) { if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) { QByteArray family_name = db->families[k]->name.toUtf8(); familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); if (familyRef) { fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); goto FamilyFound; } else { #if defined(QT_MAC_USE_COCOA) // ATS and CT disagrees on what the family name should be, // use CT to look up the font if ATS fails. QCFString familyName = QString::fromAscii(family_name); QCFType<CTFontRef> CTfontRef = CTFontCreateWithName(familyName, 12, NULL); QCFType<CTFontDescriptorRef> fontDescriptor = CTFontCopyFontDescriptor(CTfontRef); QCFString displayName = (CFStringRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontDisplayNameAttribute); familyRef = ATSFontFamilyFindFromName(displayName, kATSOptionFlagsDefault); if (familyRef) { fontRef = ATSFontFindFromName(displayName, kATSOptionFlagsDefault); goto FamilyFound; } #endif } } } } FamilyFound: //fill in the engine's font definition QFontDef fontDef = d->request; //copy.. if(fontDef.pointSize < 0) fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi); else fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi); #if 0 ItemCount name_count; if(ATSUCountFontNames(fontID, &name_count) == noErr && name_count) { ItemCount actualName_size; if(ATSUGetIndFontName(fontID, 0, 0, 0, &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) { QByteArray actualName(actualName_size); if(ATSUGetIndFontName(fontID, 0, actualName_size, actualName.data(), &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) fontDef.family = QString::fromUtf8(actualName); } } #else { QCFString actualName; if(ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr) fontDef.family = actualName; } #endif #ifdef QT_MAC_USE_COCOA QFontEngine *engine = new QCoreTextFontEngineMulti(familyRef, fontRef, fontDef, d->kerning); #elif 1 QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning); #else ATSFontFamilyRef atsFamily = familyRef; ATSFontFamilyRef atsFontRef = fontRef; FMFont fontID; FMFontFamily fmFamily; FMFontStyle fntStyle = 0; fmFamily = FMGetFontFamilyFromATSFontFamilyRef(atsFamily); if (fmFamily == kInvalidFontFamily) { // Use the ATSFont then... fontID = FMGetFontFromATSFontRef(atsFontRef); } else { if (fontDef.weight >= QFont::Bold) fntStyle |= ::bold; if (fontDef.style != QFont::StyleNormal) fntStyle |= ::italic; FMFontStyle intrinsicStyle; FMFont fnt = 0; if (FMGetFontFromFontFamilyInstance(fmFamily, fntStyle, &fnt, &intrinsicStyle) == noErr) fontID = FMGetATSFontRefFromFont(fnt); } OSStatus status; const int maxAttributeCount = 5; ATSUAttributeTag tags[maxAttributeCount + 1]; ByteCount sizes[maxAttributeCount + 1]; ATSUAttributeValuePtr values[maxAttributeCount + 1]; int attributeCount = 0; Fixed size = FixRatio(fontDef.pixelSize, 1); tags[attributeCount] = kATSUSizeTag; sizes[attributeCount] = sizeof(size); values[attributeCount] = &size; ++attributeCount; tags[attributeCount] = kATSUFontTag; sizes[attributeCount] = sizeof(fontID); values[attributeCount] = &fontID; ++attributeCount; CGAffineTransform transform = CGAffineTransformIdentity; if (fontDef.stretch != 100) { transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); tags[attributeCount] = kATSUFontMatrixTag; sizes[attributeCount] = sizeof(transform); values[attributeCount] = &transform; ++attributeCount; } ATSUStyle style; status = ATSUCreateStyle(&style); Q_ASSERT(status == noErr); Q_ASSERT(attributeCount < maxAttributeCount + 1); status = ATSUSetAttributes(style, attributeCount, tags, sizes, values); Q_ASSERT(status == noErr); QFontEngine *engine = new QFontEngineMac(style, fontID, fontDef, /*multiEngine*/ 0); ATSUDisposeStyle(style); #endif d->engineData->engine = engine; engine->ref.ref(); //a ref for the engineData->engine QFontCache::instance()->insertEngine(key, engine); }
/*! \internal */ QFontEngine * QFontDatabase::findFont(int script, const QFontPrivate *fp, const QFontDef &request) { QMutexLocker locker(fontDatabaseMutex()); const int force_encoding_id = -1; if (!privateDb()->count) initializeDb(); QFontEngine *engine; QFontCache::Key key(request, script); engine = QFontCache::instance()->findEngine(key); if (engine) { qDebug() << "Cache hit level 1"; return engine; } QString family_name, foundry_name; parseFontName(request.family, foundry_name, family_name); if (qt_enable_test_font && request.family == QLatin1String("__Qt__Box__Engine__")) { engine =new QTestFontEngine(request.pixelSize); engine->fontDef = request; } QtFontDesc desc; match(script, request, family_name, foundry_name, force_encoding_id, &desc); if (desc.family != 0 && desc.foundry != 0 && desc.style != 0) { engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size); } else { FM_DEBUG(" NO MATCH FOUND\n"); } if (engine) { initFontDef(desc, request, &engine->fontDef); if (fp) { QFontDef def = request; if (def.family.isEmpty()) { def.family = fp->request.family; def.family = def.family.left(def.family.indexOf(QLatin1Char(','))); } } } if (!engine) { if (!request.family.isEmpty()) { QStringList fallbacks = fallbackFamilies(request.family,QFont::Style(request.style),QFont::StyleHint(request.styleHint),QUnicodeTables::Script(script)); for (int i = 0; i < fallbacks.size(); i++) { QFontDef def = request; def.family = fallbacks.at(i); QFontCache::Key key(def,script); engine = QFontCache::instance()->findEngine(key); if (!engine) { QtFontDesc desc; match(script, def, def.family, QLatin1String(""), 0, &desc); if (desc.family == 0 && desc.foundry == 0 && desc.style == 0) { continue; } engine = loadEngine(script, def, desc.family, desc.foundry, desc.style, desc.size); if (engine) { initFontDef(desc, def, &engine->fontDef); break; } } } } if (!engine) engine = new QFontEngineBox(request.pixelSize); FM_DEBUG("returning box engine"); } if (fp && fp->dpi > 0) { engine->fontDef.pointSize = qreal(double((engine->fontDef.pixelSize * 72) / fp->dpi)); } else { engine->fontDef.pointSize = request.pointSize; } return engine; }
static void addFontToDatabase(QString familyName, const QString &scriptName, TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, int type) { const int script = -1; const QString foundryName; Q_UNUSED(script); bool italic = false; int weight; bool fixed; bool ttf; bool scalable; int size; // QString escript = QString::fromWCharArray(f->elfScript); // qDebug("script=%s", escript.latin1()); NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; italic = tm->tmItalic; weight = tm->tmWeight; // the "@family" fonts are just the same as "family". Ignore them. if (familyName[0] != QLatin1Char('@') && !familyName.startsWith(QLatin1String("WST_"))) { QtFontStyle::Key styleKey; styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal; styleKey.weight = weightFromInteger(weight); QtFontFamily *family = privateDb()->family(familyName, true); if(ttf && localizedName(familyName) && family->english_name.isEmpty()) family->english_name = getEnglishName(familyName); QtFontFoundry *foundry = family->foundry(foundryName, true); QtFontStyle *style = foundry->style(styleKey, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); // add fonts windows can generate for us: if (styleKey.weight <= QFont::DemiBold) { QtFontStyle::Key key(styleKey); key.weight = QFont::Bold; QtFontStyle *style = foundry->style(key, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); } if (styleKey.style != QFont::StyleItalic) { QtFontStyle::Key key(styleKey); key.style = QFont::StyleItalic; QtFontStyle *style = foundry->style(key, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); } if (styleKey.weight <= QFont::DemiBold && styleKey.style != QFont::StyleItalic) { QtFontStyle::Key key(styleKey); key.weight = QFont::Bold; key.style = QFont::StyleItalic; QtFontStyle *style = foundry->style(key, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); } family->fixedPitch = fixed; if (!family->writingSystemCheck && type & TRUETYPE_FONTTYPE) { quint32 unicodeRange[4] = { signature->fsUsb[0], signature->fsUsb[1], signature->fsUsb[2], signature->fsUsb[3] }; #ifdef Q_WS_WINCE if (signature->fsUsb[0] == 0) { // If the unicode ranges bit mask is zero then // EnumFontFamiliesEx failed to determine it properly. // In this case we just pretend that the font supports all languages. unicodeRange[0] = 0xbfffffff; // second most significant bit must be zero unicodeRange[1] = 0xffffffff; unicodeRange[2] = 0xffffffff; unicodeRange[3] = 0xffffffff; } #endif quint32 codePageRange[2] = { signature->fsCsb[0], signature->fsCsb[1] }; QList<QFontDatabase::WritingSystem> systems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange); for (int i = 0; i < systems.count(); ++i) { QFontDatabase::WritingSystem writingSystem = systems.at(i); // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains // the symbol for Baht, and Windows thus reports that it supports the Thai script. // Since it's the default UI font on this platform, most widgets will be unable to // display Thai text by default. As a temporary work around, we special case Segoe UI // and remove the Thai script from its list of supported writing systems. if (writingSystem != QFontDatabase::Thai || familyName != QLatin1String("Segoe UI")) family->writingSystems[writingSystem] = QtFontFamily::Supported; } } else if (!family->writingSystemCheck) { //qDebug("family='%s' script=%s", family->name.latin1(), script.latin1()); if (scriptName == QLatin1String("Western") || scriptName == QLatin1String("Baltic") || scriptName == QLatin1String("Central European") || scriptName == QLatin1String("Turkish") || scriptName == QLatin1String("Vietnamese")) family->writingSystems[QFontDatabase::Latin] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Thai")) family->writingSystems[QFontDatabase::Thai] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Symbol") || scriptName == QLatin1String("Other")) family->writingSystems[QFontDatabase::Symbol] = QtFontFamily::Supported; else if (scriptName == QLatin1String("OEM/Dos")) family->writingSystems[QFontDatabase::Latin] = QtFontFamily::Supported; else if (scriptName == QLatin1String("CHINESE_GB2312")) family->writingSystems[QFontDatabase::SimplifiedChinese] = QtFontFamily::Supported; else if (scriptName == QLatin1String("CHINESE_BIG5")) family->writingSystems[QFontDatabase::TraditionalChinese] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Cyrillic")) family->writingSystems[QFontDatabase::Cyrillic] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Hangul")) family->writingSystems[QFontDatabase::Korean] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Hebrew")) family->writingSystems[QFontDatabase::Hebrew] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Greek")) family->writingSystems[QFontDatabase::Greek] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Japanese")) family->writingSystems[QFontDatabase::Japanese] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Arabic")) family->writingSystems[QFontDatabase::Arabic] = QtFontFamily::Supported; } } }
static void populate_database(const QString& fam) { QFontDatabasePrivate *d = privateDb(); if (!d) return; QtFontFamily *family = 0; if(!fam.isEmpty()) { family = d->family(fam); if(family && family->loaded) return; } else if (d->count) { return; } HDC dummy = GetDC(0); LOGFONT lf; lf.lfCharSet = DEFAULT_CHARSET; if (fam.isNull()) { lf.lfFaceName[0] = 0; } else { memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded } lf.lfPitchAndFamily = 0; EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, (LPARAM)privateDb(), 0); ReleaseDC(0, dummy); for (int i = 0; i < d->applicationFonts.count(); ++i) { QFontDatabasePrivate::ApplicationFont fnt = d->applicationFonts.at(i); if (!fnt.memoryFont) continue; for (int j = 0; j < fnt.families.count(); ++j) { const QString familyName = fnt.families.at(j); HDC hdc = GetDC(0); LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE, familyName.size())); lf.lfCharSet = DEFAULT_CHARSET; HFONT hfont = CreateFontIndirect(&lf); HGDIOBJ oldobj = SelectObject(hdc, hfont); TEXTMETRIC textMetrics; GetTextMetrics(hdc, &textMetrics); addFontToDatabase(familyName, QString(), &textMetrics, &fnt.signatures.at(j), TRUETYPE_FONTTYPE); SelectObject(hdc, oldobj); DeleteObject(hfont); ReleaseDC(0, hdc); } } if(!fam.isEmpty()) { family = d->family(fam); if(family) { if(!family->writingSystemCheck) { } family->loaded = true; } } }
void QFontDatabase::load(const QFontPrivate *d, int script) { // sanity checks if(!QFontCache::instance) qWarning("QFont: Must construct a QApplication before a QFont"); Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount); Q_UNUSED(script); QFontDef req = d->request; req.pixelSize = qt_mac_pixelsize(req, d->dpi); // set the point size to 0 to get better caching req.pointSize = 0; QFontCache::Key key = QFontCache::Key(req, QUnicodeTables::Common, d->screen); if(!(d->engineData = QFontCache::instance->findEngineData(key))) { d->engineData = new QFontEngineData; QFontCache::instance->insertEngineData(key, d->engineData); } else { d->engineData->ref.ref(); } if(d->engineData->engine) // already loaded return; // set it to the actual pointsize, so QFontInfo will do the right thing req.pointSize = qRound(qt_mac_pointsize(d->request, d->dpi)); QFontEngine *e = QFontCache::instance->findEngine(key); if(!e && qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) { e = new QTestFontEngine(req.pixelSize); e->fontDef = req; } if(e) { Q_ASSERT(e->type() == QFontEngine::Multi || e->type() == QFontEngine::TestFontEngine); e->ref.ref(); d->engineData->engine = e; return; // the font info and fontdef should already be filled } //find the font QStringList family_list = req.family.split(QLatin1Char(',')); // append the substitute list for each family in family_list { QStringList subs_list; for(QStringList::ConstIterator it = family_list.begin(); it != family_list.end(); ++it) subs_list += QFont::substitutes(*it); family_list += subs_list; } const char *stylehint = styleHint(req); if (stylehint) family_list << QLatin1String(stylehint); // add QFont::defaultFamily() to the list, for compatibility with // previous versions family_list << QApplication::font().defaultFamily(); ATSFontFamilyRef familyRef = 0; ATSFontRef fontRef = 0; QFontDatabasePrivate *db = privateDb(); if (!db->count) initializeDb(); for(int i = 0; i < family_list.size(); ++i) { for (int k = 0; k < db->count; ++k) { if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) { QByteArray family_name = db->families[k]->name.toUtf8(); familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); if (familyRef) { fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); goto FamilyFound; } } } } FamilyFound: //fill in the engine's font definition QFontDef fontDef = d->request; //copy.. if(fontDef.pointSize < 0) fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi); else fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi); #if 0 ItemCount name_count; if(ATSUCountFontNames(fontID, &name_count) == noErr && name_count) { ItemCount actualName_size; if(ATSUGetIndFontName(fontID, 0, 0, 0, &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) { QByteArray actualName(actualName_size); if(ATSUGetIndFontName(fontID, 0, actualName_size, actualName.data(), &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) fontDef.family = QString::fromUtf8(actualName); } } #else { QCFString actualName; if(ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr) fontDef.family = actualName; } #endif QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning); d->engineData->engine = engine; engine->ref.ref(); //a ref for the engineData->engine QFontCache::instance->insertEngine(key, engine); }
static QFontEngine *loadEngine(int script, const QFontDef &request, HDC fontHdc, int dpi, bool rawMode, const QtFontDesc *desc, const QStringList &family_list) { LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); bool useDevice = (request.styleStrategy & QFont::PreferDevice) && fontHdc; HDC hdc = shared_dc(); QString font_name = desc != 0 ? desc->family->name : request.family; if (useDevice) { hdc = fontHdc; font_name = request.family; } bool stockFont = false; bool preferClearTypeAA = false; HFONT hfont = 0; #if !defined(QT_NO_DIRECTWRITE) bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting) || (request.hintingPreference == QFont::PreferVerticalHinting); IDWriteFont *directWriteFont = 0; #else bool useDirectWrite = false; #endif if (rawMode) { // will choose a stock font int f, deffnt = SYSTEM_FONT; QString fam = desc != 0 ? desc->family->name.toLower() : request.family.toLower(); if (fam == QLatin1String("default")) f = deffnt; else if (fam == QLatin1String("system")) f = SYSTEM_FONT; #ifndef Q_WS_WINCE else if (fam == QLatin1String("system_fixed")) f = SYSTEM_FIXED_FONT; else if (fam == QLatin1String("ansi_fixed")) f = ANSI_FIXED_FONT; else if (fam == QLatin1String("ansi_var")) f = ANSI_VAR_FONT; else if (fam == QLatin1String("device_default")) f = DEVICE_DEFAULT_FONT; else if (fam == QLatin1String("oem_fixed")) f = OEM_FIXED_FONT; #endif else if (fam[0] == QLatin1Char('#')) f = fam.right(fam.length()-1).toInt(); else f = deffnt; hfont = (HFONT)GetStockObject(f); if (!hfont) { qErrnoWarning("QFontEngine::loadEngine: GetStockObject failed"); hfont = systemFont(); } stockFont = true; } else { int hint = FF_DONTCARE; switch (request.styleHint) { case QFont::Helvetica: hint = FF_SWISS; break; case QFont::Times: hint = FF_ROMAN; break; case QFont::Courier: hint = FF_MODERN; break; case QFont::OldEnglish: hint = FF_DECORATIVE; break; case QFont::System: hint = FF_MODERN; break; default: break; } lf.lfHeight = -qRound(request.pixelSize); lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; if (desc == 0 || desc->style->key.weight == 50) lf.lfWeight = FW_DONTCARE; else lf.lfWeight = (desc->style->key.weight*900)/99; lf.lfItalic = (desc != 0 && desc->style->key.style != QFont::StyleNormal); lf.lfCharSet = DEFAULT_CHARSET; int strat = OUT_DEFAULT_PRECIS; if (request.styleStrategy & QFont::PreferBitmap) { strat = OUT_RASTER_PRECIS; #ifndef Q_WS_WINCE } else if (request.styleStrategy & QFont::PreferDevice) { strat = OUT_DEVICE_PRECIS; } else if (request.styleStrategy & QFont::PreferOutline) { strat = OUT_OUTLINE_PRECIS; } else if (request.styleStrategy & QFont::ForceOutline) { strat = OUT_TT_ONLY_PRECIS; #endif } lf.lfOutPrecision = strat; int qual = DEFAULT_QUALITY; if (request.styleStrategy & QFont::PreferMatch) qual = DRAFT_QUALITY; #ifndef Q_WS_WINCE else if (request.styleStrategy & QFont::PreferQuality) qual = PROOF_QUALITY; #endif if (request.styleStrategy & QFont::PreferAntialias) { if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP) { qual = CLEARTYPE_QUALITY; preferClearTypeAA = true; } else { qual = ANTIALIASED_QUALITY; } } else if (request.styleStrategy & QFont::NoAntialias) { qual = NONANTIALIASED_QUALITY; } lf.lfQuality = qual; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfPitchAndFamily = DEFAULT_PITCH | hint; QString fam = font_name; if(fam.isEmpty()) fam = QLatin1String("MS Sans Serif"); if ((fam == QLatin1String("MS Sans Serif")) && (request.style == QFont::StyleItalic || (-lf.lfHeight > 18 && -lf.lfHeight != 24))) { fam = QLatin1String("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale } if (fam == QLatin1String("Courier") && !(request.styleStrategy & QFont::PreferBitmap)) fam = QLatin1String("Courier New"); memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded hfont = CreateFontIndirect(&lf); if (!hfont) qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect failed"); stockFont = (hfont == 0); bool ttf = false; int avWidth = 0; BOOL res; HGDIOBJ oldObj = SelectObject(hdc, hfont); TEXTMETRIC tm; res = GetTextMetrics(hdc, &tm); avWidth = tm.tmAveCharWidth; ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE; SelectObject(hdc, oldObj); if (!ttf || !useDirectWrite) { useDirectWrite = false; if (hfont && (!ttf || request.stretch != 100)) { DeleteObject(hfont); if (!res) qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed"); lf.lfWidth = avWidth * request.stretch/100; hfont = CreateFontIndirect(&lf); if (!hfont) qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect with stretch failed"); } #ifndef Q_WS_WINCE if (hfont == 0) { hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); stockFont = true; } #else if (hfont == 0) { hfont = (HFONT)GetStockObject(SYSTEM_FONT); stockFont = true; } #endif } #if !defined(QT_NO_DIRECTWRITE) else { // Default to false for DirectWrite (and re-enable once/if everything // turns out okay) useDirectWrite = false; QFontDatabasePrivate *db = privateDb(); if (db->directWriteFactory == 0) { HRESULT hr = DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&db->directWriteFactory) ); if (FAILED(hr)) { qErrnoWarning("QFontEngine::loadEngine: DWriteCreateFactory failed"); } else { hr = db->directWriteFactory->GetGdiInterop(&db->directWriteGdiInterop); if (FAILED(hr)) qErrnoWarning("QFontEngine::loadEngine: GetGdiInterop failed"); } } if (db->directWriteGdiInterop != 0) { QString nameSubstitute = fontNameSubstitute(QString::fromWCharArray(lf.lfFaceName)); memcpy(lf.lfFaceName, nameSubstitute.utf16(), sizeof(wchar_t) * qMin(nameSubstitute.length() + 1, LF_FACESIZE)); HRESULT hr = db->directWriteGdiInterop->CreateFontFromLOGFONT( &lf, &directWriteFont); if (FAILED(hr)) { #ifndef QT_NO_DEBUG qErrnoWarning("QFontEngine::loadEngine: CreateFontFromLOGFONT failed " "for %ls (0x%lx)", lf.lfFaceName, hr); #endif } else { DeleteObject(hfont); useDirectWrite = true; } } } #endif } QFontEngine *fe = 0; if (!useDirectWrite) { QFontEngineWin *few = new QFontEngineWin(font_name, hfont, stockFont, lf); if (preferClearTypeAA) few->glyphFormat = QFontEngineGlyphCache::Raster_RGBMask; // Also check for OpenType tables when using complex scripts // ### TODO: This only works for scripts that require OpenType. More generally // for scripts that do not require OpenType we should just look at the list of // supported writing systems in the font's OS/2 table. if (scriptRequiresOpenType(script)) { HB_Face hbFace = few->harfbuzzFace(); if (!hbFace || !hbFace->supported_scripts[script]) { FM_DEBUG(" OpenType support missing for script\n"); delete few; return 0; } } initFontInfo(few, request, fontHdc, dpi); fe = few; } #if !defined(QT_NO_DIRECTWRITE) else { QFontDatabasePrivate *db = privateDb(); IDWriteFontFace *directWriteFontFace = NULL; HRESULT hr = directWriteFont->CreateFontFace(&directWriteFontFace); if (SUCCEEDED(hr)) { QFontEngineDirectWrite *fedw = new QFontEngineDirectWrite(db->directWriteFactory, directWriteFontFace, request.pixelSize); initFontInfo(fedw, request, dpi, directWriteFont); fe = fedw; } else { qErrnoWarning(hr, "QFontEngine::loadEngine: CreateFontFace failed"); } } if (directWriteFont != 0) directWriteFont->Release(); #endif if(script == QUnicodeTables::Common && !(request.styleStrategy & QFont::NoFontMerging) && desc != 0 && !(desc->family->writingSystems[QFontDatabase::Symbol] & QtFontFamily::Supported)) { if(!tryFonts) { LANGID lid = GetUserDefaultLangID(); switch( lid&0xff ) { case LANG_CHINESE: // Chinese (Taiwan) if ( lid == 0x0804 ) // Taiwan tryFonts = ch_TW_tryFonts; else tryFonts = ch_CN_tryFonts; break; case LANG_JAPANESE: tryFonts = jp_tryFonts; break; case LANG_KOREAN: tryFonts = kr_tryFonts; break; default: tryFonts = other_tryFonts; break; } } QStringList fm = QFontDatabase().families(); QStringList list = family_list; const char **tf = tryFonts; while(tf && *tf) { if(fm.contains(QLatin1String(*tf))) list << QLatin1String(*tf); ++tf; } QFontEngine *mfe = new QFontEngineMultiWin(fe, list); mfe->fontDef = fe->fontDef; fe = mfe; } return fe; }
static QFontEngine *loadFromDatabase(QFontDef &req, const QFontPrivate *d) { #if defined(QT_MAC_USE_COCOA) QCFString fontName = NULL; #else ATSFontFamilyRef familyRef = 0; ATSFontRef fontRef = 0; #endif QStringList family_list = familyList(req); const char *stylehint = styleHint(req); if (stylehint) family_list << QLatin1String(stylehint); // add QFont::defaultFamily() to the list, for compatibility with previous versions family_list << QApplication::font().defaultFamily(); QMutexLocker locker(fontDatabaseMutex()); QFontDatabasePrivate *db = privateDb(); if (!db->count) initializeDb(); for (int i = 0; i < family_list.size(); ++i) { for (int k = 0; k < db->count; ++k) { if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) { #if defined(QT_MAC_USE_COCOA) CFStringRef familyName = QCFString::toCFStringRef(db->families[k]->name); QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes( QCFType<CFDictionaryRef>(CFDictionaryCreate(kCFAllocatorDefault, (const void**)&kCTFontFamilyNameAttribute, (const void**)&familyName, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks))); CFRelease(familyName); QCFType<CTFontRef> ctFont = CTFontCreateWithFontDescriptor(descriptor, 0, NULL); if (ctFont) { fontName = CTFontCopyFullName(ctFont); goto found; } #else familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); if (familyRef) { fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); goto found; } #endif } } } found: #ifdef QT_MAC_USE_COCOA if (fontName) return new QCoreTextFontEngineMulti(fontName, req, d->kerning); #else if (familyRef) { QCFString actualName; if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr) req.family = actualName; return new QFontEngineMacMulti(familyRef, fontRef, req, d->kerning); } #endif return NULL; }