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(); } }
pgp6WglotEzvw.pgp
Description: PGP signature