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/gui/text/qfontdatabase.cpp | |
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/gui/text/qfontdatabase.cpp')
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 91 |
1 files changed, 66 insertions, 25 deletions
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 02b9e6d25c..ae7b6c1c0d 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -317,6 +317,7 @@ struct QtFontFamily QtFontFamily(const QString &n) : + populated(false), fixedPitch(false), name(n), count(0), foundries(0) , bogusWritingSystems(false) @@ -330,6 +331,7 @@ struct QtFontFamily free(foundries); } + bool populated : 1; bool fixedPitch : 1; QString name; @@ -344,6 +346,8 @@ struct QtFontFamily bool matchesFamilyName(const QString &familyName) const; QtFontFoundry *foundry(const QString &f, bool = false); + + void ensurePopulated(); }; QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create) @@ -375,6 +379,14 @@ bool QtFontFamily::matchesFamilyName(const QString &familyName) const return name.compare(familyName, Qt::CaseInsensitive) == 0 || aliases.contains(familyName, Qt::CaseInsensitive); } +void QtFontFamily::ensurePopulated() +{ + if (populated) + return; + + QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamily(name); + Q_ASSERT(populated); +} class QFontDatabasePrivate { @@ -386,7 +398,14 @@ public: ~QFontDatabasePrivate() { free(); } - QtFontFamily *family(const QString &f, bool = false); + + enum FamilyRequestFlags { + RequestFamily = 0, + EnsureCreated, + EnsurePopulated + }; + + QtFontFamily *family(const QString &f, FamilyRequestFlags flags = EnsurePopulated); void free() { while (count--) delete families[count]; @@ -424,8 +443,10 @@ void QFontDatabasePrivate::invalidate() emit static_cast<QGuiApplication *>(QCoreApplication::instance())->fontDatabaseChanged(); } -QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create) +QtFontFamily *QFontDatabasePrivate::family(const QString &f, FamilyRequestFlags flags) { + QtFontFamily *fam = 0; + int low = 0; int high = count; int pos = count / 2; @@ -439,28 +460,34 @@ QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create) pos = (high + low) / 2; } if (!res) - return families[pos]; + fam = families[pos]; } - if (!create) - return 0; - if (res < 0) - pos++; + if (!fam && (flags & EnsureCreated)) { + if (res < 0) + pos++; + + // qDebug() << "adding family " << f.toLatin1() << " at " << pos << " total=" << count; + if (!(count % 8)) { + QtFontFamily **newFamilies = (QtFontFamily **) + realloc(families, + (((count+8) >> 3) << 3) * sizeof(QtFontFamily *)); + Q_CHECK_PTR(newFamilies); + families = newFamilies; + } + + QtFontFamily *family = new QtFontFamily(f); + memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *)); + families[pos] = family; + count++; - // qDebug() << "adding family " << f.toLatin1() << " at " << pos << " total=" << count; - if (!(count % 8)) { - QtFontFamily **newFamilies = (QtFontFamily **) - realloc(families, - (((count+8) >> 3) << 3) * sizeof(QtFontFamily *)); - Q_CHECK_PTR(newFamilies); - families = newFamilies; + fam = families[pos]; } - QtFontFamily *family = new QtFontFamily(f); - memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *)); - families[pos] = family; - count++; - return families[pos]; + if (fam && (flags & EnsurePopulated)) + fam->ensurePopulated(); + + return fam; } @@ -670,7 +697,7 @@ void qt_registerFont(const QString &familyName, const QString &stylename, styleKey.style = style; styleKey.weight = weight; styleKey.stretch = stretch; - QtFontFamily *f = d->family(familyName, true); + QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::EnsureCreated); f->fixedPitch = fixedPitch; for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) { @@ -689,6 +716,13 @@ void qt_registerFont(const QString &familyName, const QString &stylename, integration->fontDatabase()->releaseHandle(size->handle); } size->handle = handle; + f->populated = true; +} + +void qt_registerFontFamily(const QString &familyName) +{ + // Create uninitialized/unpopulated family + privateDb()->family(familyName, QFontDatabasePrivate::EnsureCreated); } void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias) @@ -697,7 +731,7 @@ void qt_registerAliasToFontFamily(const QString &familyName, const QString &alia return; QFontDatabasePrivate *d = privateDb(); - QtFontFamily *f = d->family(familyName, false); + QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::RequestFamily); if (!f) return; @@ -1092,6 +1126,8 @@ static int match(int script, const QFontDef &request, if (!matchFamilyName(family_name, test.family)) continue; + test.family->ensurePopulated(); + if (family_name.isEmpty()) load(test.family->name, script); @@ -1304,6 +1340,8 @@ QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems() const QList<WritingSystem> list; for (int i = 0; i < d->count; ++i) { QtFontFamily *family = d->families[i]; + family->ensurePopulated(); + if (family->count == 0) continue; for (int x = Latin; x < WritingSystemsCount; ++x) { @@ -1367,11 +1405,14 @@ QStringList QFontDatabase::families(WritingSystem writingSystem) const QStringList flist; for (int i = 0; i < d->count; i++) { QtFontFamily *f = d->families[i]; - if (f->count == 0) + if (f->populated && f->count == 0) continue; - if (writingSystem != Any && (f->writingSystems[writingSystem] != QtFontFamily::Supported)) - continue; - if (f->count == 1) { + if (writingSystem != Any) { + f->ensurePopulated(); + if (f->writingSystems[writingSystem] != QtFontFamily::Supported) + continue; + } + if (!f->populated || f->count == 1) { flist.append(f->name); } else { for (int j = 0; j < f->count; j++) { |