]> git.lyx.org Git - features.git/commitdiff
Simplify single par drawing:
authorAbdelrazak Younes <younes@lyx.org>
Sat, 17 Nov 2007 11:27:03 +0000 (11:27 +0000)
committerAbdelrazak Younes <younes@lyx.org>
Sat, 17 Nov 2007 11:27:03 +0000 (11:27 +0000)
* ParagraphMetrics::computeRowSignature(): Integrate row's dimensions and selection status in the row signature.
* TextMetrics::drawParagraph(): compute the row signature here and rely on that to decide if a redraw is needed or not.
* BufferView::Private: get rid of the ViewMetricsInfo member. Just keep the ScreenUpdateStrategy.
* BufferView::draw(): full screen update even for singlePar case because the row signature will detect if something needs to be redrawn.
* Text3.cpp: get rid of hack following architecture update.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@21650 a592a061-630c-0410-9148-cb99ea01b6c8

src/BufferView.cpp
src/BufferView.h
src/MetricsInfo.h
src/ParagraphMetrics.cpp
src/ParagraphMetrics.h
src/Row.cpp
src/Row.h
src/Text3.cpp
src/TextMetrics.cpp
src/frontends/qt4/GuiWorkArea.cpp
src/rowpainter.h

index 124303a1b6ae5fcea43a6b102e08f01ead62ca1b..83ce588a8b6dc314a59d04d1c0065334fe0220e5 100644 (file)
@@ -210,6 +210,13 @@ void gotoInset(BufferView * bv, InsetCode code, bool same_content)
 /// A map from a Text to the associated text metrics
 typedef std::map<Text const *, TextMetrics> TextMetricsCache;
 
+enum ScreenUpdateStrategy {
+       NoScreenUpdate,
+       SingleParUpdate,
+       FullScreenUpdate,
+       DecorationUpdate
+};
+
 } // anon namespace
 
 
@@ -229,7 +236,7 @@ struct BufferView::Private
        ///
        ScrollbarParameters scrollbarParameters_;
        ///
-       ViewMetricsInfo metrics_info_;
+       ScreenUpdateStrategy update_strategy_;
        ///
        CoordCache coord_cache_;
 
@@ -375,12 +382,12 @@ void BufferView::processUpdateFlags(Update::flags flags)
        // Case when no explicit update is requested.
        if (!flags) {
                // no need to redraw anything.
-               d->metrics_info_.update_strategy = NoScreenUpdate;
+               d->update_strategy_ = NoScreenUpdate;
                return;
        }
 
        if (flags == Update::Decoration) {
-               d->metrics_info_.update_strategy = DecorationUpdate;
+               d->update_strategy_ = DecorationUpdate;
                buffer_.changed();
                return;
        }
@@ -395,12 +402,12 @@ void BufferView::processUpdateFlags(Update::flags flags)
                        return;
                }
                if (flags & Update::Decoration) {
-                       d->metrics_info_.update_strategy = DecorationUpdate;
+                       d->update_strategy_ = DecorationUpdate;
                        buffer_.changed();
                        return;
                }
                // no screen update is needed.
-               d->metrics_info_.update_strategy = NoScreenUpdate;
+               d->update_strategy_ = NoScreenUpdate;
                return;
        }
 
@@ -1176,7 +1183,7 @@ Update::flags BufferView::dispatch(FuncRequest const & cmd)
                        //FIXME: updateMetrics() does not update paragraph position
                        // This is done at draw() time. So we need a redraw!
                        // But no screen update is needed.
-                       d->metrics_info_.update_strategy = NoScreenUpdate;
+                       d->update_strategy_ = NoScreenUpdate;
                        buffer_.changed();
                        p = getPos(cur, cur.boundary());
                }
@@ -1205,7 +1212,7 @@ Update::flags BufferView::dispatch(FuncRequest const & cmd)
                }
                // FIXME: we need to do a redraw again because of the selection
                // But no screen update is needed.
-               d->metrics_info_.update_strategy = NoScreenUpdate;
+               d->update_strategy_ = NoScreenUpdate;
                buffer_.changed();
                updateFlags = Update::Force | Update::FitCursor;
                break;
@@ -1334,23 +1341,10 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0)
                if (!need_redraw)
                        return;
 
-               // if last metrics update was in singlepar mode, WorkArea::redraw() will
-               // not expose the button for redraw. We adjust here the metrics dimension
-               // to enable a full redraw in any case as this is not costly.
-               TextMetrics & tm = d->text_metrics_[&buffer_.text()];
-               std::pair<pit_type, ParagraphMetrics const *> firstpm = tm.first();
-               std::pair<pit_type, ParagraphMetrics const *> lastpm = tm.last();
-               int y1 = firstpm.second->position() - firstpm.second->ascent();
-               int y2 = lastpm.second->position() + lastpm.second->descent();
-               d->metrics_info_ = ViewMetricsInfo(firstpm.first, lastpm.first, y1, y2,
-                       FullScreenUpdate, buffer_.text().paragraphs().size());
-               // Reinitialize anchor to first pit.
-               d->anchor_ref_ = firstpm.first;
-               d->offset_ref_ = -y1;
-               LYXERR(Debug::PAINTING,
-                        "Mouse hover detected at: (" << cmd.x << ", " << cmd.y << ")"
-                       << "\nTriggering redraw: y1: " << y1 << " y2: " << y2
-                       << " pit1: " << firstpm.first << " pit2: " << lastpm.first);
+               LYXERR(Debug::PAINTING, "Mouse hover detected at: ("
+                       << cmd.x << ", " << cmd.y << ")");
+
+               d->update_strategy_ = DecorationUpdate;
 
                // This event (moving without mouse click) is not passed further.
                // This should be changed if it is further utilized.
@@ -1629,12 +1623,6 @@ pit_type BufferView::anchor_ref() const
 }
 
 
-ViewMetricsInfo const & BufferView::viewMetricsInfo()
-{
-       return d->metrics_info_;
-}
-
-
 bool BufferView::singleParUpdate()
 {
        Text & buftext = buffer_.text();
@@ -1653,13 +1641,11 @@ bool BufferView::singleParUpdate()
                // the singlePar optimisation.
                return false;
 
-       int y1 = pm.position() - pm.ascent();
-       int y2 = pm.position() + pm.descent();
-       d->metrics_info_ = ViewMetricsInfo(bottom_pit, bottom_pit, y1, y2,
-               SingleParUpdate, buftext.paragraphs().size());
+       d->update_strategy_ = SingleParUpdate;
+
        LYXERR(Debug::PAINTING, BOOST_CURRENT_FUNCTION
-               << "\ny1: " << y1
-               << " y2: " << y2
+               << "\ny1: " << pm.position() - pm.ascent()
+               << " y2: " << pm.position() + pm.descent()
                << " pit: " << bottom_pit
                << " singlepar: 1");
        return true;
@@ -1741,8 +1727,7 @@ void BufferView::updateMetrics()
                << " npit: " << npit
                << " singlepar: 0");
 
-       d->metrics_info_ = ViewMetricsInfo(pit1, pit2, y1, y2,
-               FullScreenUpdate, npit);
+       d->update_strategy_ = FullScreenUpdate;
 
        if (lyxerr.debugging(Debug::WORKAREA)) {
                LYXERR(Debug::WORKAREA, "BufferView::updateMetrics");
@@ -1928,11 +1913,10 @@ void BufferView::draw(frontend::Painter & pain)
        LYXERR(Debug::PAINTING, "\t\t*** START DRAWING ***");
        Text & text = buffer_.text();
        TextMetrics const & tm = d->text_metrics_[&text];
-       int const y = d->metrics_info_.y1 
-               + tm.parMetrics(d->metrics_info_.p1).ascent();
+       int const y = - d->offset_ref_ + tm.parMetrics(d->anchor_ref_).ascent();
        PainterInfo pi(this, pain);
 
-       switch (d->metrics_info_.update_strategy) {
+       switch (d->update_strategy_) {
 
        case NoScreenUpdate:
                // If no screen painting is actually needed, only some the different
@@ -1943,9 +1927,11 @@ void BufferView::draw(frontend::Painter & pain)
                break;
 
        case SingleParUpdate:
-               // Only the current outermost paragraph will be redrawn.
                pi.full_repaint = false;
-               tm.drawParagraph(pi, d->metrics_info_.p1, 0, y);
+               // In general, only the current row of the outermost paragraph
+               // will be redrawn. Particular cases where selection spans
+               // multiple paragraph are correctly detected in TextMetrics.
+               tm.draw(pi, 0, y);
                break;
 
        case DecorationUpdate:
@@ -1957,21 +1943,16 @@ void BufferView::draw(frontend::Painter & pain)
                // The whole screen, including insets, will be refreshed.
                pi.full_repaint = true;
 
-               // Clear background (if not delegated to rows)
-               pain.fillRectangle(0, d->metrics_info_.y1, width_,
-                       d->metrics_info_.y2 - d->metrics_info_.y1,
+               // Clear background.
+               pain.fillRectangle(0, 0, width_, height_,
                        buffer_.inset().backgroundColor());
                tm.draw(pi, 0, y);
 
-               // and grey out above (should not happen later)
-               if (d->metrics_info_.y1 > 0)
-                       pain.fillRectangle(0, 0, width_,
-                               d->metrics_info_.y1, Color_bottomarea);
-
                // and possibly grey out below
-               if (d->metrics_info_.y2 < height_)
-                       pain.fillRectangle(0, d->metrics_info_.y2, width_,
-                               height_ - d->metrics_info_.y2, Color_bottomarea);
+               std::pair<pit_type, ParagraphMetrics const *> lastpm = tm.last();
+               int const y2 = lastpm.second->position() + lastpm.second->descent();
+               if (y2 < height_)
+                       pain.fillRectangle(0, y2, width_, height_ - y2, Color_bottomarea);
                break;
        }
 
index 9dfe5568cfbb08cf2862f8bb49720b477d746295..426e8cf8a0407d32e055d19e507787dfea238d39 100644 (file)
@@ -41,7 +41,6 @@ class ParagraphMetrics;
 class Point;
 class Text;
 class TextMetrics;
-class ViewMetricsInfo;
 
 enum CursorStatus {
        CUR_INSIDE,
@@ -195,11 +194,6 @@ public:
        void putSelectionAt(DocIterator const & cur,
                int length, bool backwards);
 
-       /// return the internal \c ViewMetricsInfo.
-       /// This is used specifically by the \c Workrea.
-       /// \sa WorkArea
-       /// \sa ViewMetricsInfo
-       ViewMetricsInfo const & viewMetricsInfo();
        /// update the internal \c ViewMetricsInfo.
        void updateMetrics();
 
index f1583d193cebc289b071b6ad21bb1a6089af355c..e091dc78308ff55760e03d2867223997332dbe59 100644 (file)
@@ -112,38 +112,9 @@ public:
 
 class TextMetricsInfo {};
 
-enum ScreenUpdateStrategy {
-       NoScreenUpdate,
-       SingleParUpdate,
-       FullScreenUpdate,
-       DecorationUpdate
-};
-
-class ViewMetricsInfo
-{
-public:
-       ViewMetricsInfo()
-                       : p1(0), p2(0), y1(0), y2(0),
-                       update_strategy(FullScreenUpdate), size(0)
-               {}
-       ViewMetricsInfo(pit_type p1, pit_type p2, int y1, int y2,
-                       ScreenUpdateStrategy updatestrategy, pit_type size)
-                       : p1(p1), p2(p2), y1(y1), y2(y2),
-                       update_strategy(updatestrategy), size(size)
-               {}
-
-       pit_type p1;
-       pit_type p2;
-       int y1;
-       int y2;
-       ScreenUpdateStrategy update_strategy;
-       pit_type size;
-};
-
-
-// Generic base for temporarily changing things.
-// The original state gets restored when the Changer is destructed.
 
+/// Generic base for temporarily changing things.
+/// The original state gets restored when the Changer is destructed.
 template <class Struct, class Temp = Struct>
 class Changer {
 public:
index 483620a8e7ace77332da7af2569db91297c57e4d..f8901ecfc77d7728a021ea0a7aea1edfb8b06c2d 100644 (file)
@@ -97,8 +97,8 @@ void ParagraphMetrics::reset(Paragraph const & par)
 }
 
 
-void ParagraphMetrics::computeRowSignature(Row & row,
-               BufferParams const & bparams)
+size_t ParagraphMetrics::computeRowSignature(Row const & row,
+               BufferParams const & bparams) const
 {
        boost::crc_32_type crc;
        for (pos_type i = row.pos(); i < row.endpos(); ++i) {
@@ -110,7 +110,12 @@ void ParagraphMetrics::computeRowSignature(Row & row,
                        crc.process_bytes(b, 1);
                }                       
        }
-       row.setCrc(crc.checksum());
+
+       Dimension const & d = row.dimension();
+       char_type const b[] = { row.sel_beg, row.sel_end, d.wid, d.asc, d.des};
+       crc.process_bytes(b, 5);
+
+       return crc.checksum();
 }
 
 
index 43dbd747487afb505d5b42c6ded8626e4a9a9c24..53f5f4379a4c37b2121183e6c8fa26ee5c187bfe 100644 (file)
@@ -87,7 +87,7 @@ public:
        bool hfillExpansion(Row const & row, pos_type pos) const;
 
        /// 
-       void computeRowSignature(Row &, BufferParams const & bparams);
+       size_t computeRowSignature(Row const &, BufferParams const & bparams) const;
 
        ///
        int position() const { return position_; }
index c965210e7a1c258494a2f8af0a2c3e20bd65d2d7..5b3a8fc76262f01be4a1dcafb05bb79723c088e8 100644 (file)
@@ -35,16 +35,15 @@ Row::Row(pos_type pos)
 {}
 
 
-void Row::setCrc(size_type crc)
+void Row::setCrc(size_type crc) const
 {
-       changed_ |= crc != crc_;
+       changed_ = crc != crc_;
        crc_ = crc;
 }
 
 
 void Row::setDimension(Dimension const & dim)
 {
-       changed_ |= dim != dim_;
        dim_ = dim;
 }
 
@@ -63,7 +62,6 @@ void Row::endpos(pos_type p)
 
 void Row::setSelection(pos_type beg, pos_type end)
 {
-       pos_type sel_beg_b = sel_beg;
        if (pos_ >= beg && pos_ <= end)
                sel_beg = pos_;
        else if (beg > pos_ && beg <= end_)
@@ -71,21 +69,12 @@ void Row::setSelection(pos_type beg, pos_type end)
        else
                sel_beg = -1;
 
-       pos_type sel_end_b = sel_end;
        if (end_ >= beg && end_ <= end)
                sel_end = end_;
        else if (end < end_ && end >= pos_)
                sel_end = end;
        else
                sel_end = -1;
-/*
-                       && ((rit->pos() >= beg.pos() && rit->pos() <= end.pos())
-                               || (rit->endpos() >= beg.pos() && rit->endpos() <= end.pos())
-                               || (beg.pos() >= rit->pos() && beg.pos() <= rit->endpos())
-                               || (end.pos() >= rit->pos() && end.pos() <= rit->endpos()));
-*/
-       changed_ |= sel_beg_b != sel_beg;
-       changed_ |= sel_end_b != sel_end;
 }
 
 
index 5b67abba5e463d655edfbb3b3dcf621c5db91634..cb25a4dcd99f17608fad48271527f2b71c6f427f 100644 (file)
--- a/src/Row.h
+++ b/src/Row.h
@@ -38,7 +38,7 @@ public:
        ///
        void setChanged(bool c) { changed_ = c; }
        ///
-       void setCrc(size_type crc);
+       void setCrc(size_type crc) const;
        ///
        void setSelection(pos_type sel_beg, pos_type sel_end);
 
@@ -80,9 +80,9 @@ public:
        pos_type sel_end;
 private:
        /// has the Row appearance changed since last drawing?
-       bool changed_;
+       mutable bool changed_;
        /// CRC of row contents.
-       size_type crc_;
+       mutable size_type crc_;
        /// first pos covered by this row
        pos_type pos_;
        /// one behind last pos covered by this row
index 6808b3d78ea02dacd396304379a17702d4914101..4f685679931a9322b03544c35ad68e6c93e32b6d 100644 (file)
@@ -1203,17 +1203,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                // "auto_region_delete", which defaults to
                // true (on).
 
-               if (lyxrc.auto_region_delete && cur.selection()) {
-                       pit_type const begpit = cur.selBegin().pit();
-                       pit_type const endpit = cur.selEnd().pit();
+               if (lyxrc.auto_region_delete && cur.selection())
                        cutSelection(cur, false, false);
-                       // When a selection spans multiple paragraphs, the metrics update
-                       // mechanism sometimes fail to detect that a full update is needed.
-                       // In this case, we force the full update:
-                       // (see http://bugzilla.lyx.org/show_bug.cgi?id=4317)
-                       if (isMainText(cur.bv().buffer()) && begpit != endpit)
-                               cur.updateFlags(Update::Force);
-               }
 
                cur.clearSelection();
                Font const old_font = cur.real_current_font;
index 9b576e2a92c5e8310842b3fbd8b6abe5a04854eb..c54fe0e1219b6813cb23e672af5f01f4dc3dc043 100644 (file)
@@ -359,7 +359,6 @@ bool TextMetrics::redoParagraph(pit_type const pit)
        pm.reset(par);
 
        Buffer & buffer = bv_->buffer();
-       BufferParams const & bparams = buffer.params();
        main_text_ = (text_ == &buffer.text());
        bool changed = false;
 
@@ -477,7 +476,6 @@ bool TextMetrics::redoParagraph(pit_type const pit)
                row.setDimension(dim);
                int const max_row_width = max(dim_.wid, dim.wid);
                computeRowMetrics(pit, row, max_row_width);
-               pm.computeRowSignature(row, bparams);
                first = end;
                ++row_index;
 
@@ -502,7 +500,6 @@ bool TextMetrics::redoParagraph(pit_type const pit)
                row.setDimension(dim);
                int const max_row_width = max(dim_.wid, dim.wid);
                computeRowMetrics(pit, row, max_row_width);
-               pm.computeRowSignature(row, bparams);
                pm.dim().des += dim.height();
        }
 
@@ -1862,7 +1859,6 @@ int TextMetrics::singleWidth(pit_type pit, pos_type pos) const
 }
 
 
-// only used for inset right now. should also be used for main text
 void TextMetrics::draw(PainterInfo & pi, int x, int y) const
 {
        if (par_metrics_.empty())
@@ -1888,6 +1884,7 @@ void TextMetrics::draw(PainterInfo & pi, int x, int y) const
 
 void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) const
 {
+       BufferParams const & bparams = bv_->buffer().params();
        ParagraphMetrics const & pm = par_metrics_[pit];
        if (pm.rows().empty())
                return;
@@ -1910,26 +1907,27 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co
                RowPainter rp(pi, *text_, pit, row, bidi, x, y);
 
                // Row signature; has row changed since last paint?
+               row.setCrc(pm.computeRowSignature(row, bparams));
                bool row_has_changed = row.changed();
                
-               bool row_selection = row.sel_beg != -1 && row.sel_end != -1;
-
-               if (!row_selection && !pi.full_repaint && !row_has_changed) {
-                       // Paint the only the insets if the text itself is
+               // Don't paint the row if a full repaint has not been requested
+               // or if it has not changed.
+               if (!pi.full_repaint && !row_has_changed) {
+                       // Paint only the insets if the text itself is
                        // unchanged.
                        rp.paintOnlyInsets();
                        y += row.descent();
                        continue;
                }
 
-               // Paint the row if a full repaint has been requested or it has
-               // changed.
-               // Clear background of this row
-               // (if paragraph background was not cleared)
-               if (row_selection || (!pi.full_repaint && row_has_changed)) {
+               // Clear background of this row if paragraph background was not
+               // already cleared because of a full repaint.
+               if (!pi.full_repaint && row_has_changed) {
                        pi.pain.fillRectangle(x, y - row.ascent(),
                                width(), row.height(), pi.background_color);
                }
+
+               bool row_selection = row.sel_beg != -1 && row.sel_end != -1;
                if (row_selection) {
                        DocIterator beg = bv_->cursor().selectionBegin();
                        DocIterator end = bv_->cursor().selectionEnd();
@@ -1944,13 +1942,14 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co
 
                // Instrumentation for testing row cache (see also
                // 12 lines lower):
-               if (lyxerr.debugging(Debug::PAINTING)) {
-                       if (text_->isMainText(bv_->buffer()))
-                               LYXERR(Debug::PAINTING, "\n{" << inside <<
-                               pi.full_repaint << row_has_changed << "}");
-                       else
-                               LYXERR(Debug::PAINTING, "[" << inside <<
-                               pi.full_repaint << row_has_changed << "]");
+               if (lyxerr.debugging(Debug::PAINTING) && inside
+                       && (row_selection || pi.full_repaint || row_has_changed)) {
+                               std::string const foreword = text_->isMainText(bv_->buffer()) ?
+                                       "main text redraw " : "inset text redraw: ";
+                       LYXERR(Debug::PAINTING, foreword << "pit=" << pit << " row=" << i
+                               << " row_selection="    << row_selection
+                               << " full_repaint="     << pi.full_repaint
+                               << " row_has_changed="  << row_has_changed);
                }
 
                // Backup full_repaint status and force full repaint
index 66654b45ba07b714aac39edcd86902d52578a35b..d25e9d626b927685c73755090a0317230ccad6a2 100644 (file)
@@ -320,18 +320,9 @@ void GuiWorkArea::redraw()
                showCursor();
        }
        
-       ViewMetricsInfo const & vi = buffer_view_->viewMetricsInfo();
-
        LYXERR(Debug::WORKAREA, "WorkArea::redraw screen");
-
-       int const ymin = std::max(vi.y1, 0);
-       int const ymax = vi.p2 < vi.size - 1 ? vi.y2 : viewport()->height();
-
        updateScreen();
-       update(0, ymin, viewport()->width(), ymax - ymin);
-
-       //LYXERR(Debug::WORKAREA, "  ymin = " << ymin << "  width() = " << width()
-       //              << "  ymax-ymin = " << ymax-ymin);
+       update(0, 0, viewport()->width(), viewport()->height());
 
        if (lyxerr.debugging(Debug::WORKAREA))
                buffer_view_->coordCache().dump();
index 14fe013ebb575817307064809a2185c938a4d73d..c9bcafb7231940c6d683753f47602ac8dae7fc43 100644 (file)
@@ -31,7 +31,6 @@ class ParagraphMetrics;
 class Row;
 class Text;
 class TextMetrics;
-class ViewMetricsInfo;
 
 namespace frontend { class Painter; }