summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2017-03-20 19:31:29 +0100
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2017-04-11 09:23:44 +0000
commit5ad2e1cea1b2c08950c91174840f542806954d99 (patch)
treee75b656caa2451c8070a8e516809b162481307a6
parent17fc188aec5806167d3c6165b0ad299a8d2a6bcf (diff)
Populate application fonts via font descriptors on Apple platforms
Instead of registering the font via CTFontManagerRegister we just create a font descriptor for the data/URL and populate that like normal system fonts. This makes the code more similar to how we deal with other fonts, shaves off a ms during font registration due to not registering the font, and fixes an issue on iOS where CTFontManagerRegister would invalidate earlier populated system font descriptors. Task-number: QTBUG-56765 Change-Id: I002a65075b15837c9a2d22573020d4c834111837 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm71
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h7
2 files changed, 22 insertions, 56 deletions
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index ce9b61ba4c..d0b28b856b 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -199,10 +199,6 @@ static CFArrayRef availableFamilyNames()
void QCoreTextFontDatabase::populateFontDatabase()
{
- // The caller (QFontDB) expects the db to be populate only with system fonts, so we need
- // to make sure that any previously registered app fonts become invisible.
- removeApplicationFonts();
-
QCFType<CFArrayRef> familyNames = availableFamilyNames();
const int numberOfFamilies = CFArrayGetCount(familyNames);
for (int i = 0; i < numberOfFamilies; ++i) {
@@ -585,21 +581,19 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
}
template <>
-CFArrayRef QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::createDescriptorArrayForFont(CTFontRef font, const QString &fileName)
+CFArrayRef QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName)
{
Q_UNUSED(fileName)
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
CFArrayAppendValue(array, descriptor);
return array;
}
#ifndef QT_NO_FREETYPE
template <>
-CFArrayRef QCoreTextFontDatabaseEngineFactory<QFontEngineFT>::createDescriptorArrayForFont(CTFontRef font, const QString &fileName)
+CFArrayRef QCoreTextFontDatabaseEngineFactory<QFontEngineFT>::createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName)
{
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
// The physical font source URL (usually a local file or Qt resource) is only required for
// FreeType, when using non-system fonts, and needs some hackery to attach in a format
@@ -630,44 +624,36 @@ CFArrayRef QCoreTextFontDatabaseEngineFactory<QFontEngineFT>::createDescriptorAr
QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{
QCFType<CFArrayRef> fonts;
- QStringList families;
- CFErrorRef error = 0;
if (!fontData.isEmpty()) {
QByteArray* fontDataCopy = new QByteArray(fontData);
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy,
fontDataCopy->constData(), fontDataCopy->size(), releaseFontData);
- QCFType<CGFontRef> cgFont = CGFontCreateWithDataProvider(dataProvider);
- if (cgFont) {
- if (CTFontManagerRegisterGraphicsFont(cgFont, &error)) {
- QCFType<CTFontRef> font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
- fonts = createDescriptorArrayForFont(font, fileName);
- m_applicationFonts.append(QVariant::fromValue(QCFType<CGFontRef>::constructFromGet(cgFont)));
- }
+ if (QCFType<CGFontRef> cgFont = CGFontCreateWithDataProvider(dataProvider)) {
+ QCFType<CTFontRef> ctFont = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
+ QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(ctFont);
+ fonts = createDescriptorArrayForDescriptor(descriptor, fileName);
}
} else {
- QCFType<CFURLRef> fontURL = CFURLCreateWithFileSystemPath(NULL, QCFString(fileName), kCFURLPOSIXPathStyle, false);
- if (CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error)) {
- fonts = CTFontManagerCreateFontDescriptorsFromURL(fontURL);
- m_applicationFonts.append(QVariant::fromValue(QCFType<CFURLRef>::constructFromGet(fontURL)));
- }
+ QCFType<CFURLRef> fontURL = QUrl::fromLocalFile(fileName).toCFURL();
+ fonts = CTFontManagerCreateFontDescriptorsFromURL(fontURL);
}
- if (error) {
- NSLog(@"Unable to register font: %@", error);
- CFRelease(error);
- }
+ if (!fonts)
+ 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(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute));
- families.append(QCFString(familyName));
- }
+ QStringList families;
+ const int numFonts = CFArrayGetCount(fonts);
+ for (int i = 0; i < numFonts; ++i) {
+ CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i));
+ populateFromDescriptor(fontDescriptor);
+ QCFType<CFStringRef> familyName = CFStringRef(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute));
+ families.append(QString::fromCFString(familyName));
}
+ // Note: We don't do font matching via CoreText for application fonts, so we don't
+ // need to enable font matching for them via CTFontManagerEnableFontDescriptors.
+
return families;
}
@@ -846,22 +832,5 @@ QList<int> QCoreTextFontDatabase::standardSizes() const
return ret;
}
-void QCoreTextFontDatabase::removeApplicationFonts()
-{
- if (m_applicationFonts.isEmpty())
- return;
-
- for (const QVariant &font : qAsConst(m_applicationFonts)) {
- CFErrorRef error;
- if (font.canConvert(qMetaTypeId<QCFType<CGFontRef> >())) {
- CTFontManagerUnregisterGraphicsFont(font.value<QCFType<CGFontRef> >(), &error);
- } else if (font.canConvert(qMetaTypeId<QCFType<CFURLRef> >())) {
- CTFontManagerUnregisterFontsForURL(font.value<QCFType<CFURLRef> >(), kCTFontManagerScopeProcess, &error);
- }
- }
-
- m_applicationFonts.clear();
-}
-
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index 8edf60b5fa..11ea0bea02 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -91,13 +91,10 @@ public:
private:
void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString());
- virtual CFArrayRef createDescriptorArrayForFont(CTFontRef font, const QString &fileName) = 0;
+ virtual CFArrayRef createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName) = 0;
mutable QString defaultFontName;
- void removeApplicationFonts();
-
- QVector<QVariant> m_applicationFonts;
mutable QSet<CTFontDescriptorRef> m_systemFontDescriptors;
mutable QHash<QPlatformTheme::Font, QFont *> m_themeFonts;
};
@@ -112,7 +109,7 @@ public:
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
protected:
- CFArrayRef createDescriptorArrayForFont(CTFontRef font, const QString &fileName) override;
+ CFArrayRef createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName) override;
};
QT_END_NAMESPACE