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