diff options
author | Tor Arne Vestbø <torarnv@gmail.com> | 2014-01-22 13:41:26 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-25 03:04:49 +0100 |
commit | c76a6fe2c4f7e2e92ea0fe02b1e635c529db8a12 (patch) | |
tree | c2a27f35395599427e1c9c85408c7926f2863db2 | |
parent | 5173589b795560c2042d06d191ac86ad61f24e51 (diff) |
Teach CoreText font db to handle application font files with multiple fonts
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ø <tor.arne.vestbo@digia.com>
-rw-r--r-- | src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm | 126 |
1 files changed, 59 insertions, 67 deletions
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<CFArrayRef> 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<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy, fontDataCopy->constData(), fontDataCopy->size(), releaseFontData); - CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider); + QCFType<CGFontRef> 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<CTFontRef> font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL); + CFArrayAppendValue(singleFontArray, QCFType<CTFontDescriptorRef>(CTFontCopyFontDescriptor(font))); + fonts = singleFontArray; m_applicationFonts.append(QVariant::fromValue(QCFType<CGFontRef>::constructFromGet(cgFont))); - } else { - NSLog(@"Unable to register font: %@", error); - CFRelease(error); } - CGFontRelease(cgFont); } } else { - CFErrorRef error; QCFType<CFURLRef> fontURL = CFURLCreateWithFileSystemPath(NULL, QCFString(fileName), kCFURLPOSIXPathStyle, false); - bool success = CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error); - if (success) { - const void *keys[] = { kCTFontURLAttribute }; - const void *values[] = { fontURL }; - QCFType<CFDictionaryRef> attributes = CFDictionaryCreate(NULL, keys, values, 1, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes); - font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL); + if (CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error)) { + fonts = CTFontManagerCreateFontDescriptorsFromURL(fontURL); m_applicationFonts.append(QVariant::fromValue(QCFType<CFURLRef>::constructFromGet(fontURL))); - } else { - NSLog(@"Unable to register font: %@", error); - CFRelease(error); } } - if (font) { - QStringList families; - families.append(QCFString(CTFontCopyFamilyName(font))); - - QCFType<CTFontDescriptorRef> 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<ATSFontRef> 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<CTFontRef> font = CTFontCreateWithPlatformFont(containedFonts[i], 12.0, NULL, NULL); - QCFType<CTFontDescriptorRef> 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<ATSFontRef> 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<CTFontRef> font = CTFontCreateWithPlatformFont(containedFonts[i], 12.0, NULL, NULL); + CFArrayAppendValue(fontsArray, QCFType<CTFontDescriptorRef>(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<CFStringRef> familyName = CFStringRef(CTFontDescriptorCopyLocalizedAttribute(fontDescriptor, kCTFontFamilyNameAttribute, NULL)); + families.append(QCFString(familyName)); + } } - return QStringList(); + return families; } #endif |