Fix setting of row pos/endpos (overlapping rows)

In TextMetrics::breakParagraph, get rid of the fragile `pos' local
variable, which was not correctly updated. Rely on the endpos of the
last element in row instead.

Rewrite cleanupRow to rely on the endpos of last the row element to
set row endpos, instead of a `pos' parameter.
This commit is contained in:
Jean-Marc Lasgouttes 2021-09-02 15:16:28 +02:00
parent 4120635185
commit 4b69f5efa7
2 changed files with 14 additions and 11 deletions

View File

@ -463,8 +463,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())
{

View File

@ -1059,15 +1059,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);
}
@ -1095,7 +1099,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);
@ -1112,7 +1115,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;
@ -1150,7 +1154,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;
@ -1165,7 +1168,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);
}