commit ef88e31a1fb00d16d6d56e63b671d128ef43ad12
Author: Jean-Marc Lasgouttes <[email protected]>
Date: Wed Jul 14 00:47:42 2021 +0200
Break the paragraph's big row according to margins
Still many features missing:
- handle insets that break rows (display math, newline, ...)
- handle rows that are too long by replacing the single call to
breakAt with a call to a reworked Row::shortenIfNeeded.
- some easy things at the end of breakRow (bidi text, etc.).
---
src/TextMetrics.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++++++-----
src/TextMetrics.h | 2 +
2 files changed, 84 insertions(+), 9 deletions(-)
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index cc380cc..fb6574d 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -990,6 +990,79 @@ 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;
+}
+
+}
+
+
+RowList TextMetrics::breakParagraph(Row const & row) const
+{
+ RowList rows;
+ bool const is_rtl = text_->isRTL(row.pit());
+
+ bool need_new_row = true;
+ pos_type pos = 0;
+ int width = 0;
+ Row::const_iterator cit = row.begin();
+ Row::const_iterator const end = row.end();
+ // This is a vector, but we use it like a pile putting and taking
+ // stuff at the back.
+ Row::Elements pile;
+ while (true) {
+ if (need_new_row) {
+ if (!rows.empty())
+ rows.back().endpos(pos);
+ rows.push_back(newRow(*this, row.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
+ // empty row at the end.
+ if (cit == end && pile.empty())
+ 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 = pile.empty() ? *cit : pile.back();
+ //LYXERR0("elt=" << elt);
+ Row::Element next_elt = elt.splitAt(width - rows.back().width(),
+
!elt.font.language()->wordWrap());
+ //LYXERR0("next_elt=" << next_elt);
+ // a new element in the row
+ rows.back().push_back(elt);
+ pos = elt.endpos;
+ // Go to next element
+ if (pile.empty())
+ ++cit;
+ else
+ pile.pop_back();
+ // Add a new next element on the pile
+ if (next_elt.isValid()) {
+ pile.push_back(next_elt);
+ need_new_row = true;
+ }
+ }
+
+ return rows;
+}
+
/** This is the function where the hard work is done. The code here is
* very sensitive to small changes :) Note that part of the
* intelligence is also in Row::shortenIfNeeded.
@@ -1003,20 +1076,20 @@ bool TextMetrics::breakRow(Row & row, int const
right_margin) const
theSession().bookmarks().bookmarksInPar(buf.fileName(),
par.id());//
pos_type const end = par.size();//
- pos_type const pos = row.pos();
+ pos_type const pos = row.pos();//
pos_type const body_pos = par.beginOfBody();//
- bool const is_rtl = text_->isRTL(row.pit());
- bool need_new_row = false;
+ bool const is_rtl = text_->isRTL(row.pit());//
+ bool need_new_row = false;//
- row.left_margin = leftMargin(row.pit(), pos);
- row.right_margin = right_margin;
- if (is_rtl)
- swap(row.left_margin, row.right_margin);
+ row.left_margin = leftMargin(row.pit(), pos);//
+ row.right_margin = right_margin;//
+ if (is_rtl)//
+ swap(row.left_margin, row.right_margin);//
// Remember that the row width takes into account the left_margin
// but not the right_margin.
- row.dim().wid = row.left_margin;
+ row.dim().wid = row.left_margin;//
// the width available for the row.
- int const width = max_width_ - row.right_margin;
+ int const width = max_width_ - row.right_margin;//
// check for possible inline completion
DocIterator const & ic_it = bv_->inlineCompletionPos();//
diff --git a/src/TextMetrics.h b/src/TextMetrics.h
index 1666cd0..3ff1161 100644
--- a/src/TextMetrics.h
+++ b/src/TextMetrics.h
@@ -153,6 +153,8 @@ private:
Row tokenizeParagraph(pit_type pit) const;
+ RowList breakParagraph(Row const & row) const;
+
/// sets row.end to the pos value *after* which a row should break.
/// for example, the pos after which isNewLine(pos) == true
/// \return true when another row is required (after a newline)
--
lyx-cvs mailing list
[email protected]
http://lists.lyx.org/mailman/listinfo/lyx-cvs