[LyX features/breakrows] Fix setting of row pos/endpos (overlapping rows)
Jean-Marc Lasgouttes
lasgouttes at lyx.org
Thu Sep 2 13:26:13 UTC 2021
The branch, breakrows, has been updated.
discards 7a0018216746aaa0b71b266f8b99e753bea93bed (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (7a0018216746aaa0b71b266f8b99e753bea93bed)
\
N -- N -- N (5bdc309b1feb6eb9e28914ff0359c3dc78d2bb92)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
- Log -----------------------------------------------------------------
commit 5bdc309b1feb6eb9e28914ff0359c3dc78d2bb92
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Thu Sep 2 15:16:28 2021 +0200
Fix setting of row pos/endpos (overlapping rows)
In TextMetrics::breakParagraph, get rid of the fragile `pos' locale
variable, which was not correctly updated. Rely on the endpos of the
last element in row instead.
Rewrite cleanupPos to rely on the endpos of last the row element to
set row endpos, instead of a `pos' parameter.
diff --git a/src/Row.cpp b/src/Row.cpp
index 8a4bf50..ee5732d 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -469,8 +469,8 @@ void Row::pop_back()
namespace {
-// Remove stuff after it from elts, and return it.
-// if init is provided, it will be in front of the rest
+// Remove stuff after \c it from \c elts, and return it.
+// if \c init is provided, it will prepended to the rest
Row::Elements splitFrom(Row::Elements & elts, Row::Elements::iterator const & it,
Row::Element const & init = Row::Element())
{
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 00ebb55..f055074 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1058,15 +1058,19 @@ 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)
+void cleanupRow(Row & row, pos_type real_endpos, bool is_rtl)
{
- row.endpos(pos);
+ if (row.empty()) {
+ row.endpos(0);
+ return;
+ }
+
+ row.endpos(row.back().endpos);
// remove trailing spaces on row break
- if (pos < real_endpos && !row.empty())
+ if (row.endpos() < real_endpos)
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);
+ row.right_boundary(row.endpos() < real_endpos && row.back().endpos == row.endpos());
// make sure that the RTL elements are in reverse ordering
row.reverseRTL(is_rtl);
}
@@ -1094,7 +1098,6 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
bool const is_rtl = text_->isRTL(bigrow.pit());
bool const end_label = text_->getEndLabel(bigrow.pit()) != END_LABEL_NO_LABEL;
- pos_type pos = 0;
int width = 0;
flexible_const_iterator<Row> fcit = flexible_begin(bigrow);
flexible_const_iterator<Row> const end = flexible_end(bigrow);
@@ -1111,7 +1114,8 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
: fcit->row_flags;
if (rows.empty() || needsRowBreak(f1, f2)) {
if (!rows.empty())
- cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
+ cleanupRow(rows.back(), bigrow.endpos(), is_rtl);
+ pos_type pos = rows.empty() ? 0 : rows.back().endpos();
rows.push_back(newRow(*this, bigrow.pit(), pos, is_rtl));
// the width available for the row.
width = max_width_ - rows.back().right_margin;
@@ -1149,7 +1153,6 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
// a new element in the row
rows.back().push_back(elt);
rows.back().finalizeLast();
- pos = elt.endpos;
// Go to next element
++fcit;
@@ -1164,7 +1167,7 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
}
if (!rows.empty()) {
- cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
+ cleanupRow(rows.back(), bigrow.endpos(), is_rtl);
// Last row in paragraph is flushed
rows.back().flushed(true);
}
commit d0e51b0c0812437e69d779f7eaaa2769972b8605
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Wed Sep 1 16:54:28 2021 +0200
Get rid of need_new_row boolean in breakParagraph
Instead of having breakParagraph decide when breaking a row is
necessary, let Row::shortenIfNeeded set the row_flag of the last
element to request a row break. This was already done in splitAt.
This is in preparation of splitAt splitting in more than two elements.
diff --git a/src/Row.cpp b/src/Row.cpp
index 0e3964a..8a4bf50 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -479,6 +479,8 @@ Row::Elements splitFrom(Row::Elements & elts, Row::Elements::iterator const & it
ret.push_back(init);
ret.insert(ret.end(), it, elts.end());
elts.erase(it, elts.end());
+ if (!elts.empty())
+ elts.back().row_flags = (elts.back().row_flags & ~AfterFlags) | BreakAfter;
return ret;
}
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index fbca421..00ebb55 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1041,6 +1041,7 @@ bool operator==(flexible_const_iterator<T> const & t1,
return t1.cit_ == t2.cit_ && t1.pile_.empty() && t2.pile_.empty();
}
+
Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
{
Row nrow;
@@ -1070,6 +1071,7 @@ void cleanupRow(Row & row, pos_type pos, pos_type real_endpos, bool is_rtl)
row.reverseRTL(is_rtl);
}
+
// Implement the priorities described in RowFlags.h.
bool needsRowBreak(int f1, int f2)
{
@@ -1092,14 +1094,12 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
bool const is_rtl = text_->isRTL(bigrow.pit());
bool const end_label = text_->getEndLabel(bigrow.pit()) != END_LABEL_NO_LABEL;
- bool need_new_row = true;
pos_type pos = 0;
int width = 0;
flexible_const_iterator<Row> fcit = flexible_begin(bigrow);
flexible_const_iterator<Row> const end = flexible_end(bigrow);
while (true) {
- bool const has_row = !rows.empty();
- bool const row_empty = !has_row || rows.back().empty();
+ bool const row_empty = rows.empty() || rows.back().empty();
// The row flags of previous element, if there is one.
// Otherwise we use NoBreakAfter to avoid an empty row before
// e.g. a displayed equation.
@@ -1109,14 +1109,12 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
// paragraph has an end label (for which an empty row is OK).
int const f2 = (fcit == end) ? (end_label ? Inline : NoBreakBefore)
: fcit->row_flags;
- need_new_row |= needsRowBreak(f1, f2);
- if (need_new_row) {
+ if (rows.empty() || needsRowBreak(f1, f2)) {
if (!rows.empty())
cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
rows.push_back(newRow(*this, bigrow.pit(), pos, is_rtl));
// the width available for the row.
width = max_width_ - rows.back().right_margin;
- need_new_row = false;
}
// The stopping condition is here because we may need a new
@@ -1146,7 +1144,6 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
if (!next_elts.empty()) {
rb.flushed(false);
fcit.put(next_elts);
- need_new_row = true;
}
} else {
// a new element in the row
@@ -1162,7 +1159,6 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
// do as if we inserted this element in the original row
if (!next_elt.str.empty())
fcit.put(next_elt);
- need_new_row = true;
}
}
}
commit df3e3a065664ac367d3342e19f3468dc31264985
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Tue Aug 31 19:23:55 2021 +0200
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.
diff --git a/src/Row.cpp b/src/Row.cpp
index 920dd9e..0e3964a 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -35,7 +35,6 @@ using namespace std;
namespace lyx {
-using support::rtrim;
using frontend::FontMetrics;
@@ -168,6 +167,20 @@ bool Row::Element::breakAt(int w, bool force)
}
+void Row::Element::rtrim()
+{
+ if (type != STRING)
+ return;
+ /* This is intended for strings that have been created by breakAt.
+ * 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
{
@@ -545,14 +558,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.
@@ -584,11 +589,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 d45f852..3c78d80 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -107,6 +107,8 @@ public:
* respects the row breaking rules of characters.
*/
bool breakAt(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 fb2a4ae..fbca421 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1060,6 +1060,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
-----------------------------------------------------------------------
Summary of changes:
src/Row.cpp | 33 +++++++++++++++++++++------------
src/Row.h | 2 ++
src/TextMetrics.cpp | 35 +++++++++++++++++++----------------
3 files changed, 42 insertions(+), 28 deletions(-)
hooks/post-receive
--
Repository for new features
More information about the lyx-cvs
mailing list