diff options
Diffstat (limited to 'src/gui/text/qfontdatabase.cpp')
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 97 |
1 files changed, 80 insertions, 17 deletions
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 85a804acfe..aae84dc988 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -47,6 +47,7 @@ #include <qpa/qplatformfontdatabase.h> #include <qpa/qplatformtheme.h> +#include <QtCore/qcache.h> #include <QtCore/qmath.h> #include <stdlib.h> @@ -413,11 +414,45 @@ void QtFontFamily::ensurePopulated() Q_ASSERT_X(populated, Q_FUNC_INFO, qPrintable(name)); } + +struct FallbacksCacheKey { + QString family; + QFont::Style style; + QFont::StyleHint styleHint; + QChar::Script script; +}; + +inline bool operator==(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rhs) Q_DECL_NOTHROW +{ + return lhs.script == rhs.script && + lhs.styleHint == rhs.styleHint && + lhs.style == rhs.style && + lhs.family == rhs.family; +} + +inline bool operator!=(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rhs) Q_DECL_NOTHROW +{ + return !operator==(lhs, rhs); +} + +inline uint qHash(const FallbacksCacheKey &key, uint seed = 0) Q_DECL_NOTHROW +{ + QtPrivate::QHashCombine hash; + seed = hash(seed, key.family); + seed = hash(seed, int(key.style)); + seed = hash(seed, int(key.styleHint)); + seed = hash(seed, int(key.script)); + return seed; +} + + class QFontDatabasePrivate { public: QFontDatabasePrivate() - : count(0), families(0), reregisterAppFonts(false) + : count(0), families(0), + fallbacksCache(64), + reregisterAppFonts(false) { } ~QFontDatabasePrivate() { @@ -443,6 +478,7 @@ public: int count; QtFontFamily **families; + QCache<FallbacksCacheKey, QStringList> fallbacksCache; struct ApplicationFont { @@ -461,6 +497,8 @@ public: void QFontDatabasePrivate::invalidate() { QFontCache::instance()->clear(); + + fallbacksCache.clear(); free(); QGuiApplicationPrivate::platformIntegration()->fontDatabase()->invalidate(); emit static_cast<QGuiApplication *>(QCoreApplication::instance())->fontDatabaseChanged(); @@ -680,8 +718,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutex, fontDatabaseMutex, (QMutex::Recursive)) void qt_cleanupFontDatabase() { QFontDatabasePrivate *db = privateDb(); - if (db) + if (db) { + db->fallbacksCache.clear(); db->free(); + } } // used in qfontengine_x11.cpp @@ -798,11 +838,17 @@ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString &family, QFo return retList; } -QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) +static QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) { + QFontDatabasePrivate *db = privateDb(); + + const FallbacksCacheKey cacheKey = { family, style, styleHint, script }; + + if (const QStringList *fallbacks = db->fallbacksCache.object(cacheKey)) + return *fallbacks; + // make sure that the db has all fallback families QStringList retList = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script); - QFontDatabasePrivate *db = privateDb(); QStringList::iterator i; for (i = retList.begin(); i != retList.end(); ++i) { @@ -818,9 +864,18 @@ QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFo --i; } } + + db->fallbacksCache.insert(cacheKey, new QStringList(retList)); + return retList; } +QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) +{ + QMutexLocker locker(fontDatabaseMutex()); + return fallbacksForFamily(family, style, styleHint, script); +} + static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt); static void initializeDb() @@ -935,7 +990,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request, if (styleHint == QFont::AnyStyle && request.fixedPitch) styleHint = QFont::TypeWriter; - fallbacks += qt_fallbacksForFamily(family->name, QFont::Style(style->key.style), styleHint, QChar::Script(script)); + fallbacks += fallbacksForFamily(family->name, QFont::Style(style->key.style), styleHint, QChar::Script(script)); pfMultiEngine->setFallbackFamiliesList(fallbacks); } @@ -1413,22 +1468,30 @@ QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems() const QT_PREPEND_NAMESPACE(load)(); - QList<WritingSystem> list; + quint64 writingSystemsFound = 0; + Q_STATIC_ASSERT(WritingSystemsCount < 64); + 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) { - const WritingSystem writingSystem = WritingSystem(x); - if (!(family->writingSystems[writingSystem] & QtFontFamily::Supported)) - continue; - if (!list.contains(writingSystem)) - list.append(writingSystem); + for (uint x = Latin; x < uint(WritingSystemsCount); ++x) { + if (family->writingSystems[x] & QtFontFamily::Supported) + writingSystemsFound |= quint64(1) << x; } } - std::sort(list.begin(), list.end()); + + // mutex protection no longer needed - just working on local data now: + locker.unlock(); + + QList<WritingSystem> list; + list.reserve(qPopulationCount(writingSystemsFound)); + for (uint x = Latin ; x < uint(WritingSystemsCount); ++x) { + if (writingSystemsFound & (quint64(1) << x)) + list.push_back(WritingSystem(x)); + } return list; } @@ -2607,10 +2670,10 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) styleHint = QFont::TypeWriter; QStringList fallbacks = request.fallBackFamilies - + qt_fallbacksForFamily(request.family, - QFont::Style(request.style), - styleHint, - QChar::Script(script)); + + fallbacksForFamily(request.family, + QFont::Style(request.style), + styleHint, + QChar::Script(script)); if (script > QChar::Script_Common) fallbacks += QString(); // Find the first font matching the specified script. |