+
+}
+
+
+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;
+ int const next_width = max_width_ - leftMargin(bigrow.pit(), bigrow.endpos())
+ - rightMargin(bigrow.pit());
+
+ int width = 0;
+ flexible_const_iterator<Row> fcit = flexible_begin(bigrow);
+ flexible_const_iterator<Row> const end = flexible_end(bigrow);
+ while (true) {
+ 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.
+ 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;
+ if (rows.empty() || needsRowBreak(f1, f2)) {
+ if (!rows.empty()) {
+ // Flush row as requested by row flags
+ rows.back().flushed((f1 & Flush) || (f2 & FlushBefore));
+ cleanupRow(rows.back(), false);
+ }
+ 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;
+ }
+
+ // The stopping condition is here because we may need a new
+ // empty row at the end.
+ if (fcit == end)
+ break;
+
+ // Next element to consider is either the top of the temporary
+ // pile, or the place when we were in main row
+ Row::Element elt = *fcit;
+ Row::Elements tail;
+ elt.splitAt(width - rows.back().width(), next_width, Row::FIT, tail);
+ Row & rb = rows.back();
+ if (elt.type == Row::MARGINSPACE)
+ elt.dim.wid = max(elt.dim.wid, leftMargin(bigrow.pit()) - rb.width());
+ rb.push_back(elt);
+ rb.finalizeLast();
+ if (rb.width() > width) {
+ // Keep the tail for later; this ought to be rare, but play safe.
+ if (!tail.empty())
+ fcit.put(tail);
+ // if the row is too large, try to cut at last separator.
+ tail = rb.shortenIfNeeded(width, next_width);
+ }
+
+ // Go to next element
+ ++fcit;
+
+ // Handle later the elements returned by splitAt or shortenIfNeeded.
+ fcit.put(tail);
+ }
+
+ if (!rows.empty()) {
+ // Last row in paragraph is flushed
+ rows.back().flushed(true);
+ cleanupRow(rows.back(), true);
+ // Is there an end-of-paragraph change?
+ if (bigrow.needsChangeBar())
+ rows.back().needsChangeBar(true);
+ }
+
+ return rows;
+}
+
+