diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 15b69e8106..5d72a7b909 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -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; } diff --git a/src/gui/text/qfontdatabase_p.h b/src/gui/text/qfontdatabase_p.h index 5b78af34a9..341abad2f8 100644 --- a/src/gui/text/qfontdatabase_p.h +++ b/src/gui/text/qfontdatabase_p.h @@ -238,6 +238,7 @@ public: int count; QtFontFamily **families; + bool populated = false; QCache 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; diff --git a/src/gui/text/windows/qwindowsfontdatabase.cpp b/src/gui/text/windows/qwindowsfontdatabase.cpp index 35acf86671..8bac0eda41 100644 --- a/src/gui/text/windows/qwindowsfontdatabase.cpp +++ b/src/gui/text/windows/qwindowsfontdatabase.cpp @@ -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) diff --git a/src/gui/text/windows/qwindowsfontdatabase_p.h b/src/gui/text/windows/qwindowsfontdatabase_p.h index b4b367b1e7..36c5429caf 100644 --- a/src/gui/text/windows/qwindowsfontdatabase_p.h +++ b/src/gui/text/windows/qwindowsfontdatabase_p.h @@ -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;