Fix bug 2195: Slowness in rendering inside insets, especially

on the Mac

	Changes to the within-inset row rendering caching code.

	* insets/insetenv.h: 
	* insets/insetcollapsable.h: remove method
	* insets/insettabular.h:
	* insets/insetbase.h: rename, add methods
	* insets/insettext.[Ch]: rename method; add Tall()
	* paragraph_pimpl.C
	(Paragraph::Pimpl::simpleTeXSpecialC): rename call
	* mathed/math_hullinset.h: rename method
	* rowpainter.C
	(RowPainter::paintInset):
	(paintPar): remove isTrueTextInset, move to insets 



git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_4_X@13568 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jean-Marc Lasgouttes 2006-04-06 12:06:37 +00:00
parent b5d8f230a1
commit 5adf6d5d58
23 changed files with 277 additions and 98 deletions

View File

@ -5,12 +5,6 @@ This file describes some known problems in LyX 1.4.1 that did not
occur in 1.3.7. Note that fixes are available for many of these, but
they have not yet been applied because of incomplete testing.
** Noticeable delays when editing documents
- creating/deleting paragraphs in large documents or documents with
images and previews.
http://bugzilla.lyx.org/show_bug.cgi?id=2287
** Change tracking
- Pasted text inserted wrong after switch of change tracking state.

View File

@ -369,6 +369,18 @@ void BufferView::putSelectionAt(DocIterator const & cur,
}
bool const BufferView::repaintAll() const
{
return pimpl_->repaintAll();
}
void const BufferView::repaintAll(bool r) const
{
pimpl_->repaintAll(r);
}
LCursor & BufferView::cursor()
{
return pimpl_->cursor_;

View File

@ -40,7 +40,8 @@ namespace Update {
enum flags {
FitCursor = 1,
Force = 2,
SinglePar = 4
SinglePar = 4,
MultiParSel = 8
};
inline flags operator|(flags const f, flags const g)
@ -198,7 +199,10 @@ public:
*/
void putSelectionAt(DocIterator const & cur,
int length, bool backwards);
///
bool const repaintAll() const;
///
void const repaintAll(bool r) const;
private:
///

View File

@ -658,6 +658,17 @@ bool BufferView::Pimpl::fitCursor()
}
bool BufferView::Pimpl::multiParSel()
{
if (!cursor_.selection())
return false;
bool ret = multiparsel_cache_;
multiparsel_cache_ = cursor_.selBegin().pit() != cursor_.selEnd().pit();
// Either this, or previous selection spans paragraphs
return ret || multiparsel_cache_;
}
void BufferView::Pimpl::update(Update::flags flags)
{
lyxerr[Debug::DEBUG]
@ -682,12 +693,16 @@ void BufferView::Pimpl::update(Update::flags flags)
// First drawing step
ViewMetricsInfo vi = metrics(flags & Update::SinglePar);
bool forceupdate(flags & Update::Force);
bool forceupdate(flags & (Update::Force | Update::SinglePar));
if ((flags & Update::FitCursor) && fitCursor()) {
forceupdate = true;
vi = metrics();
}
if ((flags & Update::MultiParSel) && multiParSel()) {
forceupdate = true;
vi = metrics();
}
if (forceupdate) {
// Second drawing step
screen().redraw(*bv_, vi);
@ -984,7 +999,7 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
if (cur.result().update())
update(Update::FitCursor | Update::Force);
else
update();
update(Update::FitCursor | Update::MultiParSel);
}
// See workAreaKeyPress

View File

@ -59,6 +59,8 @@ public:
void resizeCurrentBuffer();
//
bool fitCursor();
//
bool multiParSel();
///
void update(Update::flags flags = Update::Force);
///
@ -103,6 +105,10 @@ public:
FuncStatus getStatus(FuncRequest const & cmd);
/// a function should be executed
bool dispatch(FuncRequest const & ev);
/// Flag: do a full redraw of inside text of inset
bool repaintAll() { return refresh_inside_; }
///
void repaintAll(bool r) {refresh_inside_ = r; }
private:
/// An error list (replaces the error insets)
ErrorList errorlist_;
@ -183,13 +189,15 @@ private:
///
LCursor cursor_;
///
bool multiparsel_cache_;
///
lyx::pit_type anchor_ref_;
///
int offset_ref_;
///
ViewMetricsInfo metrics(bool singlepar = false);
/// Working variable indicating a full screen refresh
mutable bool refresh_inside_;
};
#endif // BUFFERVIEW_PIMPL_H

View File

@ -1,3 +1,25 @@
2006-03-18 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* rowpainter.C (paintInset): remove unneeded casts
(paintPar): ditto
2006-03-17 Martin Vermeer <martin.vermeer@hut.fi>
Changes to the within-inset row rendering caching code.
* paragraph_pimpl.C (simpleTeXSpecialChar): use canTrackChanges
* rowpainter.C (paintInset):
(paintPar): remove isTrueTextInset, move to insets
2006-03-10 Martin Vermeer <martin.vermeer@hut.fi>
* BufferView.[Ch]:
* BufferView_pimpl.[Ch]:
* LyXAction.C:
* debug.[Ch]:
* rowpainter.C:
* text3.C: Inside-inset speedup, esp. for the Mac (bug 2195)
2006-03-29 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
* LaTeX.C (handleFoundFile): do not add directories to the
@ -24,39 +46,39 @@
2006-03-23 Lars Gullik Bjønnes <larsbj@gullik.net>
* output_latex.h:
* buffer.h:
* CutAndPaste.h:
* pariterator.h:
* paragraph_funcs.h:
* output_linuxdoc.h:
* output_docbook.h: get forward declaration of ParagraphList
* output_latex.h:
* buffer.h:
* CutAndPaste.h:
* pariterator.h:
* paragraph_funcs.h:
* output_linuxdoc.h:
* output_docbook.h: get forward declaration of ParagraphList
* output_plaintext.C:
* bufferlist.C:
* undo.C:
* lyxtext.h:
* undo.h:
* buffer_funcs.C: get proper ParagraphList decls
* output_plaintext.C:
* bufferlist.C:
* undo.C:
* lyxtext.h:
* undo.h:
* buffer_funcs.C: get proper ParagraphList decls
* output_linuxdoc.C (linuxdocParagraphs):
* output_latex.C (TeXOnePar): use std::distance
* output_linuxdoc.C (linuxdocParagraphs):
* output_latex.C (TeXOnePar): use std::distance
* CutAndPaste.C (pasteSelectionHelper, copySelectionHelper):
* paragraph_funcs.C (breakParagraph,
breakParagraphConservative, mergeParagraph):
* text.C (acceptChange, rejectChange):
* text2.C (deleteEmptyParagraphMechanism): use boost::next
* CutAndPaste.C (pasteSelectionHelper, copySelectionHelper):
* paragraph_funcs.C (breakParagraph,
breakParagraphConservative, mergeParagraph):
* text.C (acceptChange, rejectChange):
* text2.C (deleteEmptyParagraphMechanism): use boost::next
* output_docbook.C (several places): use boost::next and
std::distance
* output_docbook.C (several places): use boost::next and
std::distance
* ParagraphList_fwd.h: modify to provid a forward declaratoin
of the new ParagraphList.
* ParagraphList_fwd.h: modify to provid a forward declaratoin
of the new ParagraphList.
* ParagraphList.h: new file, setup user of RandomAccessList
* ParagraphList.h: new file, setup user of RandomAccessList
* paragraph.C: remove ParagraphList constructor from this file
* paragraph.C: remove ParagraphList constructor from this file
2006-03-18 Martin Vermeer <martin.vermeer@hut.fi>

View File

@ -97,7 +97,7 @@ void LyXAction::init()
{ LFUN_UNDERBAR, "accent-underbar", Noop },
{ LFUN_UNDERDOT, "accent-underdot", Noop },
{ LFUN_APPENDIX, "appendix", Noop },
{ LFUN_LEFTSEL, "backward-select", ReadOnly },
{ LFUN_LEFTSEL, "backward-select", ReadOnly | SingleParUpdate },
{ LFUN_BOOKMARK_GOTO, "bookmark-goto", ReadOnly },
{ LFUN_BOOKMARK_SAVE, "bookmark-save", ReadOnly },
{ LFUN_BREAKLINE, "break-line", Noop },
@ -143,8 +143,8 @@ void LyXAction::init()
{ LFUN_DEPTH_MIN, "depth-decrement", Noop },
{ LFUN_DEPTH_PLUS, "depth-increment", Noop },
{ LFUN_LDOTS, "dots-insert", Noop },
{ LFUN_DOWN, "down", ReadOnly | NoUpdate},
{ LFUN_DOWNSEL, "down-select", ReadOnly },
{ LFUN_DOWN, "down", ReadOnly | NoUpdate },
{ LFUN_DOWNSEL, "down-select", ReadOnly | SingleParUpdate },
{ LFUN_DROP_LAYOUTS_CHOICE, "drop-layouts-choice", ReadOnly },
{ LFUN_END_OF_SENTENCE, "end-of-sentence-period-insert", Noop },
{ LFUN_ENVIRONMENT_INSERT, "environment-insert", Noop },
@ -173,7 +173,7 @@ void LyXAction::init()
{ LFUN_FONT_STATE, "font-state", ReadOnly },
{ LFUN_UNDERLINE, "font-underline", Noop },
{ LFUN_INSET_FOOTNOTE, "footnote-insert", Noop },
{ LFUN_RIGHTSEL, "forward-select", ReadOnly },
{ LFUN_RIGHTSEL, "forward-select", ReadOnly | SingleParUpdate },
{ LFUN_HFILL, "hfill-insert", Noop },
{ LFUN_HELP_OPEN, "help-open", NoBuffer | Argument},
{ LFUN_HTMLURL, "html-insert", Noop },
@ -198,10 +198,10 @@ void LyXAction::init()
{ LFUN_LAYOUT_PARAGRAPH, "layout-paragraph", ReadOnly },
{ LFUN_LAYOUT_TABULAR, "layout-tabular", Noop },
{ LFUN_HOME, "line-begin", ReadOnly | NoUpdate},
{ LFUN_HOMESEL, "line-begin-select", ReadOnly },
{ LFUN_HOMESEL, "line-begin-select", ReadOnly | SingleParUpdate },
{ LFUN_DELETE_LINE_FORWARD, "line-delete-forward", Noop },
{ LFUN_END, "line-end", ReadOnly | NoUpdate},
{ LFUN_ENDSEL, "line-end-select", ReadOnly },
{ LFUN_ENDSEL, "line-end-select", ReadOnly | SingleParUpdate },
#if 0
{ LFUN_INSET_LIST, "list-insert", Noop },
#endif
@ -283,7 +283,7 @@ void LyXAction::init()
{ LFUN_TOGGLECURSORFOLLOW, "toggle-cursor-follows-scrollbar", ReadOnly },
{ LFUN_UNDO, "undo", Noop },
{ LFUN_UP, "up", ReadOnly | NoUpdate},
{ LFUN_UPSEL, "up-select", ReadOnly },
{ LFUN_UPSEL, "up-select", ReadOnly | SingleParUpdate },
{ LFUN_URL, "url-insert", Noop },
{ LFUN_VC_CHECKIN, "vc-check-in", ReadOnly },
{ LFUN_VC_CHECKOUT, "vc-check-out", ReadOnly },
@ -291,14 +291,14 @@ void LyXAction::init()
{ LFUN_VC_REVERT, "vc-revert", ReadOnly },
{ LFUN_VC_UNDO, "vc-undo-last", ReadOnly },
{ LFUN_WORDLEFT, "word-backward", ReadOnly | NoUpdate},
{ LFUN_WORDLEFTSEL, "word-backward-select", ReadOnly },
{ LFUN_WORDLEFTSEL, "word-backward-select", ReadOnly | SingleParUpdate },
{ LFUN_CAPITALIZE_WORD, "word-capitalize", Noop },
{ LFUN_DELETE_WORD_BACKWARD, "word-delete-backward", Noop },
{ LFUN_DELETE_WORD_FORWARD, "word-delete-forward", Noop },
{ LFUN_WORDFINDBACKWARD, "word-find-backward", ReadOnly },
{ LFUN_WORDFINDFORWARD, "word-find-forward", ReadOnly },
{ LFUN_WORDRIGHT, "word-forward", ReadOnly | NoUpdate},
{ LFUN_WORDRIGHTSEL, "word-forward-select", ReadOnly },
{ LFUN_WORDRIGHTSEL, "word-forward-select", ReadOnly | SingleParUpdate },
{ LFUN_LOWCASE_WORD, "word-lowcase", Noop },
{ LFUN_WORDSEL, "word-select", ReadOnly },
{ LFUN_UPCASE_WORD, "word-upcase", Noop },
@ -348,7 +348,7 @@ void LyXAction::init()
{ LFUN_FINISHED_UP, "", ReadOnly },
{ LFUN_FINISHED_DOWN, "", ReadOnly },
{ LFUN_MOUSE_PRESS, "", ReadOnly },
{ LFUN_MOUSE_MOTION, "", ReadOnly },
{ LFUN_MOUSE_MOTION, "", ReadOnly | SingleParUpdate },
{ LFUN_MOUSE_RELEASE, "", ReadOnly },
{ LFUN_MOUSE_DOUBLE, "", ReadOnly },
{ LFUN_MOUSE_TRIPLE, "", ReadOnly },

View File

@ -63,6 +63,7 @@ error_item errorTags[] = {
{ Debug::GRAPHICS, "graphics", N_("Graphics conversion and loading")},
{ Debug::CHANGES, "changes", N_("Change tracking")},
{ Debug::EXTERNAL, "external", N_("External template/inset messages")},
{ Debug::PAINTING, "painting", N_("RowPainter profiling")},
{ Debug::DEBUG, "debug", N_("Developers' general debug messages")},
{ Debug::ANY, "any", N_("All debugging messages")}
};

View File

@ -74,6 +74,8 @@ public:
///
EXTERNAL = (1 << 23),
///
PAINTING = (1 << 24),
///
DEBUG = (1 << 31),
///
ANY = 0xffffffff

View File

@ -1,17 +1,31 @@
2006-03-18 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* insetbase.h (asTextInset):
* insettext.h (asTextInset): constify
2006-03-17 Martin Vermeer <martin.vermeer@hut.fi>
Changes to the within-inset row rendering caching code.
* insetenv.h (isTextInset):
* insetcollapsable.h (isTextInset): remove method
* insettabular.h (canTrackChanges):
* insetbase.h (canTrackChange): rename from isTextInset, add methods
* insettext.[Ch]: rename method; add Tall()
2006-03-11 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
*insettabular (doDispatch, insertAsciiString):
fix insertion of \t- and \n-separated content from external
clipboard (bug 2394).
* insettabular (doDispatch, insertAsciiString): fix insertion of
\t- and \n-separated content from external clipboard (bug 2394).
2006-03-23 Lars Gullik Bjønnes <larsbj@gullik.net>
* insettext.h: get forward declaration of ParagraphList
* insettext.h: get forward declaration of ParagraphList
* insetbibitem.C: get proper ParagraphList decls
* insetbibitem.C: get proper ParagraphList decls
* insettext.C (appendParagraphs):
* insetcharstyle.C (docbook): use std::distance
* insettext.C (appendParagraphs):
* insetcharstyle.C (docbook): use std::distance
2006-03-24 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
@ -41,7 +55,8 @@
2006-02-22 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
* insetfootlike.C (metrics, draw): use buffer's default font (bug 2308).
* insetfootlike.C (metrics, draw): use buffer's default font (bug
2308).
2006-02-05 Martin Vermeer <martin.vermeer@hut.fi>

View File

@ -21,6 +21,7 @@ class BufferView;
class CursorSlice;
class FuncRequest;
class FuncStatus;
class InsetText;
class LaTeXFeatures;
class LCursor;
class LyXLex;
@ -216,8 +217,10 @@ public:
virtual EDITABLE editable() const;
/// can we go further down on mouse click?
virtual bool descendable() const { return false; }
///
virtual bool isTextInset() const { return false; }
/// does this contain text that can be change track marked in DVI?
virtual bool canTrackChanges() const { return false; }
/// is this inset based on the TextInset class?
virtual InsetText const * asTextInset() const { return 0; }
/// return true if the inset should be removed automatically
virtual bool autoDelete() const;

View File

@ -138,7 +138,7 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const
dim = dimensionCollapsed();
if (status() == Open) {
InsetText::metrics(mi, textdim_);
openinlined_ = (textdim_.wid + dim.wid <= mi.base.textwidth);
openinlined_ = textdim_.wid + 2 * dim.wid <= mi.base.textwidth;
if (openinlined_) {
dim.wid += textdim_.wid;
dim.des = max(dim.des - textdim_.asc + dim.asc, textdim_.des);
@ -171,6 +171,7 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
button_dim.y2 = top + dimc.height();
pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_);
if (status() == Open) {
int textx, texty;
if (openinlined_) {

View File

@ -57,8 +57,6 @@ public:
/// can we go further down on mouse click?
bool descendable() const;
///
bool isTextInset() const { return true; }
///
void setLabel(std::string const & l);
///
virtual void setButtonLabel() {}

View File

@ -34,8 +34,6 @@ public:
///
InsetBase::EDITABLE editable() const { return HIGHLY_EDITABLE; }
///
bool isTextInset() const { return true; }
///
LyXLayout_ptr const & layout() const;
/** returns true if, when outputing LaTeX, font changes should
be closed before generating this inset. This is needed for

View File

@ -69,7 +69,7 @@ public:
///
bool insetAllowed(InsetBase::Code) const { return true; }
///
bool isTextInset() const { return true; }
bool canTrackChanges() const { return true; }
/** returns true if, when outputing LaTeX, font changes should
be closed before generating this inset. This is needed for
insets that may contain several paragraphs */

View File

@ -200,6 +200,7 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
// update our idea of where we are
setPosCache(pi, x, y);
text_.background_color_ = backgroundColor();
text_.draw(pi, x + border_, y);
if (drawFrame_) {
@ -207,7 +208,7 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
int const a = text_.ascent() + border_;
int const h = a + text_.descent() + border_;
int const ww = pi.base.bv->workWidth();
if (w > ww - 40) {
if (w > ww - 40 || Wide()) {
pi.pain.line(0, y - a, ww, y - a, frameColor());
pi.pain.line(0, y - a + h, ww, y - a + h, frameColor());
} else {
@ -219,13 +220,16 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
void InsetText::drawSelection(PainterInfo & pi, int x, int y) const
{
if (backgroundColor() != LColor::background) {
// repaint the background if needed
int const w = text_.width() + 2 * border_;
int const a = text_.ascent() + border_;
int const h = a + text_.descent() + border_;
pi.pain.fillRectangle(x, y - a, w, h, backgroundColor());
}
int const w = text_.width() + 2 * border_;
int const a = text_.ascent() + border_;
int const h = a + text_.descent() + border_;
int const ww = pi.base.bv->workWidth();
if (Wide())
pi.pain.fillRectangle(0, y - a, ww, h,
backgroundColor());
else
pi.pain.fillRectangle(x, y - a, w, h,
backgroundColor());
text_.drawSelection(pi, x, y);
}
@ -254,6 +258,12 @@ InsetBase * InsetText::editXY(LCursor & cur, int x, int y)
}
bool const InsetText::Tall() const
{
return text_.ascent() + text_.descent() > 2 * defaultRowHeight();
}
void InsetText::doDispatch(LCursor & cur, FuncRequest & cmd)
{
lyxerr[Debug::DEBUG] << BOOST_CURRENT_FUNCTION

View File

@ -57,7 +57,9 @@ public:
///
EDITABLE editable() const { return HIGHLY_EDITABLE; }
///
bool isTextInset() const { return true; }
bool canTrackChanges() const { return true; }
///
InsetText const * asTextInset() const { return this; }
///
int latex(Buffer const &, std::ostream &,
OutputParams const &) const;
@ -137,6 +139,10 @@ public:
bool neverIndent() const;
///
InsetText(InsetText const &);
///
bool & Wide() const { return wide_inset_; }
///
bool const Tall() const;
protected:
///
@ -158,6 +164,8 @@ private:
mutable lyx::pit_type old_pit;
///
static int border_;
///
mutable bool wide_inset_;
public:
///
mutable LyXText text_;

View File

@ -1,3 +1,7 @@
2006-03-17 Martin Vermeer <martin.vermeer@hut.fi>
* math_hullinset.h (canTrackChanges): renamed from isTextInset.
2006-03-14 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* math_parser.C (parse1): Parse \tag and \tag* correctly

View File

@ -189,7 +189,7 @@ public:
/// what appears in the minibuffer when opening
virtual std::string const editMessage() const;
///
virtual bool isTextInset() const { return true; }
virtual bool canTrackChanges() const { return true; }
///
virtual void mutateToText();
///

View File

@ -536,7 +536,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
&& runparams.flavor == OutputParams::LATEX
&& features.isAvailable("dvipost");
if (inset->isTextInset()) {
if (inset->canTrackChanges()) {
column += Changes::latexMarkChange(os, running_change,
Change::UNCHANGED, output);
running_change = Change::UNCHANGED;

View File

@ -164,8 +164,17 @@ void RowPainter::paintInset(pos_type const pos, LyXFont const & font)
pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0);
pi.erased_ = erased_ || isDeletedText(par_, pos);
theCoords.insets().add(inset, int(x_), yo_);
inset->drawSelection(pi, int(x_), yo_);
InsetText const * const in = inset->asTextInset();
// non-wide insets are painted completely. Recursive
bool tmp = bv_.repaintAll();
if (!in || !in->Wide()) {
bv_.repaintAll(true);
lyxerr[Debug::PAINTING] << endl << "Paint inset fully" << endl;
}
if (bv_.repaintAll())
inset->drawSelection(pi, int(x_), yo_);
inset->draw(pi, int(x_), yo_);
bv_.repaintAll(tmp);
x_ += inset->width();
}
@ -720,25 +729,52 @@ void RowPainter::paintText()
}
lyx::size_type calculateRowSignature(Row const & row, Paragraph const & par)
lyx::size_type calculateRowSignature(Row const & row, Paragraph const & par,
int x, int y)
{
boost::crc_32_type crc;
for (lyx::pos_type i = row.pos(); i < row.endpos(); ++i) {
const unsigned char b[] = { par.getChar(i) };
crc.process_bytes(b, 1);
}
const unsigned char b[] = { x, y, row.width() };
crc.process_bytes(b, 3);
return crc.checksum();
}
bool isCursorOnRow(PainterInfo & pi, pit_type pit, RowList::const_iterator rit)
bool CursorOnRow(PainterInfo & pi, pit_type const pit,
RowList::const_iterator rit, LyXText const & text)
{
// Is there a cursor on this row (or inside inset on row)
LCursor & cur = pi.base.bv->cursor();
for (lyx::size_type d = 0; d < cur.depth(); d++)
if (cur[d].pit() == pit
&& cur[d].pos() >= rit->pos()
&& cur[d].pos() <= rit->endpos())
for (lyx::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, LyXText const & text)
{
// Is there a cursor inside an inset on this row, and is this inset
// the only "character" on this row
LCursor & cur = pi.base.bv->cursor();
if (rit->pos() + 1 != rit->endpos())
return false;
for (lyx::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;
}
@ -762,17 +798,33 @@ void paintPar
lyx::size_type rowno(0);
for (RowList::const_iterator rit = rb; rit != re; ++rit, ++rowno) {
y += rit->ascent();
// Allow setting of bv->repaintAll() for nested insets in
// this row only
bool tmp = pi.base.bv->repaintAll();
// Row signature; has row changed since last paint?
lyx::size_type const row_sig = calculateRowSignature(*rit, par);
bool cursor_on_row = isCursorOnRow(pi, pit, rit);
lyx::size_type const row_sig = calculateRowSignature(*rit, par, x, y);
bool row_has_changed = par.rowSignature()[rowno] != row_sig;
// If selection is on, the current row signature differs from
bool cursor_on_row = CursorOnRow(pi, pit, rit, text);
bool in_inset_alone_on_row = innerCursorOnRow(pi, pit, rit,
text);
// If this is the only object on the row, we can make it wide
for (pos_type i = rit->pos() ; i != rit->endpos(); ++i) {
InsetBase const * const in = par.getInset(i);
if (in) {
InsetText const * const t = in->asTextInset();
if (t)
t->Wide() = in_inset_alone_on_row &&
t->Tall();
}
}
// 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 || par.rowSignature()[rowno] != row_sig
|| cursor_on_row) {
if (repaintAll || row_has_changed || cursor_on_row) {
// Add to row signature cache
par.rowSignature()[rowno] = row_sig;
@ -781,15 +833,25 @@ void paintPar
RowPainter rp(inside ? pi : nullpi, text, pit, *rit, x, y);
// Clear background of this row
// (if paragraph background was not cleared)
if (!repaintAll) {
pi.pain.fillRectangle(x, y - rit->ascent(),
if (!repaintAll &&
(!in_inset_alone_on_row || row_has_changed)) {
pi.pain.fillRectangle(( rowno ? 0 : x - 10 ), y - rit->ascent(),
pi.base.bv->workWidth(), rit->height(),
text.backgroundColor());
// If outer row has changed, force nested
// insets to repaint completely
if (row_has_changed)
pi.base.bv->repaintAll(true);
}
// Instrumentation for testing row cache (see also
// 12 lines lower):
//lyxerr << "#";
if (text.isMainText())
lyxerr[Debug::PAINTING] << "#";
else
lyxerr[Debug::PAINTING] << "[" <<
repaintAll << row_has_changed <<
cursor_on_row << "]";
rp.paintAppendix();
rp.paintDepthBar();
rp.paintChangeBar();
@ -800,8 +862,10 @@ void paintPar
rp.paintText();
}
y += rit->descent();
// Restore, see above
pi.base.bv->repaintAll(tmp);
}
//lyxerr << "." << endl;
lyxerr[Debug::PAINTING] << "." << endl;
}
} // namespace anon
@ -814,8 +878,11 @@ void paintText(BufferView const & bv, ViewMetricsInfo const & vi)
bool const select = bv.cursor().selection();
PainterInfo pi(const_cast<BufferView *>(&bv), pain);
if (select || !vi.singlepar) {
// Clear background (Delegated to rows if no selection)
// Should the whole screen, including insets, be refreshed?
bool repaintAll(select || !vi.singlepar);
if (repaintAll) {
// Clear background (if not delegated to rows)
pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1,
text->backgroundColor());
}
@ -826,9 +893,10 @@ void paintText(BufferView const & bv, ViewMetricsInfo const & vi)
int yy = vi.y1;
// draw contents
for (pit_type pit = vi.p1; pit <= vi.p2; ++pit) {
bv.repaintAll(repaintAll);
Paragraph const & par = text->getPar(pit);
yy += par.ascent();
paintPar(pi, *bv.text(), pit, 0, yy, select || !vi.singlepar);
paintPar(pi, *bv.text(), pit, 0, yy, repaintAll);
yy += par.descent();
}
@ -865,9 +933,11 @@ void paintTextInset(LyXText const & text, PainterInfo & pi, int x, int y)
// lyxerr << " paintTextInset: y: " << y << endl;
y -= text.getPar(0).ascent();
// This flag can not be set from within same inset:
bool repaintAll = pi.base.bv->repaintAll();
for (int pit = 0; pit < int(text.paragraphs().size()); ++pit) {
y += text.getPar(pit).ascent();
paintPar(pi, text, pit, x, y, true);
paintPar(pi, text, pit, x, y, repaintAll);
y += text.getPar(pit).descent();
}
}

View File

@ -628,12 +628,16 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_DELETE:
if (!cur.selection()) {
if (cur.pos() == cur.paragraph().size())
// Par boundary, force full-screen update
singleParUpdate = false;
needsUpdate = Delete(cur);
cur.resetAnchor();
// It is possible to make it a lot faster still
// just comment out the line below...
} else {
cutSelection(cur, true, false);
singleParUpdate = false;
}
moveCursor(cur, false);
break;
@ -656,6 +660,9 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_BACKSPACE:
if (!cur.selection()) {
if (bv->owner()->getIntl().getTransManager().backspace()) {
// Par boundary, full-screen update
if (cur.pos() == 0)
singleParUpdate = false;
needsUpdate = backspace(cur);
cur.resetAnchor();
// It is possible to make it a lot faster still
@ -663,6 +670,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
}
} else {
cutSelection(cur, true, false);
singleParUpdate = false;
}
bv->switchKeyMap();
break;
@ -1532,10 +1540,14 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
if (singleParUpdate)
// Inserting characters does not change par height
if (cur.bottom().paragraph().dim().height()
if (cur.bottom().paragraph().dim().height()
== olddim.height()) {
// if so, update _only_ this paragraph
cur.bv().update(Update::SinglePar | Update::Force);
cur.bv().update(Update::SinglePar |
Update::FitCursor |
Update::MultiParSel);
cur.noUpdate();
return;
} else
needsUpdate = true;
if (!needsUpdate

View File

@ -58,6 +58,8 @@ What's new
* User Interface:
- Fix slowness in rendering inside insets, especially on the Mac (bug 2195)
- Convert line endings for external copy/paste on OS X (bug 1955).
- Disable saving when document is unchanged (bug 2313).