From 9583695827aaa691e570ece37ecee227cd411dd2 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Sun, 11 Jul 2021 15:33:33 +0200 Subject: [PATCH] Small Row cleanups Move declaration of RowList to Row.h Move initialization of POD members of Row and Row::Element to declaration. Make method isVirtual() depend on type. Add new row element type INVALID and method isValid() Make methods R::E::left/right_pos inline. Add method R::E::splitAt() that returns an element containing the remaining stuff, or an invalid element if nothing was split. breakAt is now a simple wrapper around this function. Add method R::push_back(). --- src/ParagraphMetrics.h | 9 ---- src/Row.cpp | 44 +++++++++---------- src/Row.h | 96 ++++++++++++++++++++++++++---------------- src/RowPainter.cpp | 4 ++ 4 files changed, 86 insertions(+), 67 deletions(-) diff --git a/src/ParagraphMetrics.h b/src/ParagraphMetrics.h index 988947355e..1d690aab77 100644 --- a/src/ParagraphMetrics.h +++ b/src/ParagraphMetrics.h @@ -20,17 +20,8 @@ #include "Dimension.h" #include "Row.h" -#include - namespace lyx { -/** - * Each paragraph is broken up into a number of rows on the screen. - * This is a list of such on-screen rows, ordered from the top row - * downwards. - */ -typedef std::vector RowList; - class BufferView; class Paragraph; diff --git a/src/Row.cpp b/src/Row.cpp index 2f6db3deaf..da2d885eb2 100644 --- a/src/Row.cpp +++ b/src/Row.cpp @@ -124,53 +124,43 @@ pos_type Row::Element::x2pos(int &x) const x = 0; i = isRTL(); } + break; + case INVALID: + LYXERR0("x2pos: INVALID row element !"); } //lyxerr << "=> p=" << pos + i << " x=" << x << endl; return pos + i; } -bool Row::Element::breakAt(int w, bool force) +Row::Element Row::Element::splitAt(int w, bool force) { if (type != STRING) - return false; + return Element(); FontMetrics const & fm = theFontMetrics(font); dim.wid = w; int const i = fm.breakAt(str, dim.wid, isRTL(), force); if (i != -1) { + Element ret(STRING, pos + i, font, change); + ret.str = str.substr(i); + ret.endpos = ret.pos + ret.str.length(); str.erase(i); endpos = pos + i; //lyxerr << "breakAt(" << w << ") Row element Broken at " << x << "(w(str)=" << fm.width(str) << "): e=" << *this << endl; + return ret; } - return i != - 1; + return Element(); } -pos_type Row::Element::left_pos() const -{ - return isRTL() ? endpos : pos; -} - - -pos_type Row::Element::right_pos() const +bool Row::Element::breakAt(int w, bool force) { - return isRTL() ? pos : endpos; + return splitAt(w, force).isValid(); } -Row::Row() - : separator(0), label_hfill(0), left_margin(0), right_margin(0), - sel_beg(-1), sel_end(-1), - begin_margin_sel(false), end_margin_sel(false), - changed_(true), - pit_(0), pos_(0), end_(0), - right_boundary_(false), flushed_(false), rtl_(false), - changebar_(false) -{} - - bool Row::isMarginSelected(bool left, DocIterator const & beg, DocIterator const & end) const { @@ -262,6 +252,9 @@ ostream & operator<<(ostream & os, Row::Element const & e) case Row::SPACE: os << "SPACE: "; break; + case Row::INVALID: + os << "INVALID: "; + break; } os << "width=" << e.full_width(); return os; @@ -443,6 +436,13 @@ void Row::addSpace(pos_type const pos, int const width, } +void Row::push_back(Row::Element const & e) +{ + dim_.wid += e.dim.wid; + elements_.push_back(e); +} + + void Row::pop_back() { dim_.wid -= elements_.back().dim.wid; diff --git a/src/Row.h b/src/Row.h index b54a233b20..3048cf1ccf 100644 --- a/src/Row.h +++ b/src/Row.h @@ -49,7 +49,9 @@ public: // An inset INSET, // Some spacing described by its width, not a string - SPACE + SPACE, + // Something that should not happen (for error handling) + INVALID }; /** @@ -57,9 +59,12 @@ public: * by other methods that need to parse the Row contents. */ struct Element { + // + Element() = default; + // Element(Type const t, pos_type p, Font const & f, Change const & ch) - : type(t), pos(p), endpos(p + 1), inset(0), - extra(0), font(f), change(ch), final(false) {} + : type(t), pos(p), endpos(p + 1), font(f), change(ch) {} + // Return the number of separator in the element (only STRING type) int countSeparators() const; @@ -86,40 +91,49 @@ public: * adjusted to the actual pixel position. */ pos_type x2pos(int &x) const; + /** Break the element in two if possible, so that its width is less + * than \param w. + * \return an element containing the remainder of the text, or + * an invalid element if nothing happened. + * \param w: the desired maximum width + * \param force: if true, the string is cut at any place, otherwise it + * respects the row breaking rules of characters. + */ + Element splitAt(int w, bool force); /** Break the element if possible, so that its width is less * than \param w. Returns true on success. When \param force - * is true, the string is cut at any place, other wise it + * is true, the string is cut at any place, otherwise it * respects the row breaking rules of characters. */ bool breakAt(int w, bool force); - // Returns the position on left side of the element. - pos_type left_pos() const; - // Returns the position on right side of the element. - pos_type right_pos() const; - // bool isRTL() const { return font.isVisibleRightToLeft(); } // This is true for virtual elements. - // Note that we do not use the type here. The two definitions - // should be equivalent - bool isVirtual() const { return pos == endpos; } + bool isVirtual() const { return type == VIRTUAL; } + // Invalid element, for error handling + bool isValid() const { return type !=INVALID; } + + // Returns the position on left side of the element. + pos_type left_pos() const { return isRTL() ? endpos : pos; }; + // Returns the position on right side of the element. + pos_type right_pos() const { return isRTL() ? pos : endpos; }; // The kind of row element - Type type; + Type type = INVALID; // position of the element in the paragraph - pos_type pos; + pos_type pos = 0; // first position after the element in the paragraph - pos_type endpos; + pos_type endpos = 0; // The dimension of the chunk (does not contains the // separator correction) Dimension dim; // Non-zero only if element is an inset - Inset const * inset; + Inset const * inset = nullptr; // Only non-null for justified rows - double extra; + double extra = 0; // Non-empty if element is a string or is virtual docstring str; @@ -128,14 +142,15 @@ public: // Change change; // is it possible to add contents to this element? - bool final; + bool final = false; friend std::ostream & operator<<(std::ostream & os, Element const & row); }; /// - Row(); + Row() {} + /** * Helper function: set variable \c var to value \c val, and mark * row as changed is the values were different. This is intended @@ -264,7 +279,9 @@ public: Element & back() { return elements_.back(); } /// Element const & back() const { return elements_.back(); } - /// remove last element + /// add element at the end and update width + void push_back(Element const &); + /// remove last element and update width void pop_back(); /** * if row width is too large, remove all elements after last @@ -301,21 +318,21 @@ public: friend std::ostream & operator<<(std::ostream & os, Row const & row); /// additional width for separators in justified rows (i.e. space) - double separator; + double separator = 0; /// width of hfills in the label - double label_hfill; + double label_hfill = 0; /// the left margin position of the row - int left_margin; + int left_margin = 0; /// the right margin of the row - int right_margin; + int right_margin = 0; /// - mutable pos_type sel_beg; + mutable pos_type sel_beg = -1; /// - mutable pos_type sel_end; + mutable pos_type sel_end = -1; /// - mutable bool begin_margin_sel; + mutable bool begin_margin_sel = false; /// - mutable bool end_margin_sel; + mutable bool end_margin_sel = false; private: /// Decides whether the margin is selected. @@ -340,28 +357,35 @@ private: Elements elements_; /// has the Row appearance changed since last drawing? - mutable bool changed_; + mutable bool changed_ = true; /// Index of the paragraph that contains this row - pit_type pit_; + pit_type pit_ = 0; /// first pos covered by this row - pos_type pos_; + pos_type pos_ = 0; /// one behind last pos covered by this row - pos_type end_; + pos_type end_ = 0; // Is there a boundary at the end of the row (display inset...) - bool right_boundary_; + bool right_boundary_ = false; // Shall the row be flushed when it is supposed to be justified? - bool flushed_; + bool flushed_ = false; /// Row dimension. Dimension dim_; /// Row contents dimension. Does not contain the space above/below row. Dimension contents_dim_; /// true when this row lives in a right-to-left paragraph - bool rtl_; + bool rtl_ = false; /// true when a changebar should be drawn in the margin - bool changebar_; + bool changebar_ = false; }; +/** + * Each paragraph is broken up into a number of rows on the screen. + * This is a list of such on-screen rows, ordered from the top row + * downwards. + */ +typedef std::vector RowList; + } // namespace lyx #endif diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp index 400b7b66e8..656f89a4e0 100644 --- a/src/RowPainter.cpp +++ b/src/RowPainter.cpp @@ -565,6 +565,10 @@ void RowPainter::paintText() case Row::SPACE: paintTextDecoration(e); + break; + + case Row::INVALID: + LYXERR0("Trying to paint INVALID row element."); } // The markings of foreign languages -- 2.39.5