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>
This commit is contained in:
parent
5173589b79
commit
c76a6fe2c4
@ -477,99 +477,91 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
|
|||||||
#ifdef Q_OS_MACX
|
#ifdef Q_OS_MACX
|
||||||
QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
|
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 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
|
||||||
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
|
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
|
||||||
CTFontRef font = NULL;
|
CFErrorRef error = 0;
|
||||||
|
|
||||||
if (!fontData.isEmpty()) {
|
if (!fontData.isEmpty()) {
|
||||||
QByteArray* fontDataCopy = new QByteArray(fontData);
|
QByteArray* fontDataCopy = new QByteArray(fontData);
|
||||||
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy,
|
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy,
|
||||||
fontDataCopy->constData(), fontDataCopy->size(), releaseFontData);
|
fontDataCopy->constData(), fontDataCopy->size(), releaseFontData);
|
||||||
CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider);
|
QCFType<CGFontRef> cgFont = CGFontCreateWithDataProvider(dataProvider);
|
||||||
if (cgFont) {
|
if (cgFont) {
|
||||||
CFErrorRef error;
|
if (CTFontManagerRegisterGraphicsFont(cgFont, &error)) {
|
||||||
bool success = CTFontManagerRegisterGraphicsFont(cgFont, &error);
|
CFMutableArrayRef singleFontArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
|
||||||
if (success) {
|
QCFType<CTFontRef> font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
|
||||||
font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
|
CFArrayAppendValue(singleFontArray, QCFType<CTFontDescriptorRef>(CTFontCopyFontDescriptor(font)));
|
||||||
|
fonts = singleFontArray;
|
||||||
m_applicationFonts.append(QVariant::fromValue(QCFType<CGFontRef>::constructFromGet(cgFont)));
|
m_applicationFonts.append(QVariant::fromValue(QCFType<CGFontRef>::constructFromGet(cgFont)));
|
||||||
} else {
|
|
||||||
NSLog(@"Unable to register font: %@", error);
|
|
||||||
CFRelease(error);
|
|
||||||
}
|
}
|
||||||
CGFontRelease(cgFont);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CFErrorRef error;
|
|
||||||
QCFType<CFURLRef> fontURL = CFURLCreateWithFileSystemPath(NULL, QCFString(fileName), kCFURLPOSIXPathStyle, false);
|
QCFType<CFURLRef> fontURL = CFURLCreateWithFileSystemPath(NULL, QCFString(fileName), kCFURLPOSIXPathStyle, false);
|
||||||
bool success = CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error);
|
if (CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error)) {
|
||||||
if (success) {
|
fonts = CTFontManagerCreateFontDescriptorsFromURL(fontURL);
|
||||||
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);
|
|
||||||
m_applicationFonts.append(QVariant::fromValue(QCFType<CFURLRef>::constructFromGet(fontURL)));
|
m_applicationFonts.append(QVariant::fromValue(QCFType<CFURLRef>::constructFromGet(fontURL)));
|
||||||
} else {
|
|
||||||
NSLog(@"Unable to register font: %@", error);
|
|
||||||
CFRelease(error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (font) {
|
if (error) {
|
||||||
QStringList families;
|
NSLog(@"Unable to register font: %@", error);
|
||||||
families.append(QCFString(CTFontCopyFamilyName(font)));
|
CFRelease(error);
|
||||||
|
|
||||||
QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
|
|
||||||
populateFromDescriptor(descriptor);
|
|
||||||
|
|
||||||
CFRelease(font);
|
|
||||||
return families;
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ATSFontContainerRef fontContainer;
|
ATSFontContainerRef fontContainer;
|
||||||
OSStatus e;
|
OSStatus e;
|
||||||
|
|
||||||
if (!fontData.isEmpty()) {
|
if (!fontData.isEmpty()) {
|
||||||
e = ATSFontActivateFromMemory((void *) fontData.constData(), fontData.size(),
|
e = ATSFontActivateFromMemory((void *) fontData.constData(), fontData.size(),
|
||||||
kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
|
kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
|
||||||
kATSOptionFlagsDefault, &fontContainer);
|
kATSOptionFlagsDefault, &fontContainer);
|
||||||
} else {
|
} else {
|
||||||
FSRef ref;
|
FSRef ref;
|
||||||
OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref);
|
OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref);
|
||||||
if (qt_mac_create_fsref(fileName, &ref) != noErr)
|
if (qt_mac_create_fsref(fileName, &ref) != noErr)
|
||||||
return QStringList();
|
return QStringList();
|
||||||
e = ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0,
|
e = ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0,
|
||||||
kATSOptionFlagsDefault, &fontContainer);
|
kATSOptionFlagsDefault, &fontContainer);
|
||||||
}
|
|
||||||
|
|
||||||
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)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_applicationFonts.append(QVariant::fromValue(fontContainer));
|
if (e == noErr) {
|
||||||
return families;
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QStringList();
|
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 families;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user