On Wed, 2005-12-14 at 10:59 -0500, Bennett Helm wrote:
> On Dec 14, 2005, at 10:51 AM, Jean-Marc Lasgouttes wrote:
> 
> >>>>>> "Angus" == Angus Leeming <[EMAIL PROTECTED]> writes:
> >
> > Angus> Do I read top-down correctly as saying that one half of all
> > Angus> LyX's processing time is spent in doTextTask?
> >
> > Yes, drawing seems to be very slow with Qt/Mac.
> 
> But this doesn't explain why the same version of Qt/Mac together with  
> lyx-1.3.x is relatively speedy! With lyx-1.3.x, there's no lag *at  
> all* in typing into even very large paragraphs, into large insets  
> embedded within large paragraphs, etc. I don't think this can be the  
> explanation of the speed problem in lyx-1.4.0.

So I gave it another try... see attached. This is essentially based upon
the 'row signature' approach mentioned by Jean-Marc in a later post.

What I did wrong in the earlier singlerow patch was, that I tested for
the presence of an inset in the current paragraph by seeing if insetlist
was empty. (This must be done because rows containing insets containing
further text _must be rendered_ in order to render the inside text
through recursive descent.) Now unfortunately almost any paragraph in a
typical text contains _some_ inset, if only a double quote or so.

So I had to make the inset testing more refined. Now the code traverses
the inset list looking for HIGHLY_EDITABLE insets, the only ones that
can contain inner text. While at it, I did this test for every row
separately. Testing with lyxerr-instrumented code in rowpainter showed
this to be highly effective. LyX even _feels_ faster with this patch,
even on Linux.

Currently this is implemented only for "outer" paragraphs, not text
inside an inset. If it does the job, I know precisely what to do to get
also the latter working. 

So Bennett, if I may bother you once again to test this for a huge
paragraph _not inside an inset_. If it works, I will extend it for
insets, and the patch can then be included with the Mac binaries to be
published, if at this point we don't want to risk it with 1.4.0. After
all this is a serious regression for one platform.

Oh, and you should have the earlier lyxfunc patch included as well for
testing.

- Martin

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 09:29:36 -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();
+	unsigned rowno = 0;
 	for (RowList::const_iterator rit = rb; rit != re; ++rit) {
 		y += rit->ascent();
 		bool const inside = (y + rit->descent() >= 0
@@ -734,14 +736,52 @@ 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?
+		unsigned row_sig = rit->endpos() - rit->pos() + y;
+
+		// The following code figures out if this row contains
+		// insets containing their own rows.
+		bool insetinrow(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->editable() == InsetBase::HIGHLY_EDITABLE)
+				insetinrow = true;
+		}
+
+		// If selection is on, the current row signature differs
+		// from cache (or no cache entry), or this row contains
+		// insets (with possibly pars), then paint this row
+		if (select || rowno >= par.row_sig().size() 
+		    || par.row_sig()[rowno] != row_sig 
+		    || insetinrow) {
+			// Add to row signature cache
+			if (rowno >= par.row_sig().size())
+				par.row_sig().push_back(row_sig);
+			else
+				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(0, 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,21 +792,25 @@ void paintText(BufferView const & bv, Vi
 {
 	Painter & pain = bv.painter();
 	LyXText * const text = bv.text();
-
-	// clear background
-	pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1,
-			   LColor::background);
-
-	// draw selection
+	bool select = bv.cursor().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);
+		// This handles scroll page up - page down.
+		// Must be repainted though signature unchanged
+		if (!vi.singlepar)
+			text->getPar(pit).row_sig().clear();
+		paintPar(pi, *bv.text(), pit, 0, yy, select);
 		yy += text->getPar(pit).descent();
 	}
 
@@ -805,7 +849,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();
 	}
 }
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 09:29:37 -0000
@@ -71,7 +71,7 @@ ParagraphList::ParagraphList()
 
 
 Paragraph::Paragraph()
-	: begin_of_body_(0), pimpl_(new Paragraph::Pimpl(this))
+	: row_sig_(0), begin_of_body_(0), pimpl_(new Paragraph::Pimpl(this))
 {
 	itemdepth = 0;
 	params().clear();
@@ -80,8 +80,8 @@ Paragraph::Paragraph()
 
 Paragraph::Paragraph(Paragraph const & par)
 	:	itemdepth(par.itemdepth), insetlist(par.insetlist),
-		dim_(par.dim_),
-		rows_(par.rows_), layout_(par.layout_),
+		dim_(par.dim_), 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))
 {
@@ -110,7 +110,8 @@ Paragraph & Paragraph::operator=(Paragra
 		layout_ = par.layout();
 		text_ = par.text_;
 		begin_of_body_ = par.begin_of_body_;
-
+		row_sig_ = par.row_sig_;
+		
 		delete pimpl_;
 		pimpl_ = new Pimpl(*par.pimpl_, this);
 	}
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 09:29:37 -0000
@@ -391,7 +391,9 @@ public:
 	RowList & rows() { return rows_; }
 	/// The painter and others use this
 	RowList const & rows() const { return rows_; }
-
+	///
+	std::vector<unsigned> & row_sig() const { return row_sig_; }
+	
 	/// LyXText::redoParagraph updates this
 	Dimension & dim() { return dim_; }
 
@@ -401,6 +403,8 @@ public:
 public:
 	///
 	InsetList insetlist;
+	///
+	bool breakFlag;
 
 private:
 	/// cached dimensions of paragraph
@@ -408,6 +412,9 @@ private:
 
 	///
 	mutable RowList rows_;
+	///
+	mutable std::vector<unsigned> row_sig_;
+
 	///
 	LyXLayout_ptr layout_;
 	/**

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to