]> git.lyx.org Git - features.git/commitdiff
Implement real string width computation
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Tue, 25 Jun 2013 06:18:25 +0000 (08:18 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Wed, 25 Jun 2014 15:54:15 +0000 (17:54 +0200)
Important features:
* widths are cached in a map
* old behavior is still used when lyxrc.force_paint_single_char is true.

00README_STR_METRICS_BRANCH
src/frontends/qt4/GuiFontMetrics.cpp
src/frontends/qt4/GuiFontMetrics.h

index b34ba5befe6ff92ebd483941c0c820fafa6830c3..53d9fd3ef2a2adbacc33042899845b21f8843e63 100644 (file)
@@ -5,20 +5,29 @@ for now we intend to keep unchanged behavior for testing purposes.
 
 What is done:
 * Make TextMetrics methods operate on Row objects: breakRow and
-setRowHeight instead of rowBreakPoint and rowHeight.
+  setRowHeight instead of rowBreakPoint and rowHeight.
+
 * change breakRow operation to operate on text strings on which
-metrics are computed. Note that for now FontMetrics::width(docstring)
-still computes the sum of character widths, so that behavior is
-unchanged.
+  metrics are computed. Note that for now
+  FontMetrics::width(docstring) still computes the sum of character
+  widths, so that behavior is unchanged.
+
+* Implement proper string metrics computation (with cache), when
+  lyxrc.force_paint_single_char is false.
 
 Next steps:
+
 * Make breakRow build a list of elements (string, inset,
-separator,...) in the row. This will be reused by other methods
+  separator,...) in the row. This will be reused by other methods
+
 * get rid of rowWidth (breakRow does compute this)
+
 * re-implement getColumnNearX using row elements
-* re-implement x2pos using row elements
-* re-implement row painting using row elements
-* Finally, implement proper string metrics computation (with cache)
+
+* re-implement cursorX using row elements
+
+* re-implement row painting using row elements (can it be done?)
+
 * profile and see how performance can be improved.
 
 Difference in behavior
index e007b4a151d193f167d82dd690dd343be01a60ad..4be0fb2463ed51648038fb409fcf17da8ba2337c 100644 (file)
@@ -15,8 +15,9 @@
 
 #include "qt_helpers.h"
 
-#include "Language.h"
 #include "Dimension.h"
+#include "Language.h"
+#include "LyXRC.h"
 
 #include "insets/Inset.h"
 
@@ -110,21 +111,20 @@ int GuiFontMetrics::rbearing(char_type c) const
 
 int GuiFontMetrics::width(docstring const & s) const
 {
-       size_t ls = s.size();
        int w = 0;
-       for (unsigned int i = 0; i < ls; ++i) {
-               //FIXME: we need to detect surrogate pairs and act accordingly
-               /**
-               if isSurrogateBase(s[i]) {
-                       docstring c = s[i];
-                       w += metrics_.width(toqstr(c + s[i + 1]));
-                       ++i;
+       if (lyxrc.force_paint_single_char) {
+               size_t const ls = s.size();
+               for (size_t i = 0; i < ls; ++i)
+                       w += width(s[i]);
+       } else {
+               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;
                }
-               else
-               */
-               w += width(s[i]);
        }
-
        return w;
 }
 
index be36dbf23f39c5ca7ccebbcba5f2097c709e77cc..a2c57ecc8bdf3d25282ca7e756e5671e073a9489 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "support/docstring.h"
 
+#include <map>
+
 #include <QFontMetrics>
 #include <QHash>
 
@@ -59,6 +61,10 @@ private:
        /// Cache of char widths
        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_;
+
        struct AscendDescend {
                int ascent;
                int descent;