Le 14/11/2015 05:13, Scott Kostyshak a écrit :
I have tagged and tarred (and signed) alpha1. I will upload the tarballs
soon.

Development is open for post-alpha commits.

So can we just commit as we see fit, or would you like stuff to go to mailing list first? First example would be the following patch, which tries to avoid excessive memory use during long editing sessions.

JMarc

>From a5bbce530586b8dd6aa54e4479749cfc0a54f0b1 Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date: Mon, 9 Nov 2015 10:11:57 +0100
Subject: [PATCH] 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.
---
 src/frontends/qt4/GuiFontLoader.cpp  | 16 ++++++++++++----
 src/frontends/qt4/GuiFontMetrics.cpp | 21 ++++++++++++---------
 src/frontends/qt4/GuiFontMetrics.h   |  7 +++----
 3 files changed, 27 insertions(+), 17 deletions(-)

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;
-- 
2.5.0

Reply via email to