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.
This commit is contained in:
Jean-Marc Lasgouttes 2022-04-08 11:51:53 +02:00
parent 1f7d90d636
commit 7cb700bf67
8 changed files with 30 additions and 52 deletions

View File

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

View File

@ -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.

View File

@ -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;
};

View File

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

View File

@ -92,7 +92,6 @@ public:
int & ascent,
int & descent) const override;
int countExpanders(docstring const & str) const override;
///
int width(QString const & str) const;

View File

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

View File

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

View File

@ -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