From ef6dfe18c2149c6b96a806badde9548d7fd9f912 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Tue, 31 Aug 2021 19:23:55 +0200 Subject: [PATCH] Centralize the code that removes trailing spaces from end row element. Move to Row::Element::rtrim the code in Row::shortenIfNeeded that removes trailing spaces from last element in row, so that it can be called when actually breaking a row. Fixes bug found by Kornel. --- src/Row.cpp | 28 +++++++++++++++------------- src/Row.h | 2 ++ src/TextMetrics.cpp | 4 ++++ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/Row.cpp b/src/Row.cpp index 38dbb85696..d3529a3667 100644 --- a/src/Row.cpp +++ b/src/Row.cpp @@ -35,7 +35,6 @@ using namespace std; namespace lyx { -using support::rtrim; using frontend::FontMetrics; @@ -162,6 +161,20 @@ Row::Element Row::Element::splitAt(int w, bool force) } +void Row::Element::rtrim() +{ + if (type != STRING) + 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. + */ + str = support::rtrim(str); + endpos = pos + str.length(); +} + + bool Row::isMarginSelected(bool left, DocIterator const & beg, DocIterator const & end) const { @@ -539,14 +552,6 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width) break; } end_ = brk.endpos; - /* after breakAt, there may be spaces at the end of the - * string, but they are not counted in the string length - * (QTextLayout feature, actually). We remove them, but do - * not change the end of the row, since spaces at row - * break are invisible. - */ - brk.str = rtrim(brk.str); - brk.endpos = brk.pos + brk.str.length(); *cit_brk = brk; dim_.wid = wid_brk + brk.dim.wid; // If there are other elements, they should be removed. @@ -578,11 +583,8 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width) * boundary this time. */ Element remainder = cit->splitAt(w - wid, true); - if (remainder.isValid()) { + if (cit->row_flags & BreakAfter) { end_ = cit->endpos; - // See comment above. - cit->str = rtrim(cit->str); - cit->endpos = cit->pos + cit->str.length(); dim_.wid = wid + cit->dim.wid; // If there are other elements, they should be removed. return splitFrom(elements_, next(cit, 1), remainder); diff --git a/src/Row.h b/src/Row.h index b0b17556f4..74667976ef 100644 --- a/src/Row.h +++ b/src/Row.h @@ -101,6 +101,8 @@ public: * respects the row breaking rules of characters. */ Element splitAt(int w, bool force); + // remove trailing spaces (useful for end of row) + void rtrim(); // bool isRTL() const { return font.isVisibleRightToLeft(); } diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 37894f61db..a7dd300d2e 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -1061,6 +1061,10 @@ Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl) void cleanupRow(Row & row, pos_type pos, pos_type real_endpos, bool is_rtl) { row.endpos(pos); + // remove trailing spaces on row break + if (pos < real_endpos && !row.empty()) + row.back().rtrim(); + // boundary exists when there was no space at the end of row row.right_boundary(!row.empty() && pos < real_endpos && row.back().endpos == pos); // make sure that the RTL elements are in reverse ordering