[LyX features/biginset] In the no-draw phase, do not cache the positions of not visible insets
Jean-Marc Lasgouttes
lasgouttes at lyx.org
Mon Jul 24 14:49:29 UTC 2023
The branch, biginset, has been updated.
- Log -----------------------------------------------------------------
commit 37e56c2c19d89e32d43969944960f09df3db01d2
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Mon Jul 24 17:53:16 2023 +0200
In the no-draw phase, do not cache the positions of not visible insets
This can make a big difference for a very large branch that contains
lots of equations.
This is complementary to the previous patch, since instead of reducing
the number of calls to updatePosCache, we make it faster.
In the same test of scrolling with mouse wheel through the
branch-test.lyx document, one finds a 23% improvement for
BufferView::updateMetrics().
Part of bug #12297.
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 2ddbcd9..13a0d6f 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3064,7 +3064,7 @@ bool BufferView::singleParUpdate()
// the height does not change but the ascent does.
pm.setPosition(pm.position() - old_dim.ascent() + pm.ascent());
- tm.updatePosCache(pit);
+ tm.updatePosCache(pit, true);
LYXERR(Debug::PAINTING, "\ny1: " << pm.position() - pm.ascent()
<< " y2: " << pm.position() + pm.descent()
@@ -3563,7 +3563,7 @@ void BufferView::draw(frontend::Painter & pain, bool paint_caret)
Text & text = buffer_.text();
TextMetrics const & tm = d->text_metrics_[&text];
int const y = tm.first().second->position();
- PainterInfo pi(this, pain);
+ PainterInfo pi(this, pain, true);
// Check whether the row where the cursor lives needs to be scrolled.
// Update the drawing strategy if needed.
diff --git a/src/MetricsInfo.cpp b/src/MetricsInfo.cpp
index 8fe03ba..1f9cfd2 100644
--- a/src/MetricsInfo.cpp
+++ b/src/MetricsInfo.cpp
@@ -134,10 +134,11 @@ MetricsInfo::MetricsInfo(BufferView * bv, FontInfo font, int textwidth,
//
/////////////////////////////////////////////////////////////////////////
-PainterInfo::PainterInfo(BufferView * bv, lyx::frontend::Painter & painter)
+PainterInfo::PainterInfo(BufferView * bv, lyx::frontend::Painter & painter, bool ov)
: pain(painter), ltr_pos(false), change(),
selected(false), selected_left(false), selected_right(false),
- do_spellcheck(true), full_repaint(true), background_color(Color_background),
+ do_spellcheck(true), full_repaint(true), only_visible(ov),
+ background_color(Color_background),
leftx(0), rightx(0)
{
base.bv = bv;
diff --git a/src/MetricsInfo.h b/src/MetricsInfo.h
index 09c5b63..6ecc859 100644
--- a/src/MetricsInfo.h
+++ b/src/MetricsInfo.h
@@ -117,7 +117,7 @@ public:
class PainterInfo {
public:
///
- PainterInfo(BufferView * bv, frontend::Painter & pain);
+ PainterInfo(BufferView * bv, frontend::Painter & pain, bool only_visible);
///
void draw(int x, int y, char_type c);
///
@@ -149,6 +149,8 @@ public:
bool do_spellcheck;
/// True when it can be assumed that the screen has been cleared
bool full_repaint;
+ /// When true, painting with nullPainter will be limited to screen
+ bool only_visible;
/// Current background color
ColorCode background_color;
/// The left and right position of current line (inside margins).
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 2e5fd56..bcf1248 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -193,7 +193,7 @@ void TextMetrics::newParMetricsDown()
redoParagraph(pit);
par_metrics_[pit].setPosition(last.second.position()
+ last.second.descent() + par_metrics_[pit].ascent());
- updatePosCache(pit);
+ updatePosCache(pit, false);
}
@@ -208,7 +208,7 @@ void TextMetrics::newParMetricsUp()
redoParagraph(pit);
par_metrics_[pit].setPosition(first.second.position()
- first.second.ascent() - par_metrics_[pit].descent());
- updatePosCache(pit);
+ updatePosCache(pit, false);
}
@@ -261,10 +261,10 @@ bool TextMetrics::metrics(MetricsInfo const & mi, Dimension & dim, int min_width
}
-void TextMetrics::updatePosCache(pit_type pit) const
+void TextMetrics::updatePosCache(pit_type pit, bool only_visible) const
{
frontend::NullPainter np;
- PainterInfo pi(bv_, np);
+ PainterInfo pi(bv_, np, only_visible);
drawParagraph(pi, pit, origin_.x_, par_metrics_[pit].position());
}
@@ -1970,6 +1970,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
if (pm.rows().empty())
return;
size_t const nrows = pm.rows().size();
+ int const wh = bv_->workHeight();
// Remember left and right margin for drawing math numbers
Changer changeleft = changeVar(pi.leftx, x + leftMargin(pit));
Changer changeright = changeVar(pi.rightx, x + width() - rightMargin(pit));
@@ -1977,22 +1978,24 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
// Use fast lane in nodraw stage.
if (pi.pain.isNull()) {
for (size_t i = 0; i != nrows; ++i) {
-
Row const & row = pm.rows()[i];
// Adapt to cursor row scroll offset if applicable.
int row_x = x - bv_->horizScrollOffset(text_, pit, row.pos());
if (i)
y += row.ascent();
- RowPainter rp(pi, *text_, row, row_x, y);
+ // It is not needed to draw on screen if we are not inside and we do not force it
+ bool const inside = (y + row.descent() >= 0 && y - row.ascent() < wh);
+ if (inside || !pi.only_visible) {
+ RowPainter rp(pi, *text_, row, row_x, y);
+ rp.paintOnlyInsets();
+ }
- rp.paintOnlyInsets();
y += row.descent();
}
return;
}
- int const ww = bv_->workHeight();
Cursor const & cur = bv_->cursor();
DocIterator sel_beg = cur.selectionBegin();
DocIterator sel_end = cur.selectionEnd();
@@ -2035,7 +2038,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
// It is not needed to draw on screen if we are not inside.
bool const inside = (y + row.descent() >= 0
- && y - row.ascent() < ww);
+ && y - row.ascent() < wh);
if (!inside) {
// Inset positions have already been set in nodraw stage.
y += row.descent();
diff --git a/src/TextMetrics.h b/src/TextMetrics.h
index 74eef5e..9e79e3f 100644
--- a/src/TextMetrics.h
+++ b/src/TextMetrics.h
@@ -77,7 +77,7 @@ public:
/// The "nodraw" drawing stage for one single paragraph: set the
/// positions of the insets contained in this paragraph in metrics
/// cache. Related to BufferView::updatePosCache.
- void updatePosCache(pit_type pit) const;
+ void updatePosCache(pit_type pit, bool only_visible) const;
/// Gets the fully instantiated font at a given position in a paragraph.
/// Basically the same routine as Paragraph::getFont() in Paragraph.cpp.
diff --git a/src/insets/InsetSpecialChar.cpp b/src/insets/InsetSpecialChar.cpp
index f930ed7..60ee9ad 100644
--- a/src/insets/InsetSpecialChar.cpp
+++ b/src/insets/InsetSpecialChar.cpp
@@ -241,7 +241,7 @@ void InsetSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const
dim.asc = fm.maxAscent();
dim.des = fm.maxDescent();
frontend::NullPainter np;
- PainterInfo pi(mi.base.bv, np);
+ PainterInfo pi(mi.base.bv, np, true);
pi.base.font = mi.base.font;
// We rely on the fact that drawLogo updates x to compute
// the width without code duplication.
-----------------------------------------------------------------------
Summary of changes:
src/BufferView.cpp | 4 ++--
src/MetricsInfo.cpp | 5 +++--
src/MetricsInfo.h | 4 +++-
src/TextMetrics.cpp | 21 ++++++++++++---------
src/TextMetrics.h | 2 +-
src/insets/InsetSpecialChar.cpp | 2 +-
6 files changed, 22 insertions(+), 16 deletions(-)
hooks/post-receive
--
Repository for new features
More information about the lyx-cvs
mailing list