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_) {
signature.asc
Description: This is a digitally signed message part