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; }
static QFontEngine *loadWin(const QFontPrivate *d, int script, const QFontDef &req) { // list of families to try QStringList family_list = familyList(req); const char *stylehint = styleHint(d->request); if (stylehint) family_list << QLatin1String(stylehint); // append the default fallback font for the specified script // family_list << ... ; ########### // add the default family QString defaultFamily = QApplication::font().family(); if (! family_list.contains(defaultFamily)) family_list << defaultFamily; // add QFont::defaultFamily() to the list, for compatibility with // previous versions family_list << QApplication::font().defaultFamily(); // null family means find the first font matching the specified script family_list << QString(); QtFontDesc desc; QFontEngine *fe = 0; QList<int> blacklistedFamilies; while (!fe) { for (int i = 0; i < family_list.size(); ++i) { QString family, foundry; parseFontName(family_list.at(i), foundry, family); FM_DEBUG("loadWin: >>>>>>>>>>>>>>trying to match '%s'", family.toLatin1().data()); QT_PREPEND_NAMESPACE(match)(script, req, family, foundry, -1, &desc, blacklistedFamilies); if (desc.family) break; } if (!desc.family) break; fe = loadEngine(script, req, d->hdc, d->dpi, d->rawMode, &desc, family_list); if (!fe) blacklistedFamilies.append(desc.familyIndex); } return fe; }
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); }
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; }
void QFontDatabase::load(const QFontPrivate *d, int script) { QFontDef req = d->request; if (req.pixelSize == -1) { req.pixelSize = floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100; req.pixelSize = qRound(req.pixelSize); } if (req.pointSize < 0) req.pointSize = req.pixelSize*72.0/d->dpi; if (req.weight == 0) req.weight = QFont::Normal; if (req.stretch == 0) req.stretch = 100; QFontCache::Key key(req, script); 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); // list of families to try QStringList family_list; if (!req.family.isEmpty()) { family_list = familyList(req); // add the default family QString defaultFamily = QApplication::font().family(); if (! family_list.contains(defaultFamily)) family_list << defaultFamily; } // null family means find the first font matching the specified script family_list << QString(); QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd(); for (; !fe && it != end; ++it) { req.family = *it; fe = QFontDatabase::findFont(script, d, req); if (fe && (fe->type()==QFontEngine::Box) && !req.family.isEmpty()) fe = 0; } if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) { for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) { if (!d->engineData->engines[i]) { d->engineData->engines[i] = fe; fe->ref.ref(); } } } else { d->engineData->engines[script] = fe; fe->ref.ref(); } }