From: Abdelrazak Younes Date: Tue, 6 Nov 2007 14:07:49 +0000 (+0000) Subject: * BufferView: Make use of ScreenUpdateStrategy::NoScreenUpdate, avoid a screen redraw... X-Git-Tag: 1.6.10~7456 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=0b0c27ef59296e461a2de84b23430fb0c034be1d;p=lyx.git * BufferView: Make use of ScreenUpdateStrategy::NoScreenUpdate, avoid a screen redraw when it is not really needed. * Painter.h: move isDrawingEnabled() to public Area. * TextMetrics::drawParagraph(): backup and restore original drawing state of the Painter. * InsetTabular::draw(): ditto. * InsetMathNest::drawSelection(): ditto. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@21471 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/BufferView.cpp b/src/BufferView.cpp index f612e69d67..c9afa72693 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -1334,6 +1334,8 @@ Update::flags BufferView::dispatch(FuncRequest const & cmd) updateMetrics(); //FIXME: updateMetrics() does not update paragraph position // This is done at draw() time. So we need a redraw! + // But no screen update is needed. + d->metrics_info_.update_strategy = NoScreenUpdate; buffer_.changed(); p = getPos(cur, cur.boundary()); } @@ -1361,6 +1363,8 @@ Update::flags BufferView::dispatch(FuncRequest const & cmd) cur.forwardInset(); } // FIXME: we need to do a redraw again because of the selection + // But no screen update is needed. + d->metrics_info_.update_strategy = NoScreenUpdate; buffer_.changed(); updateFlags = Update::Force | Update::FitCursor; break; @@ -2084,41 +2088,56 @@ Point BufferView::getPos(DocIterator const & dit, bool boundary) const void BufferView::draw(frontend::Painter & pain) { + LYXERR(Debug::PAINTING) << "\t\t*** START DRAWING ***" << endl; + Text & text = buffer_.text(); + TextMetrics const & tm = d->text_metrics_[&text]; + int const y = d->metrics_info_.y1 + + tm.parMetrics(d->metrics_info_.p1).ascent(); PainterInfo pi(this, pain); - // Should the whole screen, including insets, be refreshed? - // FIXME: We should also distinguish DecorationUpdate to avoid text - // drawing if possible. This is not possible to do easily right now - // because of the single backing pixmap. - pi.full_repaint = d->metrics_info_.update_strategy != SingleParUpdate; - if (pi.full_repaint) + switch (d->metrics_info_.update_strategy) { + + case NoScreenUpdate: + // If no screen painting is actually needed, only some the different + // coordinates of insets and paragraphs needs to be updated. + pi.pain.setDrawingEnabled(false); + pi.full_repaint = true; + break; + + case SingleParUpdate: + // Only the current outermost paragraph will be redrawn. + pi.full_repaint = false; + tm.drawParagraph(pi, d->metrics_info_.p1, 0, y); + break; + + case DecorationUpdate: + // FIXME: We should also distinguish DecorationUpdate to avoid text + // drawing if possible. This is not possible to do easily right now + // because of the single backing pixmap. + + case FullScreenUpdate: + // The whole screen, including insets, will be refreshed. + pi.full_repaint = true; + // Clear background (if not delegated to rows) pain.fillRectangle(0, d->metrics_info_.y1, width_, d->metrics_info_.y2 - d->metrics_info_.y1, buffer_.inset().backgroundColor()); - - LYXERR(Debug::PAINTING) << "\t\t*** START DRAWING ***" << endl; - Text & text = buffer_.text(); - TextMetrics const & tm = d->text_metrics_[&text]; - int y = d->metrics_info_.y1 + tm.parMetrics(d->metrics_info_.p1).ascent(); - if (!pi.full_repaint) - tm.drawParagraph(pi, d->metrics_info_.p1, 0, y); - else tm.draw(pi, 0, y); - LYXERR(Debug::PAINTING) << "\n\t\t*** END DRAWING ***" << endl; - // and grey out above (should not happen later) -// lyxerr << "par ascent: " << text.getPar(d->metrics_info_.p1).ascent() << endl; - if (d->metrics_info_.y1 > 0 - && d->metrics_info_.update_strategy == FullScreenUpdate) - pain.fillRectangle(0, 0, width_, d->metrics_info_.y1, Color_bottomarea); - - // and possibly grey out below -// lyxerr << "par descent: " << text.getPar(d->metrics_info_.p1).ascent() << endl; - if (d->metrics_info_.y2 < height_ - && d->metrics_info_.update_strategy == FullScreenUpdate) - pain.fillRectangle(0, d->metrics_info_.y2, width_, - height_ - d->metrics_info_.y2, Color_bottomarea); + // and grey out above (should not happen later) + if (d->metrics_info_.y1 > 0) + pain.fillRectangle(0, 0, width_, + d->metrics_info_.y1, Color_bottomarea); + + // and possibly grey out below + if (d->metrics_info_.y2 < height_) + pain.fillRectangle(0, d->metrics_info_.y2, width_, + height_ - d->metrics_info_.y2, Color_bottomarea); + break; + } + + LYXERR(Debug::PAINTING) << "\n\t\t*** END DRAWING ***" << endl; } diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index a99589a2a7..93c5297f04 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -1925,6 +1925,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co Bidi bidi; + bool const original_drawing_state = pi.pain.isDrawingEnabled(); + y -= rb->ascent(); for (RowList::const_iterator rit = rb; rit != re; ++rit) { y += rit->ascent(); @@ -1932,7 +1934,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co 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); + pi.pain.setDrawingEnabled(inside && original_drawing_state); RowPainter rp(pi, *text_, pit, *rit, bidi, x, y); // Row signature; has row changed since last paint? @@ -1998,7 +2000,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co pi.full_repaint = tmp; } // Re-enable screen drawing for future use of the painter. - pi.pain.setDrawingEnabled(true); + pi.pain.setDrawingEnabled(original_drawing_state); //LYXERR(Debug::PAINTING) << "." << endl; } diff --git a/src/frontends/Painter.h b/src/frontends/Painter.h index 55256cc006..6eca5a9f5f 100644 --- a/src/frontends/Painter.h +++ b/src/frontends/Painter.h @@ -144,6 +144,9 @@ public: void setDrawingEnabled(bool drawing_enabled = true) { drawing_enabled_ = drawing_enabled; } + /// Indicate wether real screen drawing shall be done or not. + bool isDrawingEnabled() const { return drawing_enabled_; } + /// draw a char at position x, y (y is the baseline) /** * \return the width of the drawn text. @@ -188,9 +191,6 @@ protected: /// draw a bevelled button border void buttonFrame(int x, int y, int w, int h); - /// Indicate wether real screen drawing shall be done or not. - bool isDrawingEnabled() const { return drawing_enabled_; } - private: /// bool drawing_enabled_; diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index a0c0317927..9a32bfd510 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -3013,6 +3013,8 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const x += scx_; x += ADD_TO_TABULAR_WIDTH; + bool const original_drawing_state = pi.pain.isDrawingEnabled(); + idx_type idx = 0; first_visible_cell = Tabular::npos; for (row_type i = 0; i < tabular.rowCount(); ++i) { @@ -3036,7 +3038,7 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const pi.pain.setDrawingEnabled(false); cell(idx)->draw(pi, cx, y); drawCellLines(pi.pain, nx, y, i, idx, pi.erased_); - pi.pain.setDrawingEnabled(true); + pi.pain.setDrawingEnabled(original_drawing_state); } else { cell(idx)->draw(pi, cx, y); drawCellLines(pi.pain, nx, y, i, idx, pi.erased_); diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp index 13732bcc4b..8dd278cac4 100644 --- a/src/mathed/InsetMathNest.cpp +++ b/src/mathed/InsetMathNest.cpp @@ -246,9 +246,10 @@ void InsetMathNest::drawSelection(PainterInfo & pi, int x, int y) const return; // FIXME: hack to get position cache warm + bool const original_drawing_state = pi.pain.isDrawingEnabled(); pi.pain.setDrawingEnabled(false); draw(pi, x, y); - pi.pain.setDrawingEnabled(true); + pi.pain.setDrawingEnabled(original_drawing_state); CursorSlice s1 = cur.selBegin(); CursorSlice s2 = cur.selEnd();