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.
}
+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
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();
}
+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();
}
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);
}
}