Adam Treverrow wrote:

It's faster if you turn preview on!

Yes, that certainly helps -thanks. Collapsing floats and notes also helps, but typing within an existing paragraph of text can still result in excessive lag, which is a problem when editing text. I didn't notice any improvement with Richard's suggestion to alter the window size.

1.5.3 will hopefully see improvements WRT this problem (especially when typing within Inset). If you are able to compile from source, try this patch after retrieving the BRANCH_1_5_X svn branch (it might also apply cleanly to 1.5.2 source).

Abdel.
Index: BufferView.cpp
===================================================================
--- BufferView.cpp      (revision 21185)
+++ BufferView.cpp      (working copy)
@@ -1482,13 +1482,19 @@
 
        // If the paragraph metrics has changed, we can not
        // use the singlepar optimisation.
-       if (singlepar
+       if (singlepar) {
+               pit_type const bottom_pit = cursor_.bottom().pit();
+               int old_height = tm.parMetrics(bottom_pit).height();
                // In Single Paragraph mode, rebreak only
                // the (main text, not inset!) paragraph containing the cursor.
                // (if this paragraph contains insets etc., rebreaking will
                // recursively descend)
-               && tm.redoParagraph(cursor_.bottom().pit()))
-               singlepar = false;
+               tm.redoParagraph(bottom_pit);
+               // Paragraph height has changed so we cannot proceed to
+               // the singlePar optimisation.
+               if (tm.parMetrics(bottom_pit).height() != old_height)
+                       singlepar = false;
+       }
 
        pit_type const pit = anchor_ref_;
        int pit1 = pit;
Index: insets/InsetCaption.h
===================================================================
--- insets/InsetCaption.h       (revision 21185)
+++ insets/InsetCaption.h       (working copy)
@@ -59,8 +59,6 @@
        ///
        virtual bool getStatus(Cursor & cur, FuncRequest const & cmd, 
FuncStatus &) const;
        ///
-       virtual bool wide() const { return false; }
-       ///
        int latex(Buffer const & buf, odocstream & os,
                  OutputParams const &) const;
        ///
Index: insets/InsetCollapsable.cpp
===================================================================
--- insets/InsetCollapsable.cpp (revision 21185)
+++ insets/InsetCollapsable.cpp (working copy)
@@ -158,13 +158,10 @@
                dim = dimensionCollapsed();
                if (status() == Open) {
                        InsetText::metrics(mi, textdim_);
-                       // This expression should not contain mi.base.texwidth
                        openinlined_ = !hasFixedWidth()
-                               && textdim_.wid < 0.5 * mi.base.bv->workWidth();
+                               && (textdim_.wid + dim.wid) <= 
mi.base.textwidth;
                        if (openinlined_) {
-                               // Correct for button width, and re-fit
-                               mi.base.textwidth -= dim.wid;
-                               InsetText::metrics(mi, textdim_);
+                               // Correct for button width
                                dim.wid += textdim_.wid;
                                dim.des = max(dim.des - textdim_.asc + dim.asc, 
textdim_.des);
                                dim.asc = textdim_.asc;
Index: insets/InsetFloat.h
===================================================================
--- insets/InsetFloat.h (revision 21185)
+++ insets/InsetFloat.h (working copy)
@@ -61,8 +61,6 @@
        ///
        Inset::Code lyxCode() const { return Inset::FLOAT_CODE; }
        ///
-       virtual bool wide() const { return false; }
-       ///
        int latex(Buffer const &, odocstream &,
                  OutputParams const &) const;
        ///
Index: insets/InsetOptArg.h
===================================================================
--- insets/InsetOptArg.h        (revision 21185)
+++ insets/InsetOptArg.h        (working copy)
@@ -31,8 +31,6 @@
        Inset::Code lyxCode() const { return Inset::OPTARG_CODE; }
        /// return an message upon editing
        virtual docstring const editMessage() const;
-       ///
-       virtual bool wide() const { return false; }
 
        /// Standard LaTeX output -- short-circuited
        int latex(Buffer const &, odocstream &,
Index: insets/InsetText.cpp
===================================================================
--- insets/InsetText.cpp        (revision 21185)
+++ insets/InsetText.cpp        (working copy)
@@ -78,7 +78,7 @@
 
 
 InsetText::InsetText(BufferParams const & bp)
-       : drawFrame_(false), frame_color_(Color::insetframe)
+       : drawFrame_(false), frame_color_(Color::insetframe), 
fixed_width_(false)
 {
        paragraphs().push_back(Paragraph());
        paragraphs().back().layout(bp.getTextClass().defaultLayout());
@@ -90,7 +90,7 @@
 
 
 InsetText::InsetText(InsetText const & in)
-       : Inset(in), text_()
+       : Inset(in), text_(), fixed_width_(fixed_width_)
 {
        text_.autoBreakRows_ = in.text_.autoBreakRows_;
        drawFrame_ = in.drawFrame_;
@@ -174,10 +174,13 @@
        font_ = mi.base.font;
        // Hand font through to contained lyxtext:
        text_.font_ = mi.base.font;
+       // Expand the inset if
+       fixed_width_ = text_.paragraphs().size() > 1;
        if (hasFixedWidth())
                tm.metrics(mi, dim, mi.base.textwidth);
        else
                tm.metrics(mi, dim);
+       fixed_width_ |= tm.parMetrics(0).rows().size() > 1;
        dim.asc += border_;
        dim.des += border_;
        dim.wid += 2 * border_;
@@ -203,7 +206,7 @@
                int const a = tm.ascent() + border_;
                int const h = a + tm.descent() + border_;
                pi.pain.rectangle(x, y - a,
-                                 ((wide() || hasFixedWidth()) ? tm.maxWidth() 
: w),
+                                 (hasFixedWidth() ? tm.maxWidth() : w),
                                  h, frameColor());
        }
 }
@@ -217,24 +220,12 @@
        int const a = tm.ascent() + border_;
        int const h = a + tm.descent() + border_;
        pi.pain.fillRectangle(x, y - a,
-                             ((wide() || hasFixedWidth()) ? tm.maxWidth() : w),
+                             (hasFixedWidth() ? tm.maxWidth() : w),
                              h, backgroundColor());
        text_.drawSelection(pi, x + border_, y);
 }
 
 
-bool InsetText::covers(BufferView const & bv, int x, int y) const
-{
-       TextMetrics const & tm = bv.textMetrics(&text_);
-
-       return bv.coordCache().getInsets().has(this)
-                       && x >= xo(bv)
-                       && x <= xo(bv) + width() + (wide() ? tm.maxWidth() : 0)
-                       && y >= yo(bv) - ascent()
-                       && y <= yo(bv) + descent();
-}
-
-
 docstring const InsetText::editMessage() const
 {
        return _("Opened Text Inset");
@@ -347,13 +338,6 @@
 }
 
 
-bool InsetText::notifyCursorLeaves(Cursor & cur) { 
-       if(wide()) 
-               cur.updateFlags(cur.disp_.update() | Update::Force); 
-       return false; 
-} 
-
-
 void InsetText::cursorPos(BufferView const & bv,
                CursorSlice const & sl, bool boundary, int & x, int & y) const
 {
Index: insets/InsetText.h
===================================================================
--- insets/InsetText.h  (revision 21185)
+++ insets/InsetText.h  (working copy)
@@ -42,6 +42,8 @@
        explicit InsetText(BufferParams const &);
        ///
        InsetText();
+       ///
+       bool hasFixedWidth() const { return fixed_width_; }
 
        /// empty inset to empty par
        void clear();
@@ -55,8 +57,6 @@
        void draw(PainterInfo & pi, int x, int y) const;
        /// draw inset selection
        void drawSelection(PainterInfo & pi, int x, int y) const;
-       /// are we inside the area covered by the inset?
-       virtual bool covers(BufferView const & bv, int x, int y) const;
        ///
        virtual docstring const editMessage() const;
        ///
@@ -75,9 +75,6 @@
        int docbook(Buffer const &, odocstream &, OutputParams const &) const;
        ///
        void validate(LaTeXFeatures & features) const;
-       //FIXME The following should be removed when wide is.
-       /// Overridden to force an update if the inset was wide().
-       virtual bool notifyCursorLeaves(Cursor & cur);
 
        /// return x,y of given position relative to the inset's baseline
        void cursorPos(BufferView const & bv, CursorSlice const & sl,
@@ -137,10 +134,6 @@
        bool neverIndent(Buffer const &) const;
        ///
        InsetText(InsetText const &);
-       ///
-       virtual bool wide() const { return wide_inset_; }
-       ///
-       void setWide(bool wide_inset) { wide_inset_ = wide_inset; }
 
 protected:
        ///
@@ -160,8 +153,9 @@
        int frame_color_;
        ///
        mutable pit_type old_pit;
-       ///
-       bool wide_inset_;
+       /// Does the inset has fixed width?
+       /// Allow horizontal maximization of the inset.
+       mutable bool fixed_width_;
 
 public:
        ///
Index: ParagraphMetrics.cpp
===================================================================
--- ParagraphMetrics.cpp        (revision 21185)
+++ ParagraphMetrics.cpp        (working copy)
@@ -88,18 +88,27 @@
 }
 
 
-size_type ParagraphMetrics::calculateRowSignature(Row const & row)
+size_type ParagraphMetrics::calculateRowSignature(Row const & row,
+               BufferParams const & bparams) const
 {
        boost::crc_32_type crc;
        for (pos_type i = row.pos(); i < row.endpos(); ++i) {
                char_type const b[] = { par_->getChar(i) };
                crc.process_bytes(b, 1);
+               if (bparams.trackChanges) {
+                       Change change = par_->lookupChange(i);
+                       char_type const b[] = { change.type };
+                       crc.process_bytes(b, 1);
+               }                       
        }
+       char_type const b[] = { row.width(), row.ascent(), row.descent()};
+       crc.process_bytes(b, 3);
        return crc.checksum();
 }
 
 
-void ParagraphMetrics::updateRowChangeStatus()
+void ParagraphMetrics::updateRowChangeStatus(
+               BufferParams const & bparams) const
 {
        size_t const size = rows_.size();
        row_change_status_.resize(size);
@@ -107,7 +116,7 @@
 
        for (size_t i = 0; i != size; ++i) {
                // Row signature; has row changed since last update?
-               size_type const row_sig = calculateRowSignature(rows_[i]);
+               size_type const row_sig = calculateRowSignature(rows_[i], 
bparams);
                row_change_status_[i] = row_signature_[i] != row_sig;
                row_signature_[i] = row_sig;
        }
Index: ParagraphMetrics.h
===================================================================
--- ParagraphMetrics.h  (revision 21185)
+++ ParagraphMetrics.h  (working copy)
@@ -71,7 +71,7 @@
        std::vector<bool> const & rowChangeStatus() const
        { return row_change_status_; }
        ///
-       void updateRowChangeStatus();
+       void updateRowChangeStatus(BufferParams const &) const;
        ///
        int rightMargin(Buffer const & buffer) const;
 
@@ -82,13 +82,13 @@
        ///
        typedef std::vector<size_type> RowSignature;
        ///
-       size_type calculateRowSignature(Row const &);
+       size_type calculateRowSignature(Row const &, BufferParams const &) 
const;
        ///
        mutable RowList rows_;
        ///
-       RowSignature row_signature_;
+       mutable RowSignature row_signature_;
        ///
-       std::vector<bool> row_change_status_;
+       mutable std::vector<bool> row_change_status_;
        /// cached dimensions of paragraph
        Dimension dim_;
        ///
Index: rowpainter.cpp
===================================================================
--- rowpainter.cpp      (revision 21185)
+++ rowpainter.cpp      (working copy)
@@ -75,8 +75,9 @@
        void paintChangeBar();
        void paintFirst();
        void paintLast();
+       void paintOnlyInsets();
        void paintText();
-       int maxWidth() { return max_width_; }
+       int maxWidth() { return text_metrics_.width(); }
 
 private:
        void paintForeignMark(double orig_x, Font const & font, int desc = 0);
@@ -112,7 +113,6 @@
        pit_type const pit_;
        Paragraph const & par_;
        ParagraphMetrics const & pm_;
-       int max_width_;
 
        /// bidi cache, comes from outside the rowpainter because
        /// rowpainters are normally created in a for loop and there only
@@ -140,8 +140,7 @@
          pars_(text.paragraphs()),
          row_(row), pit_(pit), par_(text.paragraphs()[pit]),
          pm_(text_metrics_.parMetrics(pit)),
-         max_width_(bv_.workWidth()),
-               bidi_(bidi), erased_(pi.erased_),
+         bidi_(bidi), erased_(pi.erased_),
          xo_(x), yo_(y), width_(text_metrics_.width())
 {
        RowMetrics m = text_metrics_.computeRowMetrics(pit_, row_);
@@ -168,7 +167,8 @@
 
 int RowPainter::leftMargin() const
 {
-       return text_.leftMargin(*bv_.buffer(), max_width_, pit_, row_.pos());
+       return text_.leftMargin(*bv_.buffer(), text_metrics_.width(),
+               pit_, row_.pos());
 }
 
 
@@ -193,15 +193,16 @@
        int const x1 = int(x_);
 #endif
        bv_.coordCache().insets().add(inset, int(x_), yo_);
-       InsetText const * const in = inset->asTextInset();
-       // non-wide insets are painted completely. Recursive
+       // Backup refreshInside (modified recursively below)
        bool tmp = refreshInside;
-       if (!in || !in->wide()) {
+       InsetText const * in = inset->asTextInset();
+       // non fixed-width text insets are painted completely.
+       if (!in || !in->hasFixedWidth())
                refreshInside = true;
-       }
        if (refreshInside)
                inset->drawSelection(pi, int(x_), yo_);
        inset->draw(pi, int(x_), yo_);
+       // Restore refreshInside.
        refreshInside = tmp;
        x_ += inset->width();
 #ifdef DEBUG_METRICS
@@ -731,6 +732,25 @@
 }
 
 
+void RowPainter::paintOnlyInsets()
+{
+       pos_type const end = row_.endpos();
+       for (pos_type pos = row_.pos(); pos != end; ++pos) {
+               if (!par_.isInset(pos))
+                       continue;
+
+               if (x_ > bv_.workWidth())
+                       continue;
+
+               // If outer row has changed, nested insets are repaint 
completely.
+               Inset const * inset = par_.getInset(pos);
+               x_ = bv_.coordCache().getInsets().x(inset);
+               pos_type vpos = pos;
+               paintFromPos(vpos); // vpos is modified by paintFromPos.
+       }
+}
+
+
 void RowPainter::paintText()
 {
        pos_type const end = row_.endpos();
@@ -876,68 +896,6 @@
 }
 
 
-bool CursorOnRow(PainterInfo & pi, pit_type const pit,
-       RowList::const_iterator rit, Text const & text)
-{
-       // Is there a cursor on this row (or inside inset on row)
-       Cursor & cur = pi.base.bv->cursor();
-       for (size_type d = 0; d < cur.depth(); ++d) {
-               CursorSlice const & sl = cur[d];
-               if (sl.text() == &text
-                   && sl.pit() == pit
-                   && sl.pos() >= rit->pos()
-                   && sl.pos() <= rit->endpos())
-                       return true;
-       }
-       return false;
-}
-
-
-bool innerCursorOnRow(PainterInfo & pi, pit_type pit,
-       RowList::const_iterator rit, Text const & text)
-{
-       // Is there a cursor inside an inset on this row, and is this inset
-       // the only "character" on this row
-       Cursor & cur = pi.base.bv->cursor();
-       if (rit->pos() + 1 != rit->endpos())
-               return false;
-       for (size_type d = 0; d < cur.depth(); d++) {
-               CursorSlice const & sl = cur[d];
-               if (sl.text() == &text
-                   && sl.pit() == pit
-                   && sl.pos() == rit->pos())
-                       return d < cur.depth() - 1;
-       }
-       return false;
-}
-
-
-// FIXME: once wide() is obsolete, remove this as well!
-bool inNarrowInset(PainterInfo & pi)
-{
-       // check whether the current inset is nested in a non-wide inset
-       Cursor & cur = pi.base.bv->cursor();
-       Inset const * cur_in = &cur.inset();
-       // check all higher nested insets
-       for (size_type i = 1; i < cur.depth(); ++i) {
-               Inset * const in = &cur[i].inset();
-               if (in == cur_in)
-                       // we reached the level of the current inset, so stop
-                       return false;
-               else if (in) {
-                       if (in->hasFixedWidth())
-                               return true;
-                       InsetText * t =
-                               const_cast<InsetText *>(in->asTextInset());
-                       if (t && !t->wide())
-                               // OK, we are in a non-wide() inset
-                               return true;
-               }
-       }
-       return false;
-}
-
-
 void paintPar
        (PainterInfo & pi, Text const & text, pit_type pit, int x, int y,
         bool repaintAll)
@@ -947,10 +905,12 @@
 
        pi.base.bv->coordCache().parPos()[&text][pit] = Point(x, y);
 
-       Paragraph const & par = text.paragraphs()[pit];
        ParagraphMetrics const & pm = pi.base.bv->parMetrics(&text, pit);
        if (pm.rows().empty())
                return;
+       // Update the row change statuses. The painter will need that info
+       // in order to know which row has to be repainted.
+       pm.updateRowChangeStatus(pi.base.bv->buffer()->params());
 
        RowList::const_iterator const rb = pm.rows().begin();
        RowList::const_iterator const re = pm.rows().end();
@@ -968,49 +928,20 @@
                // Row signature; has row changed since last paint?
                bool row_has_changed = pm.rowChangeStatus()[rowno];
 
-               bool cursor_on_row = CursorOnRow(pi, pit, rit, text);
-               bool in_inset_alone_on_row =
-                       innerCursorOnRow(pi, pit, rit, text);
-               bool leftEdgeFixed =
-                       (par.getAlign() == LYX_ALIGN_LEFT ||
-                        par.getAlign() == LYX_ALIGN_BLOCK);
-               bool inNarrowIns = inNarrowInset(pi);
+               bool const inside = (y + rit->descent() >= 0
+                       && y - rit->ascent() < ww);
+               // it is not needed to draw on screen if we are not inside.
+               pi.pain.setDrawingEnabled(inside);
+               RowPainter rp(pi, text, pit, *rit, bidi, x, y);
 
-               // If this is the only object on the row, we can make it wide
-               //
-               // FIXME: there is a const_cast here because paintPar() is not 
supposed
-               // to touch the paragraph contents. So either we move this 
"wide"
-               // property out of InsetText or we localize the feature to the 
painting
-               // done here.
-               // JSpitzm: We should aim at removing wide() altogether while 
retaining
-               // typing speed within insets.
-               for (pos_type i = rit->pos() ; i != rit->endpos(); ++i) {
-                       Inset const * const in = par.getInset(i);
-                       if (in) {
-                               InsetText * t = const_cast<InsetText 
*>(in->asTextInset());
-                               if (t)
-                                       t->setWide(in_inset_alone_on_row
-                                                  && leftEdgeFixed
-                                                  && !inNarrowIns);
-                       }
-               }
-
-               // If selection is on, the current row signature differs
-               // from cache, or cursor is inside an inset _on this row_,
-               // then paint the row
-               if (repaintAll || row_has_changed || cursor_on_row) {
-                       bool const inside = (y + rit->descent() >= 0
-                               && y - rit->ascent() < ww);
-                       // it is not needed to draw on screen if we are not 
inside.
-                       pi.pain.setDrawingEnabled(inside);
-                       RowPainter rp(pi, text, pit, *rit, bidi, x, y);
+               // If selection is on if the current row signature differs
+               // from cache, then paint the row.
+               if (repaintAll || row_has_changed) {
                        // Clear background of this row
                        // (if paragraph background was not cleared)
-                       if (!repaintAll &&
-                           (!(in_inset_alone_on_row && leftEdgeFixed && 
!inNarrowIns)
-                               || row_has_changed)) {
+                       if (!repaintAll && row_has_changed) {
                                pi.pain.fillRectangle(x, y - rit->ascent(),
-                                   rp.maxWidth(), rit->height(),
+                                       rp.maxWidth(), rit->height(),
                                    text.backgroundColor());
                                // If outer row has changed, force nested
                                // insets to repaint completely
@@ -1037,7 +968,9 @@
                        rp.paintText();
                        if (rit + 1 == re)
                                rp.paintLast();
-               }
+               } else
+                       rp.paintOnlyInsets();
+
                y += rit->descent();
                // Restore, see above
                refreshInside = tmp;
Index: TextMetrics.cpp
===================================================================
--- TextMetrics.cpp     (revision 21185)
+++ TextMetrics.cpp     (working copy)
@@ -263,14 +263,10 @@
        // redoParagraph() recursively inside parMetrics.
        Dimension old_dim = parMetrics(pit, false).dim();
 
-       changed |= old_dim.height() != pm.dim().height();
+       changed |= old_dim != pm.dim();
 
        par_metrics_[pit] = pm;
 
-       // Update the row change statuses. The painter will need that info
-       // in order to know which row has to be repainted.
-       par_metrics_[pit].updateRowChangeStatus();
-
        return changed;
 }
 

Reply via email to