diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2014-03-10 15:16:47 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-20 19:01:53 +0100 |
commit | 2bc7a40048ada41c59ddac0988bb2e04c227a18d (patch) | |
tree | 549092659e1e2c9e29c16eee3f850c809408fb44 /src/platformsupport | |
parent | 7a08f714a582b2dd1dbdcbc4c20cebc3d7536fe1 (diff) |
Teach font database to populate families lazily
Instead of requiring that QPlatformFontDatabase::populateFontDatabase()
populates every single font in the system by calling registerFont(), we
now allow the platform database to call registerFontFamily() instead, and
then keep track of which families we've yet to fully populate in the font
database.
Once a property of a family is requested (such as its writing system,
style, etc), the family is lazily populated by calling back to the
platform database through QPlatformFontDatabase::populateFamily(),
which in turn does the final call to registerFont() as before.
This cuts application startup on OS X and iOS (of which the font population
used to be a major limiting factor) from roughly one second to about 350ms.
Task-number: QTBUG-37165
Change-Id: Ic2fc3447beb818ffe23635a5b7816ed7e70c93a7
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/platformsupport')
-rw-r--r-- | src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm | 49 | ||||
-rw-r--r-- | src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h | 1 |
2 files changed, 37 insertions, 13 deletions
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index afee68ebed..1c0e888758 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -41,9 +41,11 @@ #include "qglobal.h" -#ifdef Q_OS_MACX +#if defined(Q_OS_MACX) #import <Cocoa/Cocoa.h> #import <IOKit/graphics/IOGraphicsLib.h> +#elif defined(Q_OS_IOS) +#import <UIKit/UIFont.h> #endif #include "qcoretextfontdatabase_p.h" @@ -176,29 +178,50 @@ QCoreTextFontDatabase::~QCoreTextFontDatabase() { } +static CFArrayRef availableFamilyNames() +{ +#if defined(Q_OS_OSX) + return CTFontManagerCopyAvailableFontFamilyNames(); +#elif defined(Q_OS_IOS) + return (CFArrayRef) [[UIFont familyNames] retain]; +#endif +} + 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(); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + QCFType<CFArrayRef> familyNames = availableFamilyNames(); + const int numberOfFamilies = CFArrayGetCount(familyNames); + for (int i = 0; i < numberOfFamilies; ++i) { + QString familyName = QCFString::toQString((CFStringRef) CFArrayGetValueAtIndex(familyNames, i)); - QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0); - if (! collection) - return; + // Don't populate internal fonts + if (familyName.startsWith(QLatin1Char('.')) || familyName == QStringLiteral("LastResort")) + continue; - QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection); - if (! fonts) - return; + QPlatformFontDatabase::registerFontFamily(familyName); + } +} - const int numFonts = CFArrayGetCount(fonts); - for (int i = 0; i < numFonts; ++i) { - CTFontDescriptorRef font = (CTFontDescriptorRef) CFArrayGetValueAtIndex(fonts, i); - populateFromDescriptor(font); +void QCoreTextFontDatabase::populateFamily(const QString &familyName) +{ + CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, QCFString(familyName)); + CTFontDescriptorRef nameOnlyDescriptor = CTFontDescriptorCreateWithAttributes(attributes); + + // A single family might match several different fonts with different styles eg. + QCFType<CFArrayRef> matchingFonts = (CFArrayRef) CTFontDescriptorCreateMatchingFontDescriptors(nameOnlyDescriptor, 0); + if (!matchingFonts) { + qWarning() << "QCoreTextFontDatabase: Found no matching fonts for family" << familyName; + return; } - [pool release]; + const int numFonts = CFArrayGetCount(matchingFonts); + for (int i = 0; i < numFonts; ++i) + populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i))); } void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h index c6fc791503..c73f4a32ca 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h @@ -72,6 +72,7 @@ public: QCoreTextFontDatabase(); ~QCoreTextFontDatabase(); void populateFontDatabase(); + void populateFamily(const QString &familyName) Q_DECL_OVERRIDE; QFontEngine *fontEngine(const QFontDef &fontDef, void *handle); QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); |