par.setBeginOfBody();
pos_type first = 0;
size_t row_index = 0;
+ bool need_new_row = false;
// maximum pixel width of a row
do {
if (row_index == pm.rows().size())
Row & row = pm.rows()[row_index];
row.pit(pit);
row.pos(first);
- breakRow(row, right_margin, pit);
+ need_new_row = breakRow(row, right_margin, pit);
setRowHeight(row, pit);
row.setChanged(false);
if (row_index || row.endpos() < par.size()
pm.dim().wid = max(pm.dim().wid, row.width());
pm.dim().des += row.height();
- } while (first < par.size());
+ } while (first < par.size() || need_new_row);
if (row_index < pm.rows().size())
pm.rows().resize(row_index);
- // Make sure that if a par ends in newline, there is one more row
- // under it
- if (first > 0 && par.isNewline(first - 1)) {
- if (row_index == pm.rows().size())
- pm.rows().push_back(Row());
- Row & row = pm.rows()[row_index];
- row.pos(first);
- breakRow(row, right_margin, pit);
- setRowHeight(row, pit);
- row.setChanged(false);
- int const max_row_width = max(dim_.wid, row.width());
- computeRowMetrics(pit, row, max_row_width);
- pm.dim().des += row.height();
- }
-
pm.dim().asc += pm.rows()[0].ascent();
pm.dim().des -= pm.rows()[0].ascent();
* very sensitive to small changes :) Note that part of the
* intelligence is also in Row::shortenIfNeeded.
*/
-void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit) const
+bool TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit) const
{
Paragraph const & par = text_->getPar(pit);
pos_type const end = par.size();
// the width available for the row.
int const width = max_width_ - row.right_margin;
- ParagraphList const & pars = text_->paragraphs();
+ if (pos >= end || row.width() > width) {
+ row.endpos(end);
+ return need_new_row;
+ }
#if 0
//FIXME: As long as leftMargin() is not correctly implemented for
row.endpos(i);
// End of paragraph marker
+ ParagraphList const & pars = text_->paragraphs();
if (lyxrc.paragraph_markers && !need_new_row
&& i == end && size_type(pit + 1) < pars.size()) {
// add a virtual element for the end-of-paragraph
// make sure that the RTL elements are in reverse ordering
row.reverseRTL(is_rtl);
//LYXERR0("breakrow: row is " << row);
+
+ return need_new_row;
}
void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const x, int y) const
{
- BufferParams const & bparams = bv_->buffer().params();
ParagraphMetrics const & pm = par_metrics_[pit];
if (pm.rows().empty())
return;
-
- bool const original_drawing_state = pi.pain.isDrawingEnabled();
- int const ww = bv_->workHeight();
size_t const nrows = pm.rows().size();
+ // Use fast lane when drawing is disabled.
+ if (!pi.pain.isDrawingEnabled()) {
+ for (size_t i = 0; i != nrows; ++i) {
+
+ Row const & row = pm.rows()[i];
+ // Adapt to cursor row scroll offset if applicable.
+ int row_x = x - bv_->horizScrollOffset(text_, pit, row.pos());
+ if (i)
+ y += row.ascent();
+
+ RowPainter rp(pi, *text_, pit, row, row_x, y);
+
+ rp.paintOnlyInsets();
+ y += row.descent();
+ }
+ return;
+ }
+
+ BufferParams const & bparams = bv_->buffer().params();
+ int const ww = bv_->workHeight();
Cursor const & cur = bv_->cursor();
DocIterator sel_beg = cur.selectionBegin();
DocIterator sel_end = cur.selectionEnd();
RowPainter rp(pi, *text_, pit, row, row_x, y);
+ // It is not needed to draw on screen if we are not inside.
bool const inside = (y + row.descent() >= 0
&& y - row.ascent() < ww);
- // It is not needed to draw on screen if we are not inside.
- pi.pain.setDrawingEnabled(inside && original_drawing_state);
+ pi.pain.setDrawingEnabled(inside);
+ if (!inside) {
+ // Paint only the insets to set inset cache correctly
+ // FIXME: remove paintOnlyInsets when we know that positions
+ // have already been set.
+ rp.paintOnlyInsets();
+ y += row.descent();
+ continue;
+ }
if (selection)
row.setSelectionAndMargins(sel_beg_par, sel_end_par);
}
// Row signature; has row changed since last paint?
- if (pi.pain.isDrawingEnabled())
- row.setCrc(pm.computeRowSignature(row, bparams));
+ row.setCrc(pm.computeRowSignature(row, bparams));
bool row_has_changed = row.changed()
|| bv_->hadHorizScrollOffset(text_, pit, row.pos());
// Instrumentation for testing row cache (see also
// 12 lines lower):
- if (lyxerr.debugging(Debug::PAINTING) && inside
+ if (lyxerr.debugging(Debug::PAINTING)
&& (row.selection() || pi.full_repaint || row_has_changed)) {
string const foreword = text_->isMainText() ?
"main text redraw " : "inset text redraw: ";
pi.full_repaint = tmp;
}
// Re-enable screen drawing for future use of the painter.
- pi.pain.setDrawingEnabled(original_drawing_state);
+ pi.pain.setDrawingEnabled(true);
//LYXERR(Debug::PAINTING, ".");
}