* 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
This commit is contained in:
Abdelrazak Younes 2007-11-06 14:07:49 +00:00
parent f9dd4b000e
commit 0b0c27ef59
5 changed files with 58 additions and 34 deletions

View File

@ -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);
// 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;
// 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);
}

View File

@ -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;
}

View File

@ -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_;

View File

@ -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_);

View File

@ -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();