From 84b3f123104658edabe52c1d9a673f16c31dbaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 7 Apr 2017 14:56:22 +0200 Subject: [PATCH] macOS: Defer population of localized font family aliases until needed Getting the localized family name of a font involves quite a bit of work internally in CoreText, e.g. creating and sorting font descriptors. By deferring population of family aliases until a font match misses we shave off ~1 second of startup time for applications that use non- localized font families (most applications). Change-Id: I021952c311c0d70d7769ccf764dbf997ebf30a4b Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.cpp | 4 ++ src/gui/text/qplatformfontdatabase.h | 1 + .../mac/qcoretextfontdatabase.mm | 45 ++++++++++++++----- .../mac/qcoretextfontdatabase_p.h | 3 ++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 43648d0f7f3..58933e38fb9 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2678,6 +2678,10 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) QtFontDesc desc; QList blackListed; int index = match(multi ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed); + if (index < 0 && QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamilyAliases()) { + // We populated familiy aliases (e.g. localized families), so try again + index = match(multi ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed); + } if (index >= 0) { engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size); if (engine) diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h index 2ca783f0fd0..f4558129a77 100644 --- a/src/gui/text/qplatformfontdatabase.h +++ b/src/gui/text/qplatformfontdatabase.h @@ -104,6 +104,7 @@ class Q_GUI_EXPORT QPlatformFontDatabase public: virtual ~QPlatformFontDatabase(); virtual void populateFontDatabase(); + virtual bool populateFamilyAliases() { return false; } virtual void populateFamily(const QString &familyName); virtual void invalidate(); diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index d89a81be6b8..7694bfd6bbc 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -113,6 +113,7 @@ static NSInteger languageMapSort(id obj1, id obj2, void *context) #endif QCoreTextFontDatabase::QCoreTextFontDatabase() + : m_hasPopulatedAliases(false) { #ifdef Q_OS_MACX QSettings appleSettings(QLatin1String("apple.com")); @@ -200,18 +201,8 @@ static CFArrayRef availableFamilyNames() void QCoreTextFontDatabase::populateFontDatabase() { QCFType familyNames = availableFamilyNames(); - const int numberOfFamilies = CFArrayGetCount(familyNames); - for (int i = 0; i < numberOfFamilies; ++i) { - CFStringRef familyNameRef = (CFStringRef) CFArrayGetValueAtIndex(familyNames, i); - QString familyName = QString::fromCFString(familyNameRef); - QPlatformFontDatabase::registerFontFamily(familyName); - -#if defined(Q_OS_OSX) - QString localizedFamilyName = QString::fromNSString([[NSFontManager sharedFontManager] localizedNameForFamily:(NSString*)familyNameRef face:nil]); - if (familyName != localizedFamilyName) - QPlatformFontDatabase::registerAliasToFontFamily(familyName, localizedFamilyName); -#endif - } + for (NSString *familyName in familyNames.as()) + QPlatformFontDatabase::registerFontFamily(QString::fromNSString(familyName)); // Force creating the theme fonts to get the descriptors in m_systemFontDescriptors if (m_themeFonts.isEmpty()) @@ -219,6 +210,31 @@ void QCoreTextFontDatabase::populateFontDatabase() Q_FOREACH (CTFontDescriptorRef fontDesc, m_systemFontDescriptors) populateFromDescriptor(fontDesc); + + Q_ASSERT(!m_hasPopulatedAliases); +} + +bool QCoreTextFontDatabase::populateFamilyAliases() +{ +#if defined(Q_OS_MACOS) + if (m_hasPopulatedAliases) + return false; + + QCFType familyNames = availableFamilyNames(); + for (NSString *familyName in familyNames.as()) { + NSFontManager *fontManager = [NSFontManager sharedFontManager]; + NSString *localizedFamilyName = [fontManager localizedNameForFamily:familyName face:nil]; + if (![localizedFamilyName isEqual:familyName]) { + QPlatformFontDatabase::registerAliasToFontFamily( + QString::fromNSString(familyName), + QString::fromNSString(localizedFamilyName)); + } + } + m_hasPopulatedAliases = true; + return true; +#else + return false; +#endif } void QCoreTextFontDatabase::populateFamily(const QString &familyName) @@ -239,6 +255,11 @@ void QCoreTextFontDatabase::populateFamily(const QString &familyName) populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i)), familyName); } +void QCoreTextFontDatabase::invalidate() +{ + m_hasPopulatedAliases = false; +} + struct FontDescription { QCFString familyName; QCFString styleName; diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h index a7529b7fb0f..9612b909f19 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h @@ -75,7 +75,9 @@ public: QCoreTextFontDatabase(); ~QCoreTextFontDatabase(); void populateFontDatabase() Q_DECL_OVERRIDE; + bool populateFamilyAliases() override; void populateFamily(const QString &familyName) Q_DECL_OVERRIDE; + void invalidate() override; QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const Q_DECL_OVERRIDE; QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) Q_DECL_OVERRIDE; @@ -96,6 +98,7 @@ private: mutable QSet m_systemFontDescriptors; mutable QHash m_themeFonts; + bool m_hasPopulatedAliases; }; // Split out into separate template class so that the compiler doesn't have