On Fri, Dec 16, 2005 at 04:36:15PM +0100, Jean-Marc Lasgouttes wrote: > >>>>> "Martin" == Martin Vermeer <[EMAIL PROTECTED]> writes: > Then, what could be done is have redoParagraph keep the old list (in a > oldrows struct) and for each new row created set a 'clean' flag if it > is identical to the old one (meaning there is no need to redraw). It > will not work exactly like that (because there may be several > redoParagraph calls between screen redraws), but the idea should work > and avoid the signature. the clean flag should probably be a ticker of > some sort to be able to say: "this is the same row as was painted by > screen draw number 1456".
Hmmm. I looked at something like that and it became quickly very complicated. > >> I am not sure I understand your argument about insets containing > >> text. > > Martin> The point is that an inset in a paragraph will be painted only > Martin> if it is encountered as part of the painting operation for > Martin> that paragraph. This means that if you want to selectively > Martin> paint only some row, you must make sure that _at least those > Martin> rows_ that contain insets with internal paragraphs are painted > Martin> anyway. > > Martin> This matters only when the cursor is inside such an inset. > > So why don't you test on that condition? I am sure there is some > cursor/iterator helper that can tell you whether cursor is in some > inset. Great idea! And works too. Remarkably simple. BTW do you know of an easy way to test whether the cursor is in a given lyxtext? I would need that later on. > >> 20 seconds down to 8-9 seconds > > Martin> Great news! I think this is the way to go then. > > Indeed :) > > I won't have time to try it out before Monday, unfortunately. > > JMarc Attached an again somewhat simpler patch. Life is good ;-) - Martin
Index: paragraph.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph.C,v retrieving revision 1.417 diff -u -p -r1.417 paragraph.C --- paragraph.C 25 Nov 2005 14:40:34 -0000 1.417 +++ paragraph.C 16 Dec 2005 18:11:47 -0000 @@ -81,7 +81,7 @@ Paragraph::Paragraph() Paragraph::Paragraph(Paragraph const & par) : itemdepth(par.itemdepth), insetlist(par.insetlist), dim_(par.dim_), - rows_(par.rows_), layout_(par.layout_), + rows_(par.rows_), row_sig_(par.row_sig_), layout_(par.layout_), text_(par.text_), begin_of_body_(par.begin_of_body_), pimpl_(new Paragraph::Pimpl(*par.pimpl_, this)) { @@ -107,6 +107,7 @@ Paragraph & Paragraph::operator=(Paragra rows_ = par.rows_; dim_ = par.dim_; + row_sig_ = par.row_sig_; layout_ = par.layout(); text_ = par.text_; begin_of_body_ = par.begin_of_body_; Index: paragraph.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph.h,v retrieving revision 1.157 diff -u -p -r1.157 paragraph.h --- paragraph.h 7 Sep 2005 10:36:59 -0000 1.157 +++ paragraph.h 16 Dec 2005 18:11:47 -0000 @@ -391,7 +391,9 @@ public: RowList & rows() { return rows_; } /// The painter and others use this RowList const & rows() const { return rows_; } - + /// + std::vector<lyx::size_type> & row_sig() const { return row_sig_; } + /// LyXText::redoParagraph updates this Dimension & dim() { return dim_; } @@ -408,6 +410,9 @@ private: /// mutable RowList rows_; + /// + mutable std::vector<lyx::size_type> row_sig_; + /// LyXLayout_ptr layout_; /** Index: rowpainter.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/rowpainter.C,v retrieving revision 1.159 diff -u -p -r1.159 rowpainter.C --- rowpainter.C 2 Dec 2005 13:20:26 -0000 1.159 +++ rowpainter.C 16 Dec 2005 18:11:47 -0000 @@ -713,7 +713,8 @@ void RowPainter::paintText() void paintPar - (PainterInfo & pi, LyXText const & text, pit_type pit, int x, int y) + (PainterInfo & pi, LyXText const & text, pit_type pit, int x, int y, + bool select) { // lyxerr << " paintPar: pit: " << pit << " at y: " << y << endl; static NullPainter nop; @@ -727,6 +728,7 @@ void paintPar theCoords.parPos()[&text][pit] = Point(x, y); y -= rb->ascent(); + lyx::size_type rowno = 0; for (RowList::const_iterator rit = rb; rit != re; ++rit) { y += rit->ascent(); bool const inside = (y + rit->descent() >= 0 @@ -734,14 +736,45 @@ void paintPar RowPainter rp(inside ? pi : nullpi, text, pit, *rit, x, y); y += rit->descent(); - rp.paintAppendix(); - rp.paintDepthBar(); - rp.paintChangeBar(); - if (rit == rb) - rp.paintFirst(); - if (rit + 1 == re) - rp.paintLast(); - rp.paintText(); + + // Row signature; has row changed since last paint? + lyx::size_type const row_sig + = rit->endpos() - rit->pos() + 1000 * y; + + // The following code figures out if this row contains + // insets containing their own rows. + + // cursor inside an inset: + bool inside_inset = pi.base.bv->cursor().depth() > 1; + + if (rowno >= par.row_sig().size()) + par.row_sig().push_back(0); + // If selection is on, the current row signature differs + // from cache, or this row contains insets (with + // possibly pars), then paint this row + if (select || par.row_sig()[rowno] != row_sig || inside_inset) { + // Add to row signature cache + par.row_sig()[rowno] = row_sig; + + // Clear background of this row (par background was + // not cleared) + if (!select) { + int ht = rit->ascent() + rit->descent(); + pi.pain.fillRectangle(x, y - ht, + pi.base.bv->workWidth(), ht, + text.backgroundColor()); + } + + rp.paintAppendix(); + rp.paintDepthBar(); + rp.paintChangeBar(); + if (rit == rb) + rp.paintFirst(); + if (rit + 1 == re) + rp.paintLast(); + rp.paintText(); + } + ++rowno; } } @@ -752,22 +785,27 @@ void paintText(BufferView const & bv, Vi { Painter & pain = bv.painter(); LyXText * const text = bv.text(); + bool const select = bv.cursor().selection(); - // clear background - pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1, - LColor::background); - - // draw selection PainterInfo pi(const_cast<BufferView *>(&bv), pain); - - text->drawSelection(pi, 0, 0); + if (select) { + // Clear background (Delegated to rows if no selection) + pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1, + text->backgroundColor()); + text->drawSelection(pi, 0, 0); + } int yy = vi.y1; // draw contents for (pit_type pit = vi.p1; pit <= vi.p2; ++pit) { - yy += text->getPar(pit).ascent(); - paintPar(pi, *bv.text(), pit, 0, yy); - yy += text->getPar(pit).descent(); + Paragraph const & par = text->getPar(pit); + yy += par.ascent(); + // This handles scroll page up - page down. + // Must be repainted though signature unchanged + if (!vi.singlepar) + par.row_sig().clear(); + paintPar(pi, *bv.text(), pit, 0, yy, select); + yy += par.descent(); } // Cache one paragraph above and one below @@ -805,7 +843,7 @@ void paintTextInset(LyXText const & text y -= text.getPar(0).ascent(); for (int pit = 0; pit < int(text.paragraphs().size()); ++pit) { y += text.getPar(pit).ascent(); - paintPar(pi, text, pit, x, y); + paintPar(pi, text, pit, x, y, true); y += text.getPar(pit).descent(); } }
pgp3hZjr2LVO0.pgp
Description: PGP signature