]> git.lyx.org Git - lyx.git/blobdiff - src/TextMetrics.cpp
Simplify redoParagraph by merging duplicate code
[lyx.git] / src / TextMetrics.cpp
index e69ffe9c225e77fc4581e0439ff564ac7091b0d2..2ce990b9d9f24cebbb995859d01685b34b118bd4 100644 (file)
@@ -437,6 +437,7 @@ bool TextMetrics::redoParagraph(pit_type const pit)
        par.setBeginOfBody();
        pos_type first = 0;
        size_t row_index = 0;
+       bool need_new_row = false;
        // maximum pixel width of a row
        do {
                if (row_index == pm.rows().size())
@@ -444,7 +445,7 @@ bool TextMetrics::redoParagraph(pit_type const pit)
                Row & row = pm.rows()[row_index];
                row.pit(pit);
                row.pos(first);
-               breakRow(row, right_margin, pit);
+               need_new_row = breakRow(row, right_margin, pit);
                setRowHeight(row, pit);
                row.setChanged(false);
                if (row_index || row.endpos() < par.size()
@@ -468,26 +469,11 @@ bool TextMetrics::redoParagraph(pit_type const pit)
 
                pm.dim().wid = max(pm.dim().wid, row.width());
                pm.dim().des += row.height();
-       } while (first < par.size());
+       } while (first < par.size() || need_new_row);
 
        if (row_index < pm.rows().size())
                pm.rows().resize(row_index);
 
-       // Make sure that if a par ends in newline, there is one more row
-       // under it
-       if (first > 0 && par.isNewline(first - 1)) {
-               if (row_index == pm.rows().size())
-                       pm.rows().push_back(Row());
-               Row & row = pm.rows()[row_index];
-               row.pos(first);
-               breakRow(row, right_margin, pit);
-               setRowHeight(row, pit);
-               row.setChanged(false);
-               int const max_row_width = max(dim_.wid, row.width());
-               computeRowMetrics(pit, row, max_row_width);
-               pm.dim().des += row.height();
-       }
-
        pm.dim().asc += pm.rows()[0].ascent();
        pm.dim().des -= pm.rows()[0].ascent();
 
@@ -786,7 +772,7 @@ private:
  * very sensitive to small changes :) Note that part of the
  * intelligence is also in Row::shortenIfNeeded.
  */
-void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit) const
+bool TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit) const
 {
        Paragraph const & par = text_->getPar(pit);
        pos_type const end = par.size();
@@ -806,7 +792,10 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit
        // the width available for the row.
        int const width = max_width_ - row.right_margin;
 
-       ParagraphList const & pars = text_->paragraphs();
+       if (pos >= end || row.width() > width) {
+               row.endpos(end);
+               return need_new_row;
+       }
 
 #if 0
        //FIXME: As long as leftMargin() is not correctly implemented for
@@ -900,6 +889,7 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit
        row.endpos(i);
 
        // End of paragraph marker
+       ParagraphList const & pars = text_->paragraphs();
        if (lyxrc.paragraph_markers && !need_new_row
            && i == end && size_type(pit + 1) < pars.size()) {
                // add a virtual element for the end-of-paragraph
@@ -921,6 +911,8 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit
        // make sure that the RTL elements are in reverse ordering
        row.reverseRTL(is_rtl);
        //LYXERR0("breakrow: row is " << row);
+
+       return need_new_row;
 }
 
 
@@ -1113,14 +1105,8 @@ pos_type TextMetrics::getPosNearX(Row const & row, int & x,
        int const xo = origin_.x_;
        x -= xo;
 
-       int offset = 0;
-       CursorSlice rowSlice(const_cast<InsetText &>(text_->inset()));
-       rowSlice.pit() = row.pit();
-       rowSlice.pos() = row.pos();
-
        // Adapt to cursor row scroll offset if applicable.
-       if (bv_->currentRowSlice() == rowSlice)
-               offset = bv_->horizScrollOffset();
+       int const offset = bv_->horizScrollOffset(text_, row.pit(), row.pos());
        x += offset;
 
        pos_type pos = row.pos();
@@ -1870,15 +1856,31 @@ void TextMetrics::draw(PainterInfo & pi, int x, int y) const
 
 void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const x, int y) const
 {
-       BufferParams const & bparams = bv_->buffer().params();
        ParagraphMetrics const & pm = par_metrics_[pit];
        if (pm.rows().empty())
                return;
-
-       bool const original_drawing_state = pi.pain.isDrawingEnabled();
-       int const ww = bv_->workHeight();
        size_t const nrows = pm.rows().size();
 
+       // Use fast lane when drawing is disabled.
+       if (!pi.pain.isDrawingEnabled()) {
+               for (size_t i = 0; i != nrows; ++i) {
+
+                       Row const & row = pm.rows()[i];
+                       // Adapt to cursor row scroll offset if applicable.
+                       int row_x = x - bv_->horizScrollOffset(text_, pit, row.pos());
+                       if (i)
+                               y += row.ascent();
+
+                       RowPainter rp(pi, *text_, pit, row, row_x, y);
+
+                       rp.paintOnlyInsets();
+                       y += row.descent();
+               }
+               return;
+       }
+
+       BufferParams const & bparams = bv_->buffer().params();
+       int const ww = bv_->workHeight();
        Cursor const & cur = bv_->cursor();
        DocIterator sel_beg = cur.selectionBegin();
        DocIterator sel_end = cur.selectionEnd();
@@ -1908,25 +1910,25 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
        for (size_t i = 0; i != nrows; ++i) {
 
                Row const & row = pm.rows()[i];
-               int row_x = x;
+               // Adapt to cursor row scroll offset if applicable.
+               int row_x = x - bv_->horizScrollOffset(text_, pit, row.pos());
                if (i)
                        y += row.ascent();
 
-               CursorSlice rowSlice(const_cast<InsetText &>(text_->inset()));
-               rowSlice.pit() = pit;
-               rowSlice.pos() = row.pos();
+               RowPainter rp(pi, *text_, pit, row, row_x, y);
 
+               // It is not needed to draw on screen if we are not inside.
                bool const inside = (y + row.descent() >= 0
                        && y - row.ascent() < ww);
-
-               // Adapt to cursor row scroll offset if applicable.
-               if (bv_->currentRowSlice() == rowSlice)
-                       row_x -= bv_->horizScrollOffset();
-
-               // It is not needed to draw on screen if we are not inside.
-               pi.pain.setDrawingEnabled(inside && original_drawing_state);
-
-               RowPainter rp(pi, *text_, pit, row, row_x, y);
+               pi.pain.setDrawingEnabled(inside);
+               if (!inside) {
+                       // Paint only the insets to set inset cache correctly
+                       // FIXME: remove paintOnlyInsets when we know that positions
+                       // have already been set.
+                       rp.paintOnlyInsets();
+                       y += row.descent();
+                       continue;
+               }
 
                if (selection)
                        row.setSelectionAndMargins(sel_beg_par, sel_end_par);
@@ -1943,10 +1945,9 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
                }
 
                // Row signature; has row changed since last paint?
-               if (pi.pain.isDrawingEnabled())
-                       row.setCrc(pm.computeRowSignature(row, bparams));
+               row.setCrc(pm.computeRowSignature(row, bparams));
                bool row_has_changed = row.changed()
-                       || rowSlice == bv_->lastRowSlice();
+                       || bv_->hadHorizScrollOffset(text_, pit, row.pos());
 
                // Take this opportunity to spellcheck the row contents.
                if (row_has_changed && pi.do_spellcheck && lyxrc.spellcheck_continuously) {
@@ -1975,7 +1976,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
 
                // Instrumentation for testing row cache (see also
                // 12 lines lower):
-               if (lyxerr.debugging(Debug::PAINTING) && inside
+               if (lyxerr.debugging(Debug::PAINTING)
                        && (row.selection() || pi.full_repaint || row_has_changed)) {
                                string const foreword = text_->isMainText() ?
                                        "main text redraw " : "inset text redraw: ";
@@ -2013,7 +2014,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
                pi.full_repaint = tmp;
        }
        // Re-enable screen drawing for future use of the painter.
-       pi.pain.setDrawingEnabled(original_drawing_state);
+       pi.pain.setDrawingEnabled(true);
 
        //LYXERR(Debug::PAINTING, ".");
 }