Jürgen Spitzmüller wrote:
the remaining po and doc changes can immediately be committed.
What about this? I've been using it for quite a while now and I didn't see any problem.
Abdel.
Index: BufferView.cpp =================================================================== --- BufferView.cpp (revision 20845) +++ 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 20845) +++ 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 20845) +++ 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 20845) +++ 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 20845) +++ 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 20845) +++ 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 20845) +++ 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 20845) +++ 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 20845) +++ 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 20845) +++ rowpainter.cpp (working copy) @@ -75,6 +75,7 @@ void paintChangeBar(); void paintFirst(); void paintLast(); + void paintOnlyInsets(); void paintText(); int maxWidth() { return max_width_; } @@ -193,15 +194,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 +733,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 +897,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 +906,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 +929,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 +969,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 20845) +++ 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; }