* 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
This commit is contained in:
Abdelrazak Younes 2007-08-30 13:19:24 +00:00
parent 80df00006c
commit 97f66c07f6
3 changed files with 99 additions and 63 deletions

View File

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

View File

@ -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<BufferView *>(&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);
}
}

View File

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