]> git.lyx.org Git - features.git/blobdiff - src/TextMetrics.cpp
Allow toggling of Zoom elements without buffer
[features.git] / src / TextMetrics.cpp
index c7e84f614afecd653f9e0a44a62b78e68953f3f5..2b1ee5adbeadfc5e0fb5f0b3996665aa41e7538b 100644 (file)
@@ -1042,6 +1042,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;
@@ -1049,6 +1050,7 @@ Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
        nrow.pos(pos);
        nrow.left_margin = tm.leftMargin(pit, pos);
        nrow.right_margin = tm.rightMargin(pit);
+       nrow.setRTL(is_rtl);
        if (is_rtl)
                swap(nrow.left_margin, nrow.right_margin);
        // Remember that the row width takes into account the left_margin
@@ -1058,15 +1060,24 @@ 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, bool at_end)
 {
-       row.endpos(pos);
-       row.right_boundary(!row.empty() && pos < real_endpos
-                          && row.back().endpos == pos);
+       if (row.empty()) {
+               row.endpos(0);
+               return;
+       }
+
+       row.endpos(row.back().endpos);
+       // remove trailing spaces on row break
+       if (!at_end)
+               row.back().rtrim();
+       // boundary exists when there was no space at the end of row
+       row.right_boundary(!at_end && row.back().endpos == row.endpos());
        // make sure that the RTL elements are in reverse ordering
-       row.reverseRTL(is_rtl);
+       row.reverseRTL();
 }
 
+
 // Implement the priorities described in RowFlags.h.
 bool needsRowBreak(int f1, int f2)
 {
@@ -1088,15 +1099,14 @@ 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());
 
-       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.
@@ -1106,14 +1116,16 @@ 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())
-                               cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
+               if (rows.empty() || needsRowBreak(f1, f2)) {
+                       if (!rows.empty()) {
+                               cleanupRow(rows.back(), false);
+                               // Flush row as requested by row flags
+                               rows.back().flushed((f1 & Flush) || (f2 & FlushBefore));
+                       }
+                       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;
-                       need_new_row = false;
                }
 
                // The stopping condition is here because we may need a new
@@ -1124,47 +1136,26 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
                // 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::Element next_elt = elt.splitAt(width - rows.back().width(),
-                                                   !elt.font.language()->wordWrap());
-               if (elt.dim.wid > width - rows.back().width()) {
-                       Row & rb = rows.back();
-                       rb.push_back(*fcit);
-                       // if the row is too large, try to cut at last separator. In case
-                       // of success, reset indication that the row was broken abruptly.
-                       int const next_width = max_width_ - leftMargin(rb.pit(), rb.endpos())
-                               - rightMargin(rb.pit());
-
-                       Row::Elements next_elts = rb.shortenIfNeeded(width, next_width);
-
-                       // Go to next element
-                       ++fcit;
-
-                       // Handle later the elements returned by shortenIfNeeded.
-                       if (!next_elts.empty()) {
-                               rb.flushed(false);
-                               fcit.put(next_elts);
-                               need_new_row = true;
-                       }
-               } else {
-                       // a new element in the row
-                       rows.back().push_back(elt);
-                       rows.back().finalizeLast();
-                       pos = elt.endpos;
-
-                       // Go to next element
-                       ++fcit;
-
-                       // Add a new next element on the pile
-                       if (next_elt.isValid()) {
-                               // do as if we inserted this element in the original row
-                               fcit.put(next_elt);
-                               need_new_row = true;
-                       }
+               Row::Elements tail;
+               elt.splitAt(width - rows.back().width(), next_width, false, tail);
+               Row & rb = rows.back();
+               rb.push_back(elt);
+               rb.finalizeLast();
+               if (rb.width() > width) {
+                       LATTEST(tail.empty());
+                       // 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()) {
-               cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
+               cleanupRow(rows.back(), true);
                // Last row in paragraph is flushed
                rows.back().flushed(true);
        }