QFontDatabase: Allow partially populating the font database
We were using the count of the registered families as the way to determine if the font database had been populated yet. As a result we needed to invalidate the font database every time an application font was added to an empty database, as once the application font was added, the font database was no longer empty, and we would end up failing to populate any of the system/platform fonts. We now have a dedicated flag for tracking whether the font database has been populated, and we track whether an application font has been populated by looking at its properties list, avoiding a second round of populating when the full initialization happens. This also opens up the possibility of the platform font database populating (lazily or fully) fonts up front, for example as part of resolving theme fonts. The Windows font database had to be taught to invalidate itself at the right moment, instead of assuming doing so during populate was okey. Change-Id: I80c893df755d8d35fb8a84dd7a83c6756a8f24a2 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>bb10
parent
396190686c
commit
656dde05e8
|
|
@ -305,6 +305,11 @@ void QFontDatabasePrivate::clearFamilies()
|
|||
::free(families);
|
||||
families = nullptr;
|
||||
count = 0;
|
||||
|
||||
for (auto &font : applicationFonts)
|
||||
font.properties.clear(); // Unpopulate
|
||||
|
||||
populated = false;
|
||||
// don't clear the memory fonts!
|
||||
}
|
||||
|
||||
|
|
@ -1319,9 +1324,9 @@ QString QFontDatabase::styleString(const QFontInfo &fontInfo)
|
|||
|
||||
Application fonts are always fully registered when added.
|
||||
|
||||
Fonts can be added by the user at any time, so the database
|
||||
may grow even after QFontDatabasePrivate::populateFontDatabase()
|
||||
has been completed.
|
||||
Fonts can be added at any time, so the database may grow even
|
||||
after QFontDatabasePrivate::populateFontDatabase() has been
|
||||
completed.
|
||||
|
||||
The database does not support granular removal of fonts,
|
||||
so if the system fonts change, or an application font is
|
||||
|
|
@ -1339,17 +1344,27 @@ QString QFontDatabase::styleString(const QFontInfo &fontInfo)
|
|||
QFontDatabasePrivate *QFontDatabasePrivate::ensureFontDatabase()
|
||||
{
|
||||
auto *d = QFontDatabasePrivate::instance();
|
||||
if (d->count == 0) {
|
||||
if (!d->populated) {
|
||||
// The font database may have been partially populated, but to ensure
|
||||
// we can answer queries for any platform- or user-provided family we
|
||||
// need to fully populate it now.
|
||||
|
||||
if (Q_UNLIKELY(qGuiApp == nullptr || QGuiApplicationPrivate::platformIntegration() == nullptr))
|
||||
qFatal("QFontDatabase: Must construct a QGuiApplication before accessing QFontDatabase");
|
||||
|
||||
auto *platformFontDatabase = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
|
||||
platformFontDatabase->populateFontDatabase();
|
||||
|
||||
for (int i = 0; i < d->applicationFonts.count(); i++) {
|
||||
auto *font = &d->applicationFonts[i];
|
||||
if (!font->isNull())
|
||||
if (!font->isNull() && !font->isPopulated())
|
||||
platformFontDatabase->addApplicationFont(font->data, font->fileName, font);
|
||||
}
|
||||
|
||||
// Note: Both application fonts and platform fonts may be added
|
||||
// after this initial population, so the only thing we are tracking
|
||||
// is whether we've done our part in ensuring a filled font database.
|
||||
d->populated = true;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
|
@ -2166,8 +2181,6 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &
|
|||
if (font.fileName.isEmpty() && !fontData.isEmpty())
|
||||
font.fileName = QLatin1String(":qmemoryfonts/") + QString::number(i);
|
||||
|
||||
bool wasEmpty = QFontDatabasePrivate::instance()->count == 0;
|
||||
|
||||
auto *platformFontDatabase = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
|
||||
platformFontDatabase->addApplicationFont(font.data, font.fileName, &font);
|
||||
if (font.properties.isEmpty())
|
||||
|
|
@ -2175,16 +2188,11 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &
|
|||
|
||||
applicationFonts[i] = font;
|
||||
|
||||
// If the cache has not yet been populated, we need to reload the application font later
|
||||
if (wasEmpty) {
|
||||
invalidate();
|
||||
} else {
|
||||
emit qGuiApp->fontDatabaseChanged();
|
||||
emit qApp->fontDatabaseChanged();
|
||||
|
||||
// The font cache may have cached lookups for the font that was now
|
||||
// loaded, so it has to be flushed.
|
||||
QFontCache::instance()->clear();
|
||||
}
|
||||
// The font cache may have cached lookups for the font that was now
|
||||
// loaded, so it has to be flushed.
|
||||
QFontCache::instance()->clear();
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ public:
|
|||
|
||||
int count;
|
||||
QtFontFamily **families;
|
||||
bool populated = false;
|
||||
|
||||
QCache<QtFontFallbacksCacheKey, QStringList> fallbacksCache;
|
||||
struct ApplicationFont {
|
||||
|
|
@ -245,6 +246,7 @@ public:
|
|||
QByteArray data;
|
||||
|
||||
bool isNull() const { return fileName.isEmpty(); }
|
||||
bool isPopulated() const { return !properties.isEmpty(); }
|
||||
|
||||
struct Properties {
|
||||
QString familyName;
|
||||
|
|
|
|||
|
|
@ -723,7 +723,6 @@ void QWindowsFontDatabase::addDefaultEUDCFont()
|
|||
|
||||
void QWindowsFontDatabase::populateFontDatabase()
|
||||
{
|
||||
removeApplicationFonts();
|
||||
HDC dummy = GetDC(0);
|
||||
LOGFONT lf;
|
||||
lf.lfCharSet = DEFAULT_CHARSET;
|
||||
|
|
@ -738,6 +737,11 @@ void QWindowsFontDatabase::populateFontDatabase()
|
|||
addDefaultEUDCFont();
|
||||
}
|
||||
|
||||
void QWindowsFontDatabase::invalidate()
|
||||
{
|
||||
removeApplicationFonts();
|
||||
}
|
||||
|
||||
QWindowsFontDatabase::QWindowsFontDatabase()
|
||||
{
|
||||
// Properties accessed by QWin32PrintEngine (Qt Print Support)
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ public:
|
|||
void ensureFamilyPopulated(const QString &familyName);
|
||||
|
||||
void populateFontDatabase() override;
|
||||
void invalidate() override;
|
||||
|
||||
void populateFamily(const QString &familyName) override;
|
||||
bool populateFamilyAliases(const QString &missingFamily) override;
|
||||
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
|
||||
|
|
|
|||
Loading…
Reference in New Issue