mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-09-20 06:49:56 +00:00
This commit fixes the singlePar optimization which was disabled due to the ParagraphMetrics cleanup.
* rowpainter.C::paintPar(): don't calculate row signature here. Use ParagraphMetrics::rowChangeStatus() instead. * RowList_fwd.h: RowSignature is now a vector. * ParagraphMetrics - rowChangeStatus(), updateRowChangeStatus(), calculateRowSignature(): new methods. - row_signature_: new member - rowSignature_: renamed to row_signature_ * TextMetrics::redoParagraph(): call ParagraphMetrics::updateRowChangeStatus() * BufferView::updateMetrics(): simplify the singlePar case. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16543 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
a01209bee8
commit
063fdd118b
@ -1345,23 +1345,22 @@ void BufferView::updateMetrics(bool singlepar)
|
||||
|
||||
// If the paragraph metrics has changed, we can not
|
||||
// use the singlepar optimisation.
|
||||
if (singlepar && tm.redoParagraph(cursor_.bottom().pit()))
|
||||
singlepar = false;
|
||||
if (singlepar
|
||||
// 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;
|
||||
|
||||
pit_type const pit = anchor_ref_;
|
||||
int pit1 = pit;
|
||||
int pit2 = pit;
|
||||
size_t const npit = buftext.paragraphs().size();
|
||||
|
||||
// Rebreak anchor paragraph. 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)
|
||||
if (!singlepar || pit == cursor_.bottom().pit())
|
||||
// If the paragraph metrics has changed, we can not
|
||||
// use the singlepar optimisation.
|
||||
if (tm.redoParagraph(pit))
|
||||
singlepar = false;
|
||||
// Rebreak anchor paragraph.
|
||||
if (!singlepar)
|
||||
tm.redoParagraph(pit);
|
||||
|
||||
// Clear out the position cache in case of full screen redraw.
|
||||
if (!singlepar)
|
||||
@ -1369,13 +1368,12 @@ void BufferView::updateMetrics(bool singlepar)
|
||||
|
||||
int y0 = tm.parMetrics(pit).ascent() - offset_ref_;
|
||||
|
||||
// Redo paragraphs above anchor if necessary; again, in Single Par
|
||||
// mode, only if we encounter the (main text) one having the cursor.
|
||||
// Redo paragraphs above anchor if necessary.
|
||||
int y1 = y0;
|
||||
while (y1 > 0 && pit1 > 0) {
|
||||
y1 -= tm.parMetrics(pit1).ascent();
|
||||
--pit1;
|
||||
if (!singlepar || pit1 == cursor_.bottom().pit())
|
||||
if (!singlepar)
|
||||
tm.redoParagraph(pit1);
|
||||
y1 -= tm.parMetrics(pit1).descent();
|
||||
}
|
||||
@ -1395,13 +1393,12 @@ void BufferView::updateMetrics(bool singlepar)
|
||||
anchor_ref_ = 0;
|
||||
}
|
||||
|
||||
// Redo paragraphs below the anchor if necessary. Single par mode:
|
||||
// only the one containing the cursor if encountered.
|
||||
// Redo paragraphs below the anchor if necessary.
|
||||
int y2 = y0;
|
||||
while (y2 < height_ && pit2 < int(npit) - 1) {
|
||||
y2 += tm.parMetrics(pit2).descent();
|
||||
++pit2;
|
||||
if (!singlepar || pit2 == cursor_.bottom().pit())
|
||||
if (!singlepar)
|
||||
tm.redoParagraph(pit2);
|
||||
y2 += tm.parMetrics(pit2).ascent();
|
||||
}
|
||||
|
@ -78,6 +78,42 @@ ParagraphMetrics::ParagraphMetrics(Paragraph const & par): par_(&par)
|
||||
}
|
||||
|
||||
|
||||
ParagraphMetrics & ParagraphMetrics::operator=(
|
||||
ParagraphMetrics const & pm)
|
||||
{
|
||||
rows_ = pm.rows_;
|
||||
dim_ = pm.dim_;
|
||||
par_ = pm.par_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
size_type ParagraphMetrics::calculateRowSignature(Row const & row)
|
||||
{
|
||||
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);
|
||||
}
|
||||
return crc.checksum();
|
||||
}
|
||||
|
||||
|
||||
void ParagraphMetrics::updateRowChangeStatus()
|
||||
{
|
||||
size_t const size = rows_.size();
|
||||
row_change_status_.resize(size);
|
||||
row_signature_.resize(size);
|
||||
|
||||
for (size_t i = 0; i != size; ++i) {
|
||||
// Row signature; has row changed since last update?
|
||||
size_type const row_sig = calculateRowSignature(rows_[i]);
|
||||
row_change_status_[i] = row_signature_[i] != row_sig;
|
||||
row_signature_[i] = row_sig;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Row & ParagraphMetrics::getRow(pos_type pos, bool boundary)
|
||||
{
|
||||
BOOST_ASSERT(!rows().empty());
|
||||
|
@ -31,6 +31,13 @@ public:
|
||||
ParagraphMetrics(): par_(0) {};
|
||||
/// The only useful constructor.
|
||||
ParagraphMetrics(Paragraph const & par);
|
||||
|
||||
/// Copy operator.
|
||||
/// Important note: We don't copy \c row_change_status_ and
|
||||
/// \c row_signature_ because those are updated externally with
|
||||
/// \c updateRowChangeStatus() in TextMetrics::redoParagraph().
|
||||
ParagraphMetrics & operator=(ParagraphMetrics const &);
|
||||
|
||||
///
|
||||
Row & getRow(pos_type pos, bool boundary);
|
||||
///
|
||||
@ -53,8 +60,11 @@ public:
|
||||
RowList & rows() { return rows_; }
|
||||
/// The painter and others use this
|
||||
RowList const & rows() const { return rows_; }
|
||||
/// The painter and others use this
|
||||
std::vector<bool> const & rowChangeStatus() const
|
||||
{ return row_change_status_; }
|
||||
///
|
||||
RowSignature & rowSignature() const { return rowSignature_; }
|
||||
void updateRowChangeStatus();
|
||||
///
|
||||
int rightMargin(Buffer const & buffer) const;
|
||||
|
||||
@ -62,10 +72,14 @@ public:
|
||||
void dump() const;
|
||||
|
||||
private:
|
||||
///
|
||||
size_type ParagraphMetrics::calculateRowSignature(Row const &);
|
||||
///
|
||||
mutable RowList rows_;
|
||||
///
|
||||
mutable RowSignature rowSignature_;
|
||||
RowSignature row_signature_;
|
||||
///
|
||||
std::vector<bool> row_change_status_;
|
||||
/// cached dimensions of paragraph
|
||||
Dimension dim_;
|
||||
///
|
||||
|
@ -27,7 +27,7 @@ namespace lyx {
|
||||
*/
|
||||
typedef std::vector<Row> RowList;
|
||||
///
|
||||
typedef std::map<size_type, size_type> RowSignature;
|
||||
typedef std::vector<size_type> RowSignature;
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
@ -258,6 +258,10 @@ bool TextMetrics::redoParagraph(pit_type const pit)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -823,20 +823,6 @@ void RowPainter::paintText()
|
||||
}
|
||||
|
||||
|
||||
size_type calculateRowSignature(Row const & row, Paragraph const & par,
|
||||
int x, int y)
|
||||
{
|
||||
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);
|
||||
}
|
||||
char_type const b[] = { x, y, row.width() };
|
||||
crc.process_bytes(b, 3);
|
||||
return crc.checksum();
|
||||
}
|
||||
|
||||
|
||||
bool CursorOnRow(PainterInfo & pi, pit_type const pit,
|
||||
RowList::const_iterator rit, LyXText const & text)
|
||||
{
|
||||
@ -899,8 +885,7 @@ void paintPar
|
||||
bool tmp = refreshInside;
|
||||
|
||||
// Row signature; has row changed since last paint?
|
||||
size_type const row_sig = calculateRowSignature(*rit, par, x, y);
|
||||
bool row_has_changed = pm.rowSignature()[rowno] != row_sig;
|
||||
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,
|
||||
@ -928,9 +913,6 @@ void paintPar
|
||||
// from cache, or cursor is inside an inset _on this row_,
|
||||
// then paint the row
|
||||
if (repaintAll || row_has_changed || cursor_on_row) {
|
||||
// Add to row signature cache
|
||||
pm.rowSignature()[rowno] = row_sig;
|
||||
|
||||
bool const inside = (y + rit->descent() >= 0
|
||||
&& y - rit->ascent() < ww);
|
||||
// it is not needed to draw on screen if we are not inside.
|
||||
|
Loading…
Reference in New Issue
Block a user