commit f3cdf74e68bd44074ed985106361552161efde2c
Author: Jean-Marc Lasgouttes <[email protected]>
Date:   Mon Dec 7 10:32:34 2015 +0100

    Remember the last used QTextLayout object
    
    This crude caching mecanism is useful in the particular case of a screen 
with many misspelling dotted lines. In this case, it is necessary to build a 
QTextLayout in order to know where to put the start/end of the spell line. 
Since rows typically contains text snippets longer than a word, we may be in a 
situation where the same QTextLayout is constructed repeatedly.
    
    This commit is useful in this particular use case, and should not be costly 
in other cases. A better fix would be to remember the QTextLayout associated to 
each row element. This is a bit more work, so this fix should be sufficient for 
now.
    
    Additionally, do not paint misspelled marks when painting is disabled.
    
    Fixes bug #9890.

diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp
index ec083e9..8c62926 100644
--- a/src/RowPainter.cpp
+++ b/src/RowPainter.cpp
@@ -609,7 +609,7 @@ void RowPainter::paintText()
                        paintStringAndSel(e);
 
                        // Paint the spelling marks if enabled.
-                       if (lyxrc.spellcheck_continuously && pi_.do_spellcheck)
+                       if (lyxrc.spellcheck_continuously && pi_.do_spellcheck 
&& pi_.pain.isDrawingEnabled())
                                paintMisspelledMark(orig_x, e);
                        break;
                case Row::INSET: {
diff --git a/src/frontends/qt4/GuiFontMetrics.cpp 
b/src/frontends/qt4/GuiFontMetrics.cpp
index 8d0b026..7cf841f 100644
--- a/src/frontends/qt4/GuiFontMetrics.cpp
+++ b/src/frontends/qt4/GuiFontMetrics.cpp
@@ -171,28 +171,44 @@ int GuiFontMetrics::signedWidth(docstring const & s) const
 }
 
 namespace {
-void setTextLayout(QTextLayout & tl, docstring const & s, QFont font,
-                   bool const rtl, double const wordspacing)
+
+QTextLayout const & getTextLayout(docstring const & s, QFont font,
+                                  bool const rtl, double const wordspacing)
 {
-       tl.setText(toqstr(s));
-       font.setWordSpacing(wordspacing);
-       tl.setFont(font);
-       // Note that both setFlags and the enums are undocumented
-       tl.setFlags(rtl ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight);
-       tl.beginLayout();
-       tl.createLine();
-       tl.endLayout();
+       static docstring old_s;
+       static QFont old_font;
+       static bool old_rtl = false;
+       // this invalid value is to make sure that it is reset on first try.
+       static double old_wordspacing = -1.0;
+       // This one is our trivial cache
+       static QTextLayout tl;
+       if (s != old_s || font != old_font || rtl != old_rtl
+           || wordspacing != old_wordspacing) {
+               tl.setText(toqstr(s));
+               font.setWordSpacing(wordspacing);
+               tl.setFont(font);
+               // Note that both setFlags and the enums are undocumented
+               tl.setFlags(rtl ? Qt::TextForceRightToLeft : 
Qt::TextForceLeftToRight);
+               tl.beginLayout();
+               tl.createLine();
+               tl.endLayout();
+               old_s = s;
+               old_font = font;
+               old_rtl = rtl;
+               old_wordspacing = wordspacing;
+       }
+       return tl;
 }
+
 }
 
 
 int GuiFontMetrics::pos2x(docstring const & s, int const pos, bool const rtl,
                           double const wordspacing) const
 {
-       QTextLayout tl;
        QFont copy = font_;
        copy.setWordSpacing(wordspacing);
-       setTextLayout(tl, s, font_, rtl, wordspacing);
+       QTextLayout const & tl = getTextLayout(s, font_, rtl, wordspacing);
        return static_cast<int>(tl.lineForTextPosition(pos).cursorToX(pos));
 }
 
@@ -200,8 +216,7 @@ int GuiFontMetrics::pos2x(docstring const & s, int const 
pos, bool const rtl,
 int GuiFontMetrics::x2pos(docstring const & s, int & x, bool const rtl,
                           double const wordspacing) const
 {
-       QTextLayout tl;
-       setTextLayout(tl, s, font_, rtl, wordspacing);
+       QTextLayout const & tl = getTextLayout(s, font_, rtl, wordspacing);
        int pos = tl.lineForTextPosition(0).xToCursor(x);
        // correct x value to the actual cursor position.
        x = static_cast<int>(tl.lineForTextPosition(0).cursorToX(pos));

Reply via email to