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.
/////////////////////////////////////////////////
+namespace {
-static QString makeFontName(QString const & family, QString const & foundry)
+QString makeFontName(QString const & family, QString const & foundry)
{
QString res = family;
if (!foundry.isEmpty())
}
-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;
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)
{
} // 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)
{
}
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;
}
#include "support/docstring.h"
-#include <map>
-
+#include <QByteArray>
+#include <QCache>
#include <QFont>
#include <QFontMetrics>
#include <QHash>
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;