From 7e53debcf285426042f0f7283b28f716d3b728b1 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Wed, 7 Mar 2012 14:53:57 +0100 Subject: [PATCH] Fix a performance regression with shouldLoadFontEngineForCharacter. Calling FcFontMatch should be avoided as much as possible. We can simply cache the patterns it returns, which should still save memory compared to loading all font engines as we did before. Change-Id: I67208a4f919338a948535f717cfd0139dbea2e5f Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../fontconfig/qfontenginemultifontconfig.cpp | 45 +++++++++++++++------- .../fontconfig/qfontenginemultifontconfig_p.h | 7 ++++ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp index 7b28b20..2016500 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp @@ -42,7 +42,6 @@ #include "qfontenginemultifontconfig_p.h" #include -#include #include QT_BEGIN_NAMESPACE @@ -53,6 +52,14 @@ QFontEngineMultiFontConfig::QFontEngineMultiFontConfig(QFontEngine *fe, int scri { } +QFontEngineMultiFontConfig::~QFontEngineMultiFontConfig() +{ + Q_FOREACH (FcPattern *pattern, cachedMatchPatterns) { + if (pattern) + FcPatternDestroy(pattern); + } +} + bool QFontEngineMultiFontConfig::shouldLoadFontEngineForCharacter(int at, uint ucs4) const { QFontEngineFT *fontEngine = static_cast(engines.at(at)); @@ -61,27 +68,37 @@ bool QFontEngineMultiFontConfig::shouldLoadFontEngineForCharacter(int at, uint u FcCharSet *charSet = fontEngine->freetype->charset; charSetHasChar = FcCharSetHasChar(charSet, ucs4); } else { - FcPattern *requestPattern = FcPatternCreate(); - - FcValue value; - value.type = FcTypeString; - QByteArray cs = fallbackFamilyAt(at-1).toUtf8(); - value.u.s = reinterpret_cast(cs.data()); - FcPatternAdd(requestPattern, FC_FAMILY, value, true); - - FcResult result; - FcPattern *matchPattern = FcFontMatch(0, requestPattern, &result); + FcPattern *matchPattern = getMatchPatternForFallback(at - 1); if (matchPattern != 0) { FcCharSet *charSet; FcPatternGetCharSet(matchPattern, FC_CHARSET, 0, &charSet); charSetHasChar = FcCharSetHasChar(charSet, ucs4); - FcPatternDestroy(matchPattern); } - - FcPatternDestroy(requestPattern); } return charSetHasChar; } + +FcPattern * QFontEngineMultiFontConfig::getMatchPatternForFallback(int fallBackIndex) const +{ + Q_ASSERT(fallBackIndex < fallbackFamilyCount()); + if (engines.size() - 1 > cachedMatchPatterns.size()) + cachedMatchPatterns.resize(engines.size() - 1); + FcPattern *ret = cachedMatchPatterns.at(fallBackIndex); + if (ret) + return ret; + FcPattern *requestPattern = FcPatternCreate(); + FcValue value; + value.type = FcTypeString; + QByteArray cs = fallbackFamilyAt(fallBackIndex).toUtf8(); + value.u.s = reinterpret_cast(cs.data()); + FcPatternAdd(requestPattern, FC_FAMILY, value, true); + FcResult result; + ret = FcFontMatch(0, requestPattern, &result); + cachedMatchPatterns.insert(fallBackIndex, ret); + FcPatternDestroy(requestPattern); + return ret; +} + QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h index 4323cb7..260a9b5 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h +++ b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h @@ -43,6 +43,7 @@ #define QFONTENGINEMULTIFONTCONFIG_H #include +#include QT_BEGIN_NAMESPACE @@ -52,7 +53,13 @@ class QFontEngineMultiFontConfig : public QFontEngineMultiQPA public: explicit QFontEngineMultiFontConfig(QFontEngine *fe, int script, const QStringList &fallbacks); + ~QFontEngineMultiFontConfig(); + bool shouldLoadFontEngineForCharacter(int at, uint ucs4) const; +private: + FcPattern* getMatchPatternForFallback(int at) const; + + mutable QVector cachedMatchPatterns; }; QT_END_NAMESPACE -- 2.7.4