From c76a6fe2c4f7e2e92ea0fe02b1e635c529db8a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 22 Jan 2014 13:41:26 +0100 Subject: Teach CoreText font db to handle application font files with multiple fonts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ATS code path already did this, by enumerating all the fonts in the resolved collection. The CoreText code path assumed that registering a font URL would only add a single font. We now use CTFontManagerRegisterFontsForURL to enumerate all fonts that were added. This functionality is not available for fonts based on a data provider. As part of implementing the patch the code was simplified to re-use logic between the different ways of resolving font descriptors from a file or byte array. Change-Id: I6eb15df939d03dc588a87e46f39bd54e56b50643 Reviewed-by: Tor Arne Vestbø --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 126 ++++++++++----------- 1 file changed, 59 insertions(+), 67 deletions(-) (limited to 'src/platformsupport') diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 1b468b3eff..460870f56a 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -477,99 +477,91 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo #ifdef Q_OS_MACX QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) { + QCFType fonts; + QStringList families; + #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { - CTFontRef font = NULL; - + CFErrorRef error = 0; if (!fontData.isEmpty()) { QByteArray* fontDataCopy = new QByteArray(fontData); QCFType dataProvider = CGDataProviderCreateWithData(fontDataCopy, fontDataCopy->constData(), fontDataCopy->size(), releaseFontData); - CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider); + QCFType cgFont = CGFontCreateWithDataProvider(dataProvider); if (cgFont) { - CFErrorRef error; - bool success = CTFontManagerRegisterGraphicsFont(cgFont, &error); - if (success) { - font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL); + if (CTFontManagerRegisterGraphicsFont(cgFont, &error)) { + CFMutableArrayRef singleFontArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + QCFType font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL); + CFArrayAppendValue(singleFontArray, QCFType(CTFontCopyFontDescriptor(font))); + fonts = singleFontArray; m_applicationFonts.append(QVariant::fromValue(QCFType::constructFromGet(cgFont))); - } else { - NSLog(@"Unable to register font: %@", error); - CFRelease(error); } - CGFontRelease(cgFont); } } else { - CFErrorRef error; QCFType fontURL = CFURLCreateWithFileSystemPath(NULL, QCFString(fileName), kCFURLPOSIXPathStyle, false); - bool success = CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error); - if (success) { - const void *keys[] = { kCTFontURLAttribute }; - const void *values[] = { fontURL }; - QCFType attributes = CFDictionaryCreate(NULL, keys, values, 1, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - QCFType descriptor = CTFontDescriptorCreateWithAttributes(attributes); - font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL); + if (CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error)) { + fonts = CTFontManagerCreateFontDescriptorsFromURL(fontURL); m_applicationFonts.append(QVariant::fromValue(QCFType::constructFromGet(fontURL))); - } else { - NSLog(@"Unable to register font: %@", error); - CFRelease(error); } } - if (font) { - QStringList families; - families.append(QCFString(CTFontCopyFamilyName(font))); - - QCFType descriptor = CTFontCopyFontDescriptor(font); - populateFromDescriptor(descriptor); - - CFRelease(font); - return families; + if (error) { + NSLog(@"Unable to register font: %@", error); + CFRelease(error); } } else #endif { - ATSFontContainerRef fontContainer; - OSStatus e; - - if (!fontData.isEmpty()) { - e = ATSFontActivateFromMemory((void *) fontData.constData(), fontData.size(), - kATSFontContextLocal, kATSFontFormatUnspecified, NULL, - kATSOptionFlagsDefault, &fontContainer); - } else { - FSRef ref; - OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref); - if (qt_mac_create_fsref(fileName, &ref) != noErr) - return QStringList(); - e = ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0, - kATSOptionFlagsDefault, &fontContainer); - } + ATSFontContainerRef fontContainer; + OSStatus e; - if (e == noErr) { - ItemCount fontCount = 0; - e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, 0, 0, &fontCount); - if (e != noErr) - return QStringList(); - - QVarLengthArray containedFonts(fontCount); - e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount); - if (e != noErr) - return QStringList(); - - QStringList families; - for (int i = 0; i < containedFonts.size(); ++i) { - QCFType font = CTFontCreateWithPlatformFont(containedFonts[i], 12.0, NULL, NULL); - QCFType descriptor = CTFontCopyFontDescriptor(font); - populateFromDescriptor(descriptor); - families.append(QCFString(CTFontCopyFamilyName(font))); + if (!fontData.isEmpty()) { + e = ATSFontActivateFromMemory((void *) fontData.constData(), fontData.size(), + kATSFontContextLocal, kATSFontFormatUnspecified, NULL, + kATSOptionFlagsDefault, &fontContainer); + } else { + FSRef ref; + OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref); + if (qt_mac_create_fsref(fileName, &ref) != noErr) + return QStringList(); + e = ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0, + kATSOptionFlagsDefault, &fontContainer); } - m_applicationFonts.append(QVariant::fromValue(fontContainer)); - return families; + if (e == noErr) { + ItemCount fontCount = 0; + e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, 0, 0, &fontCount); + if (e != noErr) + return QStringList(); + + QVarLengthArray containedFonts(fontCount); + e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount); + if (e != noErr) + return QStringList(); + + CFMutableArrayRef fontsArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + for (int i = 0; i < containedFonts.size(); ++i) { + QCFType font = CTFontCreateWithPlatformFont(containedFonts[i], 12.0, NULL, NULL); + CFArrayAppendValue(fontsArray, QCFType(CTFontCopyFontDescriptor(font))); + } + + fonts = fontsArray; + + m_applicationFonts.append(QVariant::fromValue(fontContainer)); + } } + + if (fonts) { + const int numFonts = CFArrayGetCount(fonts); + for (int i = 0; i < numFonts; ++i) { + CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i)); + populateFromDescriptor(fontDescriptor); + QCFType familyName = CFStringRef(CTFontDescriptorCopyLocalizedAttribute(fontDescriptor, kCTFontFamilyNameAttribute, NULL)); + families.append(QCFString(familyName)); + } } - return QStringList(); + return families; } #endif -- cgit v1.2.3