On Sat, Dec 17, 2005 at 05:23:35PM +0100, Lars Gullik Bjønnes wrote:
> Martin Vermeer <[EMAIL PROTECTED]> writes:
 
...
 
> | > .... but what are the indices in this vector... there seems to be an
> | > implicit connection here that is not obvious?
> | 
> | Yes... the row iterator counts in parallel with rowno. Not elegant but
> | works. Of course it wouldn't be impossible to use an iterator here
> | too... perhaps I'll try that.
> 
> Wouldn't the iterators be invalidated by a redoParagraph as well?

? I suppose we're not talking about the same thing. Or perhaps we are...
see attached patch + statement of disgust.
  
> Ok, leave this patch as if for now then.
>  
> | > (and would lessen the work of getting the rowList moved out of the
> | > paragraph).
> | 
> | Was that the plan? Sounds a bit ambitious for 1.4.0 :-)
> 
> No, not for 1.4, but if we can avoid creating more work for 1.5.

OK, valid argument.

Attached a patch that does most of what you ask. Also:

1) I give up on implementing the same inside insets. It turns out to
become very complex and probably impossible under the current
architecture. However, already this improves things already also inside
insets. One should remember that, e.g., branch insets can be many on a
paragraph. With this patch, only the one at the cursor will be
repainted, unlike before, when always (at least) the whole paragraph was
repainted. So: use many smaller branch insets, not one for the whole
paragraph.

2) BTW is it really true that pushing something to the
back of a <vector> (or other container), forcing a copy in memory to a
new location (?) will invalidate any iterators defined earlier to point
into it? This feels almost like assembly :-(

3) Oops... this patch lacks

///
typedef std::vector<lyx::size_type> RowSignature;

which I put in RowList_fwd.h... correct?


- 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 17 Dec 2005 18:16:27 -0000
@@ -81,7 +81,8 @@ 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_), rowSignature_(par.rowSignature_), 
+               layout_(par.layout_),
                text_(par.text_), begin_of_body_(par.begin_of_body_),
          pimpl_(new Paragraph::Pimpl(*par.pimpl_, this))
 {
@@ -107,6 +108,7 @@ Paragraph & Paragraph::operator=(Paragra
 
                rows_ = par.rows_;
                dim_ = par.dim_;
+               rowSignature_ = par.rowSignature_;
                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 17 Dec 2005 18:16:27 -0000
@@ -391,7 +391,9 @@ public:
        RowList & rows() { return rows_; }
        /// The painter and others use this
        RowList const & rows() const { return rows_; }
-
+       ///
+       RowSignature & rowSignature() const { return rowSignature_; }
+       
        /// LyXText::redoParagraph updates this
        Dimension & dim() { return dim_; }
 
@@ -408,6 +410,9 @@ private:
 
        ///
        mutable RowList rows_;
+       ///
+       mutable RowSignature rowSignature_;
+
        ///
        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        17 Dec 2005 18:16:27 -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,22 +728,68 @@ void paintPar
        theCoords.parPos()[&text][pit] = Point(x, y);
 
        y -= rb->ascent();
-       for (RowList::const_iterator rit = rb; rit != re; ++rit) {
+       RowSignature::iterator rsit = par.rowSignature().begin();
+       for (RowList::const_iterator rit = rb; rit != re; ++rit, ++rsit) {
                y += rit->ascent();
                bool const inside = (y + rit->descent() >= 0
                                       && y - rit->ascent() < ww);
                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 the cursor is inside
+               // an inset _on this row_.
+               bool cur_in_inset_in_row(false);
+               InsetList::const_iterator ii = par.insetlist.begin();
+               InsetList::const_iterator iend = par.insetlist.end();
+               for ( ; ii != iend; ++ii) {
+                       if (ii->pos >= rit->pos() && ii->pos < rit->endpos()
+                           && ii->inset->isTextInset() 
+                           && pi.base.bv->cursor().isInside(ii->inset))
+                               cur_in_inset_in_row = true;
+                               break;
+               }
+
+               if (rsit == par.rowSignature().end()) {
+                       par.rowSignature().push_back(0);
+                       // Disgusting C++. Pushing something onto a
+                       // vector invalidates iterators on it. Restore:
+                       rsit = par.rowSignature().end();
+                       --rsit;
+               }
+               // If selection is on, the current row signature differs from
+               // from cache, or cursor is inside an inset _on this row_, 
+               // then paint the row
+               if (select || *rsit != row_sig || cur_in_inset_in_row) {
+                       // Add to row signature cache
+                       *rsit = row_sig;
+
+                       // Clear background of this row 
+                       // (if paragraph 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());
+                       }
+                       
+                       // Instrumentation for testing row cache:
+                       //lyxerr << "#";
+                       rp.paintAppendix();
+                       rp.paintDepthBar();
+                       rp.paintChangeBar();
+                       if (rit == rb)
+                               rp.paintFirst();
+                       if (rit + 1 == re)
+                               rp.paintLast();
+                       rp.paintText();
+               }
        }
+       //lyxerr << "." << endl;
 }
 
 } // namespace anon
@@ -752,22 +799,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. Repaint is
+               // necessary even though paragraph signature did not change
+               if (!vi.singlepar)
+                       par.rowSignature().clear();
+               paintPar(pi, *bv.text(), pit, 0, yy, select);
+               yy += par.descent();
        }
 
        // Cache one paragraph above and one below
@@ -805,7 +857,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: pgp6WglotEzvw.pgp
Description: PGP signature

Reply via email to