]> git.lyx.org Git - features.git/commitdiff
Reduce use of double variables in Row
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 22 Dec 2014 09:36:53 +0000 (10:36 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 22 Dec 2014 13:07:24 +0000 (14:07 +0100)
All the code that is run before row metrics have been computed should use int arithmetic. After metrics have been computed, we still need doubles because fully justified rows use double for Row::Element::extra.

Rename Row::x to Row::left_margin and change its type to int.

Rename Row::Element::width() to full_width(). In some places of the code, use dim.wid (the int version without the extra separator) because metrics have not been computed.

Let Row::Element::x2pos take a int& argument instead of double&

Let Row::Element::breakAt take a int argument instead of double

src/Row.cpp
src/Row.h
src/RowPainter.cpp
src/TextMetrics.cpp

index 7052aa025cbeb24bfb5bf5d48af0ebc7d74e3048..9d944516843c2325e5617b4bd389e6857efcfc9a 100644 (file)
@@ -48,9 +48,9 @@ double Row::Element::pos2x(pos_type const i) const
        double w = 0;
        //handle first the two bounds of the element
        if (i == endpos && !(inset && inset->lyxCode() == SEPARATOR_CODE))
-               w = rtl ? 0 : width();
+               w = rtl ? 0 : full_width();
        else if (i == pos || type != STRING)
-               w = rtl ? width() : 0;
+               w = rtl ? full_width() : 0;
        else {
                FontMetrics const & fm = theFontMetrics(font);
                w = fm.pos2x(str, i - pos, font.isVisibleRightToLeft());
@@ -60,7 +60,7 @@ double Row::Element::pos2x(pos_type const i) const
 }
 
 
-pos_type Row::Element::x2pos(double &x) const
+pos_type Row::Element::x2pos(int &x) const
 {
        //lyxerr << "x2pos: x=" << x << " w=" << width() << " " << *this;
        bool const rtl = font.isVisibleRightToLeft();
@@ -69,24 +69,21 @@ pos_type Row::Element::x2pos(double &x) const
        switch (type) {
        case STRING: {
                FontMetrics const & fm = theFontMetrics(font);
-               // FIXME: is it really necessary for x to be a double?
-               int xx = int(x);
-               i = fm.x2pos(str, xx, rtl);
-               x = xx;
+               i = fm.x2pos(str, x, rtl);
                break;
        }
        case VIRTUAL:
                // those elements are actually empty (but they have a width)
                i = 0;
-               x = rtl ? width() : 0;
+               x = rtl ? int(full_width()) : 0;
                break;
        case SEPARATOR:
        case INSET:
        case SPACE:
                // those elements contain only one position. Round to
                // the closest side.
-               if (x > width()) {
-                       x = width();
+               if (x > full_width()) {
+                       x = int(full_width());
                        i = !rtl;
                } else {
                        x = 0;
@@ -100,22 +97,22 @@ pos_type Row::Element::x2pos(double &x) const
 }
 
 
-bool Row::Element::breakAt(double w)
+bool Row::Element::breakAt(int w)
 {
-       if (type != STRING || width() <= w)
+       if (type != STRING || dim.wid <= w)
                return false;
 
        bool const rtl = font.isVisibleRightToLeft();
        if (rtl)
-               w = width() - w;
+               w = dim.wid - w;
        pos_type new_pos = x2pos(w);
        if (new_pos == pos)
                return false;
        str = str.substr(0, new_pos - pos);
        if (rtl)
-               dim.wid -= int(w);
+               dim.wid -= w;
        else
-               dim.wid = int(w);
+               dim.wid = w;
        endpos = new_pos;
        return true;
 }
@@ -134,7 +131,7 @@ pos_type Row::Element::right_pos() const
 
 
 Row::Row()
-       : separator(0), label_hfill(0), x(0), right_margin(0),
+       : 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_(false), crc_(0), pos_(0), end_(0), right_boundary_(false)
@@ -236,7 +233,7 @@ ostream & operator<<(ostream & os, Row::Element const & e)
                os << "SPACE: ";
                break;
        }
-       os << "width=" << e.width();
+       os << "width=" << e.full_width();
        return os;
 }
 
@@ -244,7 +241,7 @@ ostream & operator<<(ostream & os, Row::Element const & e)
 ostream & operator<<(ostream & os, Row const & row)
 {
        os << " pos: " << row.pos_ << " end: " << row.end_
-          << " x: " << row.x
+          << " left_margin: " << row.left_margin
           << " width: " << row.dim_.wid
           << " right_margin: " << row.right_margin
           << " ascent: " << row.dim_.asc
@@ -252,11 +249,11 @@ ostream & operator<<(ostream & os, Row const & row)
           << " separator: " << row.separator
           << " label_hfill: " << row.label_hfill 
           << " row_boundary: " << row.right_boundary() << "\n";
-       double x = row.x;
+       double x = row.left_margin;
        Row::Elements::const_iterator it = row.elements_.begin();
        for ( ; it != row.elements_.end() ; ++it) {
                os << "x=" << x << " => " << *it << endl;
-               x += it->width();
+               x += it->full_width();
        }
        return os;
 }
@@ -365,8 +362,8 @@ void Row::shortenIfNeeded(pos_type const keep, int const w)
        Elements::iterator const beg = elements_.begin();
        Elements::iterator const end = elements_.end();
        Elements::iterator last_sep = elements_.end();
-       double last_width = 0;
-       double wid = x;
+       int last_width = 0;
+       int wid = left_margin;
 
        Elements::iterator cit = beg;
        for ( ; cit != end ; ++cit) {
@@ -374,16 +371,16 @@ void Row::shortenIfNeeded(pos_type const keep, int const w)
                        last_sep = cit;
                        last_width = wid;
                }
-               if (wid + cit->width() > w)
+               if (wid + cit->dim.wid > w)
                        break;
-               wid += cit->width();
+               wid += cit->dim.wid;
        }
 
        if (last_sep != end) {
                // We have found a suitable separator. This is the
                // common case.
                end_ = last_sep->endpos;
-               dim_.wid = int(last_width);
+               dim_.wid = last_width;
                elements_.erase(last_sep, end);
                return;
        }
@@ -398,14 +395,14 @@ void Row::shortenIfNeeded(pos_type const keep, int const w)
                // It is not possible to separate a virtual element from the
                // previous one.
                --cit;
-               wid -= cit->width();
+               wid -= cit->dim.wid;
        }
 
        if (cit != beg) {
                // There is no separator, but several elements (probably
                // insets) have been added. We can cut at this place.
                end_ = cit->pos;
-               dim_.wid = int(wid);
+               dim_.wid = wid;
                elements_.erase(cit, end);
                return;
        }
@@ -415,9 +412,9 @@ void Row::shortenIfNeeded(pos_type const keep, int const w)
         * something: when we have one big string, maybe with some
         * other things after it.
         */
-       if (cit->breakAt(w - x)) {
+       if (cit->breakAt(w - left_margin)) {
                end_ = cit->endpos;
-               dim_.wid = int(x + cit->width());
+               dim_.wid = left_margin + cit->dim.wid;
                // If there are other elements, they should be removed.
                elements_.erase(boost::next(cit), end);
        }
index 13a11b4870e361365bf9a47ae7e049b23f2ed425..9039ff8860e9d40c2b52cd7b817de8bec8229f8b 100644 (file)
--- a/src/Row.h
+++ b/src/Row.h
@@ -76,7 +76,7 @@ public:
                          extra(0), font(f), change(ch), final(false) {}
 
                // Return total width of element, including separator overhead
-               double width() const { return dim.wid + extra; };
+               double full_width() const { return dim.wid + extra; };
                /** Return position in pixels (from the left) of position
                 * \param i in the row element.
                 */
@@ -85,11 +85,11 @@ public:
                 *  pixel position \param x. The value \param x is
                 *  adjusted to the actual pixel position.
                */
-               pos_type x2pos(double &x) const;
+               pos_type x2pos(int &x) const;
                /** Break the element if possible, so that its width is
                 * less then \param w. Returns true on success.
                 */
-               bool breakAt(double w);
+               bool breakAt(int w);
 
                // Returns the position on left side of the element.
                pos_type left_pos() const;
@@ -243,8 +243,8 @@ public:
        double separator;
        /// width of hfills in the label
        double label_hfill;
-       /// the x position of the row (left margin)
-       double x;
+       /// the left margin position of the row
+       int left_margin;
        /// the right margin of the row
        int right_margin;
        ///
index c42e82c207052cc2874999d8c26bfa73516804f0..ab42e675b4db590f0a7c1b22a13ae833ad7a9a53 100644 (file)
@@ -83,7 +83,7 @@ RowPainter::RowPainter(PainterInfo & pi,
                dotted_line_offset_ = int(0.5 * dotted_line_thickness_) + 1;
        }
 
-       x_ = row_.x + xo_;
+       x_ = row_.left_margin + xo_;
 
        //lyxerr << "RowPainter: x: " << x_ << " xo: " << xo_ << " yo: " << yo_ << endl;
        //row_.dump();
index ce31435b7f8fdede1fd068a4cff6dc1ba56f284e..874cb17607f716e9551e53720237300f57c1f699 100644 (file)
@@ -571,9 +571,9 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
 
        bool const is_rtl = text_->isRTL(par);
        if (is_rtl)
-               row.x = rightMargin(pit);
+               row.left_margin = rightMargin(pit);
        else
-               row.x = leftMargin(max_width_, pit, row.pos());
+               row.left_margin = leftMargin(max_width_, pit, row.pos());
 
        // is there a manual margin with a manual label
        Layout const & layout = par.layout();
@@ -619,16 +619,16 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
                                row.dimension().wid = width;
                        } else if (is_rtl) {
                                row.dimension().wid = width;
-                               row.x += w;
+                               row.left_margin += w;
                        }
                        break;
                }
                case LYX_ALIGN_RIGHT:
-                       row.x += w;
+                       row.left_margin += w;
                        break;
                case LYX_ALIGN_CENTER:
                        row.dimension().wid = width - int(w / 2);
-                       row.x += w / 2;
+                       row.left_margin += w / 2;
                        break;
                case LYX_ALIGN_LEFT:
                case LYX_ALIGN_NONE:
@@ -639,21 +639,6 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
                }
        }
 
-#if 0
-       if (is_rtl) {
-               pos_type body_pos = par.beginOfBody();
-               pos_type end = row.endpos();
-
-               if (body_pos > 0
-                   && (body_pos > end || !par.isLineSeparator(body_pos - 1))) {
-                       row.x += theFontMetrics(text_->labelFont(par)).
-                               width(layout.labelsep);
-                       if (body_pos <= end)
-                               row.x += row.label_hfill;
-               }
-       }
-#endif
-
        // Finally,  handle hfill insets
        pos_type const endpos = row.endpos();
        pos_type body_pos = par.beginOfBody();
@@ -686,13 +671,13 @@ int TextMetrics::labelFill(pit_type const pit, Row const & row) const
        Paragraph const & par = text_->getPar(pit);
        LBUFERR(par.beginOfBody() > 0 || par.isEnvSeparator(0));
 
-       double w = 0;
+       int w = 0;
        Row::const_iterator cit = row.begin();
        Row::const_iterator const end = row.end();
        // iterate over elements before main body (except the last one,
        // which is extra space).
        while (cit!= end && cit->endpos < par.beginOfBody()) {
-               w += cit->width();
+               w += cit->dim.wid;
                ++cit;
        }
 
@@ -703,7 +688,7 @@ int TextMetrics::labelFill(pit_type const pit, Row const & row) const
        FontMetrics const & fm
                = theFontMetrics(text_->labelFont(par));
 
-       return max(0, fm.width(label) - int(w));
+       return max(0, fm.width(label) - w);
 }
 
 
@@ -803,8 +788,8 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit
        pos_type const body_pos = par.beginOfBody();
        row.clear();
        // This make get changed in computeRowMetrics depending on RTL
-       row.x = leftMargin(max_width_, pit, pos);
-       row.dimension().wid = int(row.x);
+       row.left_margin = leftMargin(max_width_, pit, pos);
+       row.dimension().wid = row.left_margin;
        row.right_margin = right_margin;
 
        if (pos >= end || row.width() > width) {
@@ -1117,25 +1102,25 @@ pos_type TextMetrics::getPosNearX(Row const & row, int & x,
        pos_type pos = row.pos();
        boundary = false;
        if (row.empty())
-               x = int(row.x);
-       else if (x <= row.x) {
+               x = row.left_margin;
+       else if (x <= row.left_margin) {
                pos = row.front().left_pos();
-               x = int(row.x);
+               x = row.left_margin;
        } else if (x >= row.width()) {
                pos = row.back().right_pos();
                x = row.width();
        } else {
-               double w = row.x;
+               double w = row.left_margin;
                Row::const_iterator cit = row.begin();
                Row::const_iterator cend = row.end();
                for ( ; cit != cend; ++cit) {
-                       if (w <= x &&  w + cit->width() > x) {
-                               double x_offset = x - w;
+                       if (w <= x &&  w + cit->full_width() > x) {
+                               int x_offset = int(x - w);
                                pos = cit->x2pos(x_offset);
                                x = int(x_offset + w);
                                break;
                        }
-                       w += cit->width();
+                       w += cit->full_width();
                }
                if (cit == row.end()) {
                        pos = row.back().right_pos();
@@ -1484,10 +1469,10 @@ int TextMetrics::cursorX(CursorSlice const & sl,
        if (row.empty()
            || (pos == row.begin()->left_pos()
                && pos != row.begin()->right_pos()))
-               return int(row.x);
+               return row.left_margin;
 
        Row::const_iterator cit = row.begin();
-       double x = row.x;
+       double x = row.left_margin;
        for ( ; cit != row.end() ; ++cit) {
                /** Look whether the cursor is inside the element's
                 * span. Note that it is necessary to take the
@@ -1500,7 +1485,7 @@ int TextMetrics::cursorX(CursorSlice const & sl,
                                x += cit->pos2x(pos);
                                break;
                }
-               x += cit->width();
+               x += cit->full_width();
        }
 
        return int(x);