commit b26b90ae0e2a967c1d6bb05619c09e8408336e6b
Author: Jean-Marc Lasgouttes <[email protected]>
Date: Mon Nov 9 10:11:57 2015 +0100
Use a QCache for string metrics
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.
diff --git a/src/frontends/qt4/GuiFontLoader.cpp
b/src/frontends/qt4/GuiFontLoader.cpp
index 69f1ed2..9a662a8 100644
--- a/src/frontends/qt4/GuiFontLoader.cpp
+++ b/src/frontends/qt4/GuiFontLoader.cpp
@@ -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)
{
diff --git a/src/frontends/qt4/GuiFontMetrics.cpp
b/src/frontends/qt4/GuiFontMetrics.cpp
index 2214623..8d0b026 100644
--- a/src/frontends/qt4/GuiFontMetrics.cpp
+++ b/src/frontends/qt4/GuiFontMetrics.cpp
@@ -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;
}
diff --git a/src/frontends/qt4/GuiFontMetrics.h
b/src/frontends/qt4/GuiFontMetrics.h
index 75507b0..1e813f6 100644
--- a/src/frontends/qt4/GuiFontMetrics.h
+++ b/src/frontends/qt4/GuiFontMetrics.h
@@ -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;