On Thu, Dec 22, 2005 at 06:23:26PM +0100, Jean-Marc Lasgouttes wrote:
> >>>>> "David" == David Green <[EMAIL PROTECTED]> writes:
> 
> David> On 12/22/05 7:41 AM, "Jean-Marc Lasgouttes"
> David> <[EMAIL PROTECTED]>
> David> wrote:
> 
> >>>>>>> "Martin" == Martin Vermeer <[EMAIL PROTECTED]> writes:
> >>
> Martin> Is crc32 invariant for character transposition?
> >>  Sure.
> 
> David> Erm, crc32 should produce a different result when characters
> David> are transposed.
> 
> Yes, that's what I meant, sorry.
> 
> So my answer was supposed to be "of course not."

That is what I wanted to hear...

Attached, finally, the corrected version of the patch using crc32. Turns
out y isn't needed here after all.

- Martin

Index: RowList_fwd.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/RowList_fwd.h,v
retrieving revision 1.6
diff -u -p -r1.6 RowList_fwd.h
--- RowList_fwd.h       31 Jan 2005 16:29:38 -0000      1.6
+++ RowList_fwd.h       29 Dec 2005 20:58:34 -0000
@@ -15,6 +15,7 @@
 #include "lyxrow.h"
 
 #include <vector>
+#include <map>
 
 /**
  * Each paragraph is broken up into a number of rows on the screen.
@@ -22,5 +23,7 @@
  * downwards.
  */
 typedef std::vector<Row> RowList;
+///
+typedef std::map<lyx::size_type, lyx::size_type> RowSignature;
 
 #endif
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 29 Dec 2005 20:58:35 -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 29 Dec 2005 20:58:35 -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.160
diff -u -p -r1.160 rowpainter.C
--- rowpainter.C        17 Dec 2005 15:03:39 -0000      1.160
+++ rowpainter.C        29 Dec 2005 20:58:36 -0000
@@ -40,6 +40,8 @@
 
 #include "support/textutils.h"
 
+#include <boost/crc.hpp>
+
 using lyx::pos_type;
 using lyx::pit_type;
 
@@ -717,7 +719,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 repaintAll)
 {
 //     lyxerr << "  paintPar: pit: " << pit << " at y: " << y << endl;
        static NullPainter nop;
@@ -731,22 +734,67 @@ void paintPar
        theCoords.parPos()[&text][pit] = Point(x, y);
 
        y -= rb->ascent();
-       for (RowList::const_iterator rit = rb; rit != re; ++rit) {
+       lyx::size_type rowno(0);
+       for (RowList::const_iterator rit = rb; rit != re; ++rit, ++rowno) {
                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?
+               boost::crc_32_type crc;
+               for (lyx::pos_type i = rit->pos(); i < rit->endpos(); ++i) {
+                       const unsigned char b[] = { par.getChar(i) };
+                       crc.process_bytes(b, 1);
+               }                   
+               lyx::size_type const row_sig = crc.checksum();
+
+               // 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 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 (repaintAll || par.rowSignature()[rowno] != row_sig 
+                          || cur_in_inset_in_row) {
+                       // Add to row signature cache
+                       par.rowSignature()[rowno] = row_sig;
+
+                       // Clear background of this row 
+                       // (if paragraph background was not cleared)
+                       if (!repaintAll) {
+                               int ht = rit->ascent() + rit->descent();
+                               pi.pain.fillRectangle(x, y - ht, 
+                                   pi.base.bv->workWidth(), ht, 
+                                   text.backgroundColor());
+                       }
+                       
+                       // Instrumentation for testing row cache (see also
+                       // 12 lines lower):
+                       //lyxerr << "#";
+                       rp.paintAppendix();
+                       rp.paintDepthBar();
+                       rp.paintChangeBar();
+                       if (rit == rb)
+                               rp.paintFirst();
+                       if (rit + 1 == re)
+                               rp.paintLast();
+                       rp.paintText();
+               }
        }
+       //lyxerr << "." << endl;
 }
 
 } // namespace anon
@@ -756,22 +804,25 @@ 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 || !vi.singlepar) {
+               // Clear background (Delegated to rows if no selection)
+               pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1,
+                       text->backgroundColor());
+       }
+       if (select) {
+               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();
+               paintPar(pi, *bv.text(), pit, 0, yy, select || !vi.singlepar);
+               yy += par.descent();
        }
 
        // Cache one paragraph above and one below
@@ -809,7 +860,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: pgpmI4Zu3R95q.pgp
Description: PGP signature

Reply via email to