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

Attachment: pgp3hZjr2LVO0.pgp
Description: PGP signature

Reply via email to