#include "support/lassert.h"
#include "support/lstrings.h"
#include "support/lyxlib.h"
+#include "support/textutils.h"
#include <algorithm>
#include <ostream>
void Row::Element::rtrim()
{
- if (type != STRING)
+ if (type != STRING || str.empty() || !isSpace(str.back()))
return;
/* This is intended for strings that have been created by splitAt.
- * They may have trailing spaces, but they are not counted in the
- * string length (QTextLayout feature, actually). We remove them,
- * and decrease endpos, since spaces at row break are invisible.
+ * If There is a trailing space, we remove it and decrease endpos,
+ * since spaces at row break are invisible.
*/
- str = support::rtrim(str);
+ str.pop_back();
endpos = pos + str.length();
dim.wid = nspc_wid;
}
#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/textutils.h"
#define DISABLE_PMPROF
#include "support/pmprof.h"
#endif
// Now translate the string character-by-character.
+ bool was_space = false;
for (char_type const c : s) {
+ // insert a word joiner character between consecutive spaces
+ bool const is_space = isSpace(c);
+ if (!naked && is_space && was_space)
+ qstr += word_joiner;
+ was_space = is_space;
// Remember the QString index at this point
pos2qpos_.push_back(qstr.size());
// Performance: UTF-16 characters are easier
// If the line is not the last one, trailing space is always omitted.
int nspc_wid = wid;
// For the last line, compute the width without trailing space
- if (i + 1 == tl.lineCount()) {
- // trim_pos points to the last character that is not a space
- auto trim_pos = s.find_last_not_of(from_ascii(" "));
- if (trim_pos == docstring::npos)
- nspc_wid = 0;
- else if (trim_pos + 1 < s.length()) {
- int const num_spaces = s.length() - trim_pos - 1;
- // find the position on the line before trailing
- // spaces. Remove 1 to account for the ending
- // non-breaking space of qs.
- nspc_wid = iround(line.cursorToX(line_epos - num_spaces - 1));
- }
- }
+ if (i + 1 == tl.lineCount() && !s.empty() && isSpace(s.back())
+ && line.textStart() <= tlh.pos2qpos(s.size() - 1))
+ nspc_wid = iround(line.cursorToX(tlh.pos2qpos(s.size() - 1)));
#else
// With some monospace fonts, the value of horizontalAdvance()
// can be wrong with Qt4. One hypothesis is that the invisible
// characters that we use are given a non-null width.
// FIXME: this is slower than it could be but we'll get rid of Qt4 anyway
- docstring const ss = s.substr(pos, epos - pos);
+ docstring ss = s.substr(pos, epos - pos);
int const wid = width(ss);
- int const nspc_wid = i + 1 < tl.lineCount() ? width(rtrim(ss)) : wid;
+ if (!ss.empty() && isSpace(ss.back()))
+ ss.pop_back();
+ int const nspc_wid = i + 1 < tl.lineCount() ? width(ss) : wid;
#endif
breaks.emplace_back(epos - pos, wid, nspc_wid);
pos = epos;
// 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;
+ // examples, and reading the source code.)
int nexp = 0;
for (char_type c : str)
- if (c > 0x0d && isSpace(c)) {
- if (!wasspace) {
- ++nexp;
- wasspace = true;
- }
- } else
- wasspace = false;
+ if (c > 0x0d && isSpace(c))
+ ++nexp;
return nexp;
}