]> git.lyx.org Git - features.git/commitdiff
Use a QCache for string metrics
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 9 Nov 2015 09:11:57 +0000 (10:11 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Tue, 17 Nov 2015 08:38:16 +0000 (09:38 +0100)
This is better because it implements a LRU cache. Indeed, while editing in particular, width of many different strings has to be computed. This is different from the previous situation where only width of single characters was computed and cached.

src/frontends/qt4/GuiFontLoader.cpp
src/frontends/qt4/GuiFontMetrics.cpp
src/frontends/qt4/GuiFontMetrics.h

index 69f1ed2439dbe279f49b6edc9c54066a0cd8331b..9a662a893b3ce846386588370befeeaeae755f15 100644 (file)
@@ -259,8 +259,9 @@ FontLoader::~FontLoader()
 
 /////////////////////////////////////////////////
 
+namespace {
 
-static QString makeFontName(QString const & family, QString const & foundry)
+QString makeFontName(QString const & family, QString const & foundry)
 {
        QString res = family;
        if (!foundry.isEmpty())
@@ -269,9 +270,9 @@ static QString makeFontName(QString const & family, QString const & foundry)
 }
 
 
-GuiFontInfo::GuiFontInfo(FontInfo const & f)
-       : metrics(QFont())
+QFont makeQFont(FontInfo const & f)
 {
+       QFont font;
        QString const pat = symbolFamily(f.family());
        if (!pat.isEmpty()) {
                bool ok;
@@ -347,9 +348,16 @@ GuiFontInfo::GuiFontInfo(FontInfo const & f)
 
        LYXERR(Debug::FONT, "The font has size: " << font.pointSizeF());
 
-       metrics = GuiFontMetrics(font);
+       return font;
 }
 
+} // anon namespace
+
+
+GuiFontInfo::GuiFontInfo(FontInfo const & f)
+       : font(makeQFont(f)), metrics(font)
+{}
+
 
 bool FontLoader::available(FontInfo const & f)
 {
index 2214623d3b7b9b4befc7c3aff5125f21e8957217..8d0b0269980c9a79a5be70bc2732103aaa751b9e 100644 (file)
@@ -53,7 +53,10 @@ inline QChar const ucs4_to_qchar(char_type const ucs4)
 } // anon namespace
 
 
-GuiFontMetrics::GuiFontMetrics(QFont const & font) : font_(font), metrics_(font, 0)
+// Limit strwidth_cache_ size to 512kB of string data
+GuiFontMetrics::GuiFontMetrics(QFont const & font)
+       : font_(font), metrics_(font, 0),
+         strwidth_cache_(1 << 19)
 {
 }
 
@@ -138,14 +141,14 @@ int GuiFontMetrics::rbearing(char_type c) const
 
 int GuiFontMetrics::width(docstring const & s) const
 {
-       int w = 0;
-       map<docstring, int>::const_iterator it = strwidth_cache_.find(s);
-       if (it != strwidth_cache_.end()) {
-               w = it->second;
-       } else {
-               w = metrics_.width(toqstr(s));
-               strwidth_cache_[s] = w;
-       }
+       QByteArray qba =
+               QByteArray(reinterpret_cast<char const *>(s.data()),
+                          s.size() * sizeof(docstring::value_type));
+       int * pw = strwidth_cache_[qba];
+       if (pw)
+               return *pw;
+       int w = metrics_.width(toqstr(s));
+       strwidth_cache_.insert(qba, new int(w), qba.size());
        return w;
 }
 
index 75507b0c99cf1abdcc68b2cca28e806ac7e3cfa8..1e813f6af180534ec80687ee151a2ca36c6a1b4d 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "support/docstring.h"
 
-#include <map>
-
+#include <QByteArray>
+#include <QCache>
 #include <QFont>
 #include <QFontMetrics>
 #include <QHash>
@@ -73,8 +73,7 @@ private:
        mutable QHash<char_type, int> width_cache_;
 
        /// Cache of string widths
-       /// FIXME Try to use a QHash (this requires to define qHash(docstring))
-       mutable std::map<docstring, int> strwidth_cache_;
+       mutable QCache<QByteArray, int> strwidth_cache_;
 
        struct AscendDescend {
                int ascent;