On Thu, 2005-12-22 at 08:24 +0200, Martin Vermeer wrote:
> On Wed, Dec 21, 2005 at 10:24:33PM +0200, Martin Vermeer wrote:
> > On Wed, Dec 21, 2005 at 01:46:53PM -0500, Bennett Helm wrote:
> > > On Dec 21, 2005, at 9:01 AM, Bennett Helm wrote:
> 
> ...
>  
> > BTW I did manage to extend the patch to include text inside insets.
> > Attached. You will see that there are still some rendering 'warts', but
> > I live in hope. The logic seems to be correct.
> 
> Actually there are more serious logic problems still... just try to
> insert an inset... 

Here's a slightly better patch. Doesn't crash anymore in my attempts...

The problem was calling update() from insetcollapsable's metric.
Apparently you cannot do that, and update the coord cache while it is in
use. But something like that is needed... bad rendering bugs when
switching between inlined and ordinary open.

Jean-Marc, I think it is safe to assume that we do not want *this* in
1.4.0... what about the limited patch, with a better signature?

- 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	22 Dec 2005 11:32:00 -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: BufferView.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.C,v
retrieving revision 1.264
diff -u -p -r1.264 BufferView.C
--- BufferView.C	1 Dec 2005 10:28:47 -0000	1.264
+++ BufferView.C	22 Dec 2005 11:32:00 -0000
@@ -369,6 +369,30 @@ void BufferView::putSelectionAt(DocItera
 }
 
 
+bool const BufferView::refresh() const
+{ 
+	return pimpl_->refresh(); 
+}
+
+	
+void const BufferView::refresh(bool r) const
+{ 
+	pimpl_->refresh(r);
+}
+
+
+bool const BufferView::refreshInside() const
+{ 
+	return pimpl_->refreshInside();
+}
+
+	
+void const BufferView::refreshInside(bool r) const
+{ 
+	pimpl_->refreshInside(r);
+}
+
+
 LCursor & BufferView::cursor()
 {
 	return pimpl_->cursor_;
Index: BufferView.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.h,v
retrieving revision 1.189
diff -u -p -r1.189 BufferView.h
--- BufferView.h	1 Dec 2005 10:28:47 -0000	1.189
+++ BufferView.h	22 Dec 2005 11:32:00 -0000
@@ -198,7 +198,14 @@ public:
 	 */
 	void putSelectionAt(DocIterator const & cur,
 		int length, bool backwards);
-
+	///
+	bool const refresh() const;
+	///
+	void const refresh(bool r) const;
+	///
+	bool const refreshInside() const;
+	///
+	void const refreshInside(bool r) const;
 
 private:
 	///
Index: BufferView_pimpl.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.h,v
retrieving revision 1.129
diff -u -p -r1.129 BufferView_pimpl.h
--- BufferView_pimpl.h	7 Nov 2005 15:06:42 -0000	1.129
+++ BufferView_pimpl.h	22 Dec 2005 11:32:01 -0000
@@ -103,6 +103,14 @@ public:
 	FuncStatus getStatus(FuncRequest const & cmd);
 	/// a function should be executed
 	bool dispatch(FuncRequest const & ev);
+	///
+	bool refresh() { return refresh_; }
+	///
+	void refresh(bool r) {refresh_ = r; }
+	///
+	bool refreshInside() { return refresh_inside_; }
+	///
+	void refreshInside(bool r) {refresh_inside_ = r; }
 private:
 	/// An error list (replaces the error insets)
 	ErrorList errorlist_;
@@ -189,7 +197,10 @@ private:
 	int offset_ref_;
 	///
 	ViewMetricsInfo metrics(bool singlepar = false);
-
-
+	/// Working variable indicating a full screen refresh
+	mutable bool refresh_;
+	/// Inside insets
+	mutable bool refresh_inside_;
+	
 };
 #endif // BUFFERVIEW_PIMPL_H
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	22 Dec 2005 11:32:01 -0000
@@ -37,6 +37,7 @@
 #include "frontends/Painter.h"
 
 #include "insets/insettext.h"
+#include "insets/insetcollapsable.h"
 
 #include "support/textutils.h"
 
@@ -158,7 +159,17 @@ void RowPainter::paintInset(pos_type con
 	pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0);
 	pi.erased_ = erased_ || isDeletedText(par_, pos);
 	theCoords.insets().add(inset, int(x_), yo_);
-	inset->drawSelection(pi, int(x_), yo_);
+	 // For general textinsets, force inner refresh
+	bool openInsetOnly = (row_.endpos() - row_.pos() == 1);
+	if (inset->isTextInset()) {
+		InsetCollapsable const * in = 
+			static_cast<InsetCollapsable const *>(inset);
+		openInsetOnly &= in->isOpen() && !in->inlined();
+	}
+	if (!openInsetOnly)
+		bv_.refreshInside(true);
+	if (bv_.refreshInside())
+		inset->drawSelection(pi, int(x_), yo_);
 	inset->draw(pi, int(x_), yo_);
 	x_ += inset->width();
 }
@@ -713,13 +724,14 @@ 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;
 	static PainterInfo nullpi(pi.base.bv, nop);
 	int const ww = pi.base.bv->workHeight();
-
+	
 	Paragraph const & par = text.paragraphs()[pit];
 
 	RowList::const_iterator const rb = par.rows().begin();
@@ -734,15 +746,70 @@ 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 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
+		lyx::size_type rowno = std::distance(rit, rb);
+		if (repaintAll || par.rowSignature()[rowno] != row_sig 
+			   || cur_in_inset_in_row) {
+			// Add to row signature cache
+			par.rowSignature()[rowno] = row_sig;
+
+			// Signals if this row contains a single open inset
+			// and nothing more
+			bool openInsetOnly = (rit->endpos() - rit->pos() == 1)
+			    && par.isInset(rit->pos())
+			    && par.getInset(rit->pos())->isTextInset();
+			if (openInsetOnly) {
+				InsetCollapsable const * in =
+				    static_cast<InsetCollapsable const *>(par.getInset(rit->pos()));
+				openInsetOnly = in->isOpen() && !in->inlined();
+			}
+
+			// Clear background of this row 
+			// (if whole screen background was not cleared)
+			if (!repaintAll && !openInsetOnly) {
+				// Try to keep row background inside inset
+				// frame (how?)
+				int w = pi.base.bv->workWidth() - 30;
+				int ht = rit->ascent() + rit->descent();
+				pi.pain.fillRectangle(x, y - ht, w, 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
@@ -752,22 +819,29 @@ 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);
+	// Should the whole screen, including insets, be refreshed?
+	bv.refresh(select || !vi.singlepar);
+	bv.refreshInside(bv.refresh());
+	if (bv.refresh()) {
+		// Clear background 
+		// (Delegated to rows if no forced screen refresh)
+		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, bv.refresh());
+		yy += par.descent();
 	}
 
 	// Cache one paragraph above and one below
@@ -805,7 +879,8 @@ 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);
+		// For general textinsets, force inner refresh
+		paintPar(pi, text, pit, x, y, pi.base.bv->refreshInside());
 		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	22 Dec 2005 11:32:02 -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	22 Dec 2005 11:32:02 -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: insets/insetcollapsable.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.C,v
retrieving revision 1.281
diff -u -p -r1.281 insetcollapsable.C
--- insets/insetcollapsable.C	16 Dec 2005 12:48:18 -0000	1.281
+++ insets/insetcollapsable.C	22 Dec 2005 11:32:02 -0000
@@ -139,7 +139,9 @@ void InsetCollapsable::metrics(MetricsIn
 		if (status() == Open) {
 			InsetText::metrics(mi, textdim_);
 			bool oldopeninlined = openinlined_;
-			openinlined_ = (textdim_.wid + dim.wid <= mi.base.textwidth);
+			openinlined_ = 
+			    textdim_.wid + dim.wid <= 0.7 * mi.base.textwidth
+			    && textdim_.height() < 1.5 * dim.height();
 			if (openinlined_ != oldopeninlined)
 				InsetText::metrics(mi, textdim_);
 			if (openinlined_) {
Index: insets/insettext.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettext.C,v
retrieving revision 1.622
diff -u -p -r1.622 insettext.C
--- insets/insettext.C	21 Oct 2005 09:55:23 -0000	1.622
+++ insets/insettext.C	22 Dec 2005 11:32:02 -0000
@@ -192,6 +192,7 @@ void InsetText::draw(PainterInfo & pi, i
 	// update our idea of where we are
 	setPosCache(pi, x, y);
 
+	text_.background_color_ = backgroundColor();
 	text_.draw(pi, x + border_, y);
 
 	if (drawFrame_) {

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

Reply via email to