mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-07 02:28:35 +00:00
Implement handling of row_flags for row breaking
To this end, add the helper function needsRowBreak which computes the effect of two consecutive row flags. This function implements the priorities described in RowFlags.h. This function is called with the relevant flags, or NoBreak* when at boundaries and updates need_new_row. Some common code is factored in a new cleanupRow() helper.
This commit is contained in:
parent
890fcc0872
commit
0ea1807a52
@ -980,22 +980,6 @@ Row TextMetrics::tokenizeParagraph(pit_type const pit) const
|
||||
|
||||
namespace {
|
||||
|
||||
Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
|
||||
{
|
||||
Row nrow;
|
||||
nrow.pit(pit);
|
||||
nrow.pos(pos);
|
||||
nrow.left_margin = tm.leftMargin(pit, pos);
|
||||
nrow.right_margin = tm.rightMargin(pit);
|
||||
if (is_rtl)
|
||||
swap(nrow.left_margin, nrow.right_margin);
|
||||
// Remember that the row width takes into account the left_margin
|
||||
// but not the right_margin.
|
||||
nrow.dim().wid = nrow.left_margin;
|
||||
return nrow;
|
||||
}
|
||||
|
||||
|
||||
/** Helper template flexible_const_iterator<T>
|
||||
* A way to iterate over a const container, but insert fake elements in it.
|
||||
* In the case of a row, we will have to break some elements, which
|
||||
@ -1018,6 +1002,8 @@ public:
|
||||
|
||||
value_type operator*() const { return pile_.empty() ? *cit_ : pile_.back(); }
|
||||
|
||||
value_type const * operator->() const { return pile_.empty() ? &*cit_ : &pile_.back(); }
|
||||
|
||||
void put(value_type const & e) { pile_.push_back(e); }
|
||||
|
||||
// This should be private, but declaring the friend functions is too much work
|
||||
@ -1051,6 +1037,44 @@ 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;
|
||||
nrow.pit(pit);
|
||||
nrow.pos(pos);
|
||||
nrow.left_margin = tm.leftMargin(pit, pos);
|
||||
nrow.right_margin = tm.rightMargin(pit);
|
||||
if (is_rtl)
|
||||
swap(nrow.left_margin, nrow.right_margin);
|
||||
// Remember that the row width takes into account the left_margin
|
||||
// but not the right_margin.
|
||||
nrow.dim().wid = nrow.left_margin;
|
||||
return nrow;
|
||||
}
|
||||
|
||||
|
||||
void cleanupRow(Row & row, pos_type pos, pos_type real_endpos, bool is_rtl)
|
||||
{
|
||||
row.endpos(pos);
|
||||
row.right_boundary(!row.empty() && pos < real_endpos
|
||||
&& row.back().endpos == pos);
|
||||
// make sure that the RTL elements are in reverse ordering
|
||||
row.reverseRTL(is_rtl);
|
||||
}
|
||||
|
||||
// Implement the priorities described in RowFlags.h.
|
||||
bool needsRowBreak(int f1, int f2)
|
||||
{
|
||||
if (f1 & AlwaysBreakAfter /*|| f2 & AlwaysBreakBefore*/)
|
||||
return true;
|
||||
if (f1 & NoBreakAfter || f2 & NoBreakBefore)
|
||||
return false;
|
||||
if (f1 & BreakAfter || f2 & BreakBefore)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1058,6 +1082,7 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
|
||||
{
|
||||
RowList rows;
|
||||
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;
|
||||
@ -1065,15 +1090,21 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
|
||||
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();
|
||||
// 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.
|
||||
int const f1 = row_empty ? NoBreakAfter : rows.back().back().row_flags;
|
||||
// The row flags of next element, if there is one.
|
||||
// Otherwise we use NoBreakBefore (see above), unless the
|
||||
// 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()) {
|
||||
Row & rb = rows.back();
|
||||
rb.endpos(pos);
|
||||
rb.right_boundary(!rb.empty() && rb.endpos() < bigrow.endpos()
|
||||
&& rb.back().endpos == rb.endpos());
|
||||
// make sure that the RTL elements are in reverse ordering
|
||||
rb.reverseRTL(is_rtl);
|
||||
}
|
||||
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;
|
||||
@ -1107,13 +1138,9 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
|
||||
}
|
||||
|
||||
if (!rows.empty()) {
|
||||
Row & rb = rows.back();
|
||||
cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
|
||||
// Last row in paragraph is flushed
|
||||
rb.flushed(true);
|
||||
rb.endpos(bigrow.endpos());
|
||||
rb.right_boundary(false);
|
||||
// make sure that the RTL elements are in reverse ordering
|
||||
rb.reverseRTL(is_rtl);
|
||||
rows.back().flushed(true);
|
||||
}
|
||||
|
||||
return rows;
|
||||
@ -1227,9 +1254,8 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
|
||||
}
|
||||
f.fontInfo().setColor(Color_nonunique_inlinecompletion);
|
||||
row.addVirtual(i + 1, comp.substr(uniqueTo), f, Change());
|
||||
}//---------------------------------------------------------------^^^
|
||||
}
|
||||
|
||||
// FIXME: Handle when breaking the rows
|
||||
// Handle some situations that abruptly terminate the row
|
||||
// - Before an inset with BreakBefore
|
||||
// - After an inset with BreakAfter
|
||||
@ -1254,7 +1280,6 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
|
||||
++i;
|
||||
++fi;
|
||||
}
|
||||
//--------------------------------------------------------------------vvv
|
||||
row.finalizeLast();
|
||||
row.endpos(i);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user