]> git.lyx.org Git - lyx.git/commitdiff
* qt_helpers.h:
authorAbdelrazak Younes <younes@lyx.org>
Sat, 2 Dec 2006 15:54:49 +0000 (15:54 +0000)
committerAbdelrazak Younes <younes@lyx.org>
Sat, 2 Dec 2006 15:54:49 +0000 (15:54 +0000)
  - ucs4_to_qchar(): add a FIXME and an assertion

* GuiFontMetrics: replace the table based cache with two QHash based cache. With this change, the speed overhead is not negligible (exact same score with the UserGuide test) and the required additional memory is minimal (maybe one or two megabytes).

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16132 a592a061-630c-0410-9148-cb99ea01b6c8

src/frontends/qt4/GuiFontMetrics.C
src/frontends/qt4/GuiFontMetrics.h
src/frontends/qt4/qt_helpers.h

index 165c6459f2cac6128f4bdc70d32a674e7585c4e2..ecfe48722e07ae3c5bf8d75683f58db5147b9d11 100644 (file)
@@ -24,22 +24,9 @@ using std::string;
 namespace lyx {
 namespace frontend {
 
-namespace {
-// Used for checking initialisation state of the C-ish metrics table.
-const short int BadMetrics = -1000;
-}
-
-
 GuiFontMetrics::GuiFontMetrics(QFont const & font)
 : metrics_(font), smallcaps_metrics_(font), smallcaps_shape_(false)
 {
-#ifdef USE_LYX_FONTCACHE
- for (size_t i = 0; i != MaxCharType; ++i) {
-        metrics_cache_[i].width = BadMetrics;
-        metrics_cache_[i].ascent = BadMetrics;
-        metrics_cache_[i].descent = BadMetrics;
- }
-#endif
 }
 
 
@@ -185,61 +172,41 @@ int GuiFontMetrics::descent(char_type c) const
 
 #else
 
-void GuiFontMetrics::fillCache(unsigned short val) const
+void GuiFontMetrics::fillMetricsCache(char_type c) const
 {
-       QRect const & r = metrics_.boundingRect(QChar(val));
-       metrics_cache_[val].descent = static_cast<short>(r.bottom() + 1);
-       metrics_cache_[val].ascent = static_cast<short>(-r.top());
+       QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c));
+       AscendDescend ad = { -r.top(), r.bottom() + 1};
        // We could as well compute the width but this is not really
        // needed for now as it is done directly in width() below.
-       //metrics_cache_[val].width = metrics_.width(QChar(val));
+       metrics_cache_.insert(c, ad);
 }
 
 
 int GuiFontMetrics::width(char_type c) const
 {
-       // FIXME: The following cast is not a real conversion but it work
-       // for the ucs2 subrange of unicode. Instead of an assertion we should
-       // give the metrics of some special characters that indicates that
-       // its display is not supported.
-       BOOST_ASSERT(c < MaxCharType);
-       unsigned short val = static_cast<unsigned short>(c);
-       if (metrics_cache_[val].width == BadMetrics) {
-               metrics_cache_[val].width 
-                       = static_cast<short>(metrics_.width(QChar(val)));
+       if (!width_cache_.contains(c)) {
+               width_cache_.insert(c, metrics_.width(ucs4_to_qchar(c)));
        }
 
-       return metrics_cache_[val].width;
+       return width_cache_.value(c);
 }
 
 
 int GuiFontMetrics::ascent(char_type c) const
 {
-       // FIXME: The following cast is not a real conversion but it work
-       // for the ucs2 subrange of unicode. Instead of an assertion we should
-       // give the metrics of some special characters that indicates that
-       // its display is not supported.
-       BOOST_ASSERT(c < MaxCharType);
-       unsigned short val = static_cast<unsigned short>(c);
-       if (metrics_cache_[val].ascent == BadMetrics)
-               fillCache(val);
+       if (!metrics_cache_.contains(c))
+               fillMetricsCache(c);
 
-       return metrics_cache_[val].ascent;
+       return metrics_cache_.value(c).ascent;
 }
 
 
 int GuiFontMetrics::descent(char_type c) const
 {
-       // FIXME: The following cast is not a real conversion but it work
-       // for the ucs2 subrange of unicode. Instead of an assertion we should
-       // give the metrics of some special characters that indicates that
-       // its display is not supported.
-       BOOST_ASSERT(c < MaxCharType);
-       unsigned short val = static_cast<unsigned short>(c);
-       if (metrics_cache_[val].descent == BadMetrics)
-               fillCache(val);
+       if (!metrics_cache_.contains(c))
+               fillMetricsCache(c);
 
-       return metrics_cache_[val].descent;
+       return metrics_cache_.value(c).descent;
 }
 
 #endif
index f7360506ec1aa4b2ab080b9a3271db11e7f75099..e2e168a9ff9464deea2cde79841c4d4c38ab354a 100644 (file)
@@ -17,6 +17,7 @@
 #include "support/docstring.h"
 
 #include <QFontMetrics>
+#include <QHash>
 
 // Starting with version 3.1.0, Qt/X11 does its own caching of
 // character width, so it is not necessary to provide ours.
 namespace lyx {
 namespace frontend {
 
-size_t const MaxCharType = 65536;
-
-struct CharMetrics
-{
-       short int width;
-       short int ascent;
-       short int descent;
-};
-
-
 class GuiFontMetrics: public FontMetrics
 {
 public:
@@ -82,15 +73,23 @@ private:
        bool smallcaps_shape_;
 
 #ifdef USE_LYX_FONTCACHE
-       /// fill in \c metrics_cache_ at specified value.
-       void fillCache(unsigned short val) const;
+
        /// Cache of char widths
        /** This cache adds 20Mo of memory to the LyX executable when
        * loading UserGuide.lyx which contains a good number of fonts. If
        * this turns out to be too much, we can switch to a \c QHash based
        * solution.
        **/
-       mutable CharMetrics metrics_cache_[MaxCharType];
+       mutable QHash<char_type, int> width_cache_;
+
+       struct AscendDescend {
+               short int ascent;
+               short int descent;
+       };
+       mutable QHash<char_type, AscendDescend> metrics_cache_;
+       /// fill in \c metrics_cache_ at specified value.
+       void fillMetricsCache(char_type) const;
+
 #endif // USE_LYX_FONTCACHE
 };
 
index 1bfed02b7f188184ed1666ede58fef501278f742..82a14383f396f51389a9b6e5a3da5272aaa548ee 100644 (file)
@@ -78,6 +78,11 @@ inline char_type const qchar_to_ucs4(QChar const & qchar) {
 }
 
 inline QChar const ucs4_to_qchar(char_type const ucs4) {
+       // FIXME: The following cast is not a real conversion but it work
+       // for the ucs2 subrange of unicode. Instead of an assertion we should
+       // return some special characters that indicates that its display is
+       // not supported.
+       BOOST_ASSERT(ucs4 < 65536);
        return QChar(static_cast<unsigned short>(ucs4));
 }