From 97f66c07f6202d004259c0a634c8fab675148e57 Mon Sep 17 00:00:00 2001 From: Abdelrazak Younes Date: Thu, 30 Aug 2007 13:19:24 +0000 Subject: [PATCH] * RowPainter: - paintOnlyInsets(): new public method for inset painting only in case the inset dimension didn't change within a Row. - paintInset(): put out everything not strictly related to the inset painting itself. - paintHfill(): new private method to cut the reduce code in paintText(). * TextMetrics::drawParagraph(): use paintOnlyInsets() when the Row text nor it's dimension changed. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19912 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/TextMetrics.cpp | 70 +++++++++++++++++++---------------- src/rowpainter.cpp | 89 +++++++++++++++++++++++++++++---------------- src/rowpainter.h | 5 ++- 3 files changed, 100 insertions(+), 64 deletions(-) diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 5dd582195a..6eb1bc1ace 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -1001,43 +1001,51 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y, y -= rb->ascent(); for (RowList::const_iterator rit = rb; rit != re; ++rit) { y += rit->ascent(); + + bool const inside = (y + rit->descent() >= 0 + && y - rit->ascent() < ww); + // it is not needed to draw on screen if we are not inside. + pi.pain.setDrawingEnabled(inside); + RowPainter rp(pi, *text_, pit, *rit, bidi, x, y); + // Row signature; has row changed since last paint? bool row_has_changed = rit->changed(); + + if (!repaintAll && !row_has_changed) { + // Paint the only the insets if the text itself is + // unchanged. + rp.paintOnlyInsets(); + y += rit->descent(); + continue; + } // Paint the row if a full repaint has been requested or it has // changed. - if (repaintAll || row_has_changed) { - bool const inside = (y + rit->descent() >= 0 - && y - rit->ascent() < ww); - // it is not needed to draw on screen if we are not inside. - pi.pain.setDrawingEnabled(inside); - RowPainter rp(pi, *text_, pit, *rit, bidi, x, y); - // Clear background of this row - // (if paragraph background was not cleared) - if (!repaintAll && row_has_changed) - pi.pain.fillRectangle(x, y - rit->ascent(), - width(), rit->height(), - text_->backgroundColor()); - - // Instrumentation for testing row cache (see also - // 12 lines lower): - if (lyxerr.debugging(Debug::PAINTING)) { - if (text_->isMainText(bv_->buffer())) - LYXERR(Debug::PAINTING) << "#" << - repaintAll << row_has_changed; - else - LYXERR(Debug::PAINTING) << "[" << - repaintAll << row_has_changed << "]"; - } - rp.paintAppendix(); - rp.paintDepthBar(); - rp.paintChangeBar(); - if (rit == rb) - rp.paintFirst(); - rp.paintText(); - if (rit + 1 == re) - rp.paintLast(); + // Clear background of this row + // (if paragraph background was not cleared) + if (!repaintAll && row_has_changed) + pi.pain.fillRectangle(x, y - rit->ascent(), + width(), rit->height(), + text_->backgroundColor()); + + // Instrumentation for testing row cache (see also + // 12 lines lower): + if (lyxerr.debugging(Debug::PAINTING)) { + if (text_->isMainText(bv_->buffer())) + LYXERR(Debug::PAINTING) << "#" << + repaintAll << row_has_changed << "#"; + else + LYXERR(Debug::PAINTING) << "[" << + repaintAll << row_has_changed << "]"; } + rp.paintAppendix(); + rp.paintDepthBar(); + rp.paintChangeBar(); + if (rit == rb) + rp.paintFirst(); + rp.paintText(); + if (rit + 1 == re) + rp.paintLast(); y += rit->descent(); } // Re-enable screen drawing for future use of the painter. diff --git a/src/rowpainter.cpp b/src/rowpainter.cpp index 68330aa744..cc62656efc 100644 --- a/src/rowpainter.cpp +++ b/src/rowpainter.cpp @@ -87,17 +87,44 @@ int RowPainter::leftMargin() const } +void RowPainter::paintHfill(pos_type const pos, pos_type const body_pos) +{ + x_ += 1; + + int const y0 = yo_; + int const y1 = y0 - defaultRowHeight() / 2; + + pain_.line(int(x_), y1, int(x_), y0, Color::added_space); + + if (par_.hfillExpansion(row_, pos)) { + int const y2 = (y0 + y1) / 2; + + if (pos >= body_pos) { + pain_.line(int(x_), y2, int(x_ + row_.hfill), y2, + Color::added_space, + Painter::line_onoffdash); + x_ += row_.hfill; + } else { + pain_.line(int(x_), y2, int(x_ + row_.label_hfill), y2, + Color::added_space, + Painter::line_onoffdash); + x_ += row_.label_hfill; + } + pain_.line(int(x_), y1, int(x_), y0, Color::added_space); + } + x_ += 2; +} + + // If you want to debug inset metrics uncomment the following line: //#define DEBUG_METRICS // This draws green lines around each inset. -void RowPainter::paintInset(pos_type & vpos) +void RowPainter::paintInset(Inset const * inset, pos_type const pos) { - pos_type const pos = bidi_.vis2log(vpos); Font font = text_.getFont(bv_.buffer(), par_, pos); - Inset const * inset = par_.getInset(pos); BOOST_ASSERT(inset); PainterInfo pi(const_cast(&bv_), pain_); // FIXME: We should always use font, see documentation of @@ -107,12 +134,10 @@ void RowPainter::paintInset(pos_type & vpos) font; pi.ltr_pos = (bidi_.level(pos) % 2 == 0); pi.erased_ = erased_ || par_.isDeleted(pos); - bv_.coordCache().insets().add(inset, int(x_), yo_); // insets are painted completely. Recursive inset->drawSelection(pi, int(x_), yo_); inset->draw(pi, int(x_), yo_); - ++vpos; paintForeignMark(x_, font, inset->descent()); x_ += inset->width(); @@ -634,6 +659,25 @@ void RowPainter::paintLast() } +void RowPainter::paintOnlyInsets() +{ + pos_type const end = row_.endpos(); + for (pos_type pos = row_.pos(); pos != end; ++pos) { + if (!par_.isInset(pos)) + continue; + + // If outer row has changed, nested insets are repaint completely. + Inset const * inset = par_.getInset(pos); + + if (x_ > bv_.workWidth()) + continue; + + x_ = bv_.coordCache().getInsets().x(inset); + paintInset(inset, pos); + } +} + + void RowPainter::paintText() { pos_type const end = row_.endpos(); @@ -726,46 +770,27 @@ void RowPainter::paintText() } if (par_.isHfill(pos)) { - x_ += 1; - - int const y0 = yo_; - int const y1 = y0 - defaultRowHeight() / 2; - - pain_.line(int(x_), y1, int(x_), y0, Color::added_space); - - if (par_.hfillExpansion(row_, pos)) { - int const y2 = (y0 + y1) / 2; - - if (pos >= body_pos) { - pain_.line(int(x_), y2, int(x_ + row_.hfill), y2, - Color::added_space, - Painter::line_onoffdash); - x_ += row_.hfill; - } else { - pain_.line(int(x_), y2, int(x_ + row_.label_hfill), y2, - Color::added_space, - Painter::line_onoffdash); - x_ += row_.label_hfill; - } - pain_.line(int(x_), y1, int(x_), y0, Color::added_space); - } - x_ += 2; + paintHfill(pos, body_pos); ++vpos; } else if (par_.isSeparator(pos)) { - Font orig_font = text_.getFont(bv_.buffer(), par_, pos); + Font orig_font = text_.getFont(buffer, par_, pos); double const orig_x = x_; x_ += width_pos; if (pos >= body_pos) x_ += row_.separator; - ++vpos; paintForeignMark(orig_x, orig_font); + ++vpos; } else if (par_.isInset(pos)) { // If outer row has changed, nested insets are repaint completely. - paintInset(vpos); + Inset const * inset = par_.getInset(pos); + bv_.coordCache().insets().add(inset, int(x_), yo_); + paintInset(inset, pos); + ++vpos; } else { + // paint as many characters as possible. paintFromPos(vpos); } } diff --git a/src/rowpainter.h b/src/rowpainter.h index b036904133..aa550627c6 100644 --- a/src/rowpainter.h +++ b/src/rowpainter.h @@ -21,6 +21,7 @@ namespace lyx { class Bidi; class BufferView; class Font; +class Inset; class PainterInfo; class Paragraph; class ParagraphList; @@ -50,6 +51,7 @@ public: void paintFirst(); void paintLast(); void paintText(); + void paintOnlyInsets(); private: void paintForeignMark(double orig_x, Font const & font, int desc = 0); @@ -59,7 +61,8 @@ private: bool hebrew, bool arabic); int paintAppendixStart(int y); void paintFromPos(pos_type & vpos); - void paintInset(pos_type & vpos); + void paintInset(Inset const * inset, pos_type const pos); + void paintHfill(pos_type const pos, pos_type const body_pos); /// return left margin int leftMargin() const; -- 2.39.5