[LyX/master] Fix crash with countExpanders in Qt6
Jean-Marc Lasgouttes
lasgouttes at lyx.org
Fri Apr 8 13:45:26 UTC 2022
commit 7cb700bf675ca255f3fcbe2fa07d04f0d359ed7b
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Fri Apr 8 11:51:53 2022 +0200
Fix crash with countExpanders in Qt6
It is not a good idea to contruct a QChar from a char_type that is
really 32bits.
Use lyx::isSpace, which already catters for this case.
Since this code does not depend on qt anymore, move it to
support::countExpanders.
Get rid of Row::countSeparators, which is not used anymore.
Fixes bug #12519.
---
src/Row.cpp | 20 +-------------------
src/Row.h | 5 -----
src/frontends/FontMetrics.h | 4 ----
src/frontends/qt/GuiFontMetrics.cpp | 23 +----------------------
src/frontends/qt/GuiFontMetrics.h | 1 -
src/frontends/qt/GuiPainter.cpp | 3 ++-
src/support/lstrings.cpp | 21 +++++++++++++++++++++
src/support/lstrings.h | 5 +++++
8 files changed, 30 insertions(+), 52 deletions(-)
diff --git a/src/Row.cpp b/src/Row.cpp
index f2d4aaf..3d5ab90 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -42,19 +42,11 @@ using frontend::FontMetrics;
static double const MAX_SPACE_STRETCH = 1.5; //em
-int Row::Element::countSeparators() const
-{
- if (type != STRING)
- return 0;
- return count(str.begin(), str.end(), ' ');
-}
-
-
int Row::Element::countExpanders() const
{
if (type != STRING)
return 0;
- return theFontMetrics(font).countExpanders(str);
+ return support::countExpanders(str);
}
@@ -385,16 +377,6 @@ int Row::right_x() const
}
-int Row::countSeparators() const
-{
- int n = 0;
- const_iterator const end = elements_.end();
- for (const_iterator cit = elements_.begin() ; cit != end ; ++cit)
- n += cit->countSeparators();
- return n;
-}
-
-
bool Row::setExtraWidth(int w)
{
if (w < 0)
diff --git a/src/Row.h b/src/Row.h
index 4c4bfce..6583fb2 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -66,9 +66,6 @@ public:
: type(t), pos(p), endpos(p + 1), font(f), change(ch) {}
- // Return the number of separator in the element (only STRING type)
- int countSeparators() const;
-
// Return total width of element, including separator overhead
// FIXME: Cache this value or the number of expanders?
double full_width() const { return dim.wid + extra * countExpanders(); }
@@ -238,8 +235,6 @@ public:
/// The offset of the right-most cursor position on the row
int right_x() const;
- // Return the number of separators in the row
- int countSeparators() const;
// Set the extra spacing for every expanding character in STRING-type
// elements. \param w is the total amount of extra width for the row to be
// distributed among expanders. \return false if the justification fails.
diff --git a/src/frontends/FontMetrics.h b/src/frontends/FontMetrics.h
index 66cd22d..f395270 100644
--- a/src/frontends/FontMetrics.h
+++ b/src/frontends/FontMetrics.h
@@ -168,10 +168,6 @@ public:
int & width,
int & ascent,
int & descent) const = 0;
-
- /// return the number of expanding characters taken into account for
- /// increased inter-word spacing during justification
- virtual int countExpanders(docstring const & str) const = 0;
};
diff --git a/src/frontends/qt/GuiFontMetrics.cpp b/src/frontends/qt/GuiFontMetrics.cpp
index e7f61c6..cb9f5af 100644
--- a/src/frontends/qt/GuiFontMetrics.cpp
+++ b/src/frontends/qt/GuiFontMetrics.cpp
@@ -18,10 +18,10 @@
#include "Dimension.h"
#include "support/convert.h"
+#include "support/debug.h"
#include "support/lassert.h"
#include "support/lstrings.h" // for breakString_helper with qt4
#include "support/lyxlib.h"
-#include "support/debug.h"
#define DISABLE_PMPROF
#include "support/pmprof.h"
@@ -467,27 +467,6 @@ int GuiFontMetrics::x2pos(docstring const & s, int & x, bool const rtl,
}
-int GuiFontMetrics::countExpanders(docstring const & str) const
-{
- // Numbers of characters that are expanded by inter-word spacing. These
- // characters are spaces, except for characters 09-0D which are treated
- // specially. (From a combination of testing with the notepad found in qt's
- // examples, and reading the source code.) In addition, consecutive spaces
- // only count as one expander.
- bool wasspace = false;
- int nexp = 0;
- for (char_type c : str)
- if (c > 0x0d && QChar(c).isSpace()) {
- if (!wasspace) {
- ++nexp;
- wasspace = true;
- }
- } else
- wasspace = false;
- return nexp;
-}
-
-
namespace {
const int brkStrOffset = 1 + BIDI_OFFSET;
diff --git a/src/frontends/qt/GuiFontMetrics.h b/src/frontends/qt/GuiFontMetrics.h
index 9501eb8..82c5839 100644
--- a/src/frontends/qt/GuiFontMetrics.h
+++ b/src/frontends/qt/GuiFontMetrics.h
@@ -92,7 +92,6 @@ public:
int & ascent,
int & descent) const override;
- int countExpanders(docstring const & str) const override;
///
int width(QString const & str) const;
diff --git a/src/frontends/qt/GuiPainter.cpp b/src/frontends/qt/GuiPainter.cpp
index cf9cd7c..b243c6e 100644
--- a/src/frontends/qt/GuiPainter.cpp
+++ b/src/frontends/qt/GuiPainter.cpp
@@ -26,6 +26,7 @@
#include "support/debug.h"
#include "support/lassert.h"
#include "support/lyxlib.h"
+#include "support/lstrings.h"
#include <algorithm>
@@ -329,7 +330,7 @@ void GuiPainter::text(int x, int y, docstring const & s,
if (tw == 0.0)
// Take into account space stretching (word spacing)
textwidth = fm.width(s) +
- static_cast<int>(fm.countExpanders(s) * wordspacing);
+ static_cast<int>(countExpanders(s) * wordspacing);
else
textwidth = static_cast<int>(tw);
diff --git a/src/support/lstrings.cpp b/src/support/lstrings.cpp
index 351c977..b9c23f5 100644
--- a/src/support/lstrings.cpp
+++ b/src/support/lstrings.cpp
@@ -1495,6 +1495,27 @@ string from_percent_encoding(string const & in)
}
+int countExpanders(docstring const & str)
+{
+ // Numbers of characters that are expanded by inter-word spacing. These
+ // characters are spaces, except for characters 09-0D which are treated
+ // specially. (From a combination of testing with the notepad found in qt's
+ // examples, and reading the source code.) In addition, consecutive spaces
+ // only count as one expander.
+ bool wasspace = false;
+ int nexp = 0;
+ for (char_type c : str)
+ if (c > 0x0d && isSpace(c)) {
+ if (!wasspace) {
+ ++nexp;
+ wasspace = true;
+ }
+ } else
+ wasspace = false;
+ return nexp;
+}
+
+
docstring bformat(docstring const & fmt, int arg1)
{
LATTEST(contains(fmt, from_ascii("%1$d")));
diff --git a/src/support/lstrings.h b/src/support/lstrings.h
index 3d42bb6..390d29c 100644
--- a/src/support/lstrings.h
+++ b/src/support/lstrings.h
@@ -368,6 +368,11 @@ docstring to_percent_encoding(docstring const & in, docstring const & ex = docst
/// Returns a string decoded from an URI/URL-style percent-encoded string \p in.
std::string from_percent_encoding(std::string const & in);
+/// returns the number of expanding characters taken into account for
+/// increased inter-word spacing during justification
+int countExpanders(docstring const & str);
+
+
docstring bformat(docstring const & fmt, int arg1);
docstring bformat(docstring const & fmt, long arg1);
#ifdef HAVE_LONG_LONG_INT
More information about the lyx-cvs
mailing list