From 5adf6d5d583b1dc49f811bc7762d97f1cb17cef8 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Thu, 6 Apr 2006 12:06:37 +0000 Subject: [PATCH] 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 --- RELEASE-NOTES | 6 -- src/BufferView.C | 12 ++++ src/BufferView.h | 8 ++- src/BufferView_pimpl.C | 19 +++++- src/BufferView_pimpl.h | 12 +++- src/ChangeLog | 74 ++++++++++++++-------- src/LyXAction.C | 20 +++--- src/debug.C | 1 + src/debug.h | 2 + src/insets/ChangeLog | 31 +++++++--- src/insets/insetbase.h | 7 ++- src/insets/insetcollapsable.C | 3 +- src/insets/insetcollapsable.h | 2 - src/insets/insetenv.h | 2 - src/insets/insettabular.h | 2 +- src/insets/insettext.C | 26 +++++--- src/insets/insettext.h | 10 ++- src/mathed/ChangeLog | 4 ++ src/mathed/math_hullinset.h | 2 +- src/paragraph_pimpl.C | 2 +- src/rowpainter.C | 112 +++++++++++++++++++++++++++------- src/text3.C | 16 ++++- status.14x | 2 + 23 files changed, 277 insertions(+), 98 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index a4a93eb820..9a6c9b8fa4 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -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. diff --git a/src/BufferView.C b/src/BufferView.C index 75544d0623..d5160a7420 100644 --- a/src/BufferView.C +++ b/src/BufferView.C @@ -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_; diff --git a/src/BufferView.h b/src/BufferView.h index 426e90a293..2940d77586 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -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: /// diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index af88feffe9..d1529f798e 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -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 diff --git a/src/BufferView_pimpl.h b/src/BufferView_pimpl.h index b55cf924e2..c6ac78f6f7 100644 --- a/src/BufferView_pimpl.h +++ b/src/BufferView_pimpl.h @@ -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 diff --git a/src/ChangeLog b/src/ChangeLog index 376e581381..bbf264aafd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,25 @@ +2006-03-18 Georg Baum + + * rowpainter.C (paintInset): remove unneeded casts + (paintPar): ditto + +2006-03-17 Martin Vermeer + + 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 + + * 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 * LaTeX.C (handleFoundFile): do not add directories to the @@ -24,39 +46,39 @@ 2006-03-23 Lars Gullik Bjønnes - * 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 diff --git a/src/LyXAction.C b/src/LyXAction.C index 9c98b95881..911bef3d4c 100644 --- a/src/LyXAction.C +++ b/src/LyXAction.C @@ -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 }, diff --git a/src/debug.C b/src/debug.C index 24977bc1b8..2b4badfcfa 100644 --- a/src/debug.C +++ b/src/debug.C @@ -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")} }; diff --git a/src/debug.h b/src/debug.h index af7b04067e..c338b7a228 100644 --- a/src/debug.h +++ b/src/debug.h @@ -74,6 +74,8 @@ public: /// EXTERNAL = (1 << 23), /// + PAINTING = (1 << 24), + /// DEBUG = (1 << 31), /// ANY = 0xffffffff diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index f094def217..cdfa7635df 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,17 +1,31 @@ +2006-03-18 Georg Baum + + * insetbase.h (asTextInset): + * insettext.h (asTextInset): constify + +2006-03-17 Martin Vermeer + + 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 - *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 - * 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 @@ -41,7 +55,8 @@ 2006-02-22 Jürgen Spitzmüller - * 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 diff --git a/src/insets/insetbase.h b/src/insets/insetbase.h index 516558828e..885c6356a0 100644 --- a/src/insets/insetbase.h +++ b/src/insets/insetbase.h @@ -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; diff --git a/src/insets/insetcollapsable.C b/src/insets/insetcollapsable.C index 11b02bb1d2..02a6b375db 100644 --- a/src/insets/insetcollapsable.C +++ b/src/insets/insetcollapsable.C @@ -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_) { diff --git a/src/insets/insetcollapsable.h b/src/insets/insetcollapsable.h index 22697c4828..9455eabbb2 100644 --- a/src/insets/insetcollapsable.h +++ b/src/insets/insetcollapsable.h @@ -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() {} diff --git a/src/insets/insetenv.h b/src/insets/insetenv.h index aeeb992c63..e030600930 100644 --- a/src/insets/insetenv.h +++ b/src/insets/insetenv.h @@ -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 diff --git a/src/insets/insettabular.h b/src/insets/insettabular.h index 3664c12ace..889070e9a1 100644 --- a/src/insets/insettabular.h +++ b/src/insets/insettabular.h @@ -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 */ diff --git a/src/insets/insettext.C b/src/insets/insettext.C index 94f03fdb9d..6a45246ade 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -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 diff --git a/src/insets/insettext.h b/src/insets/insettext.h index 19ed3d8abc..a47c1c0988 100644 --- a/src/insets/insettext.h +++ b/src/insets/insettext.h @@ -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_; diff --git a/src/mathed/ChangeLog b/src/mathed/ChangeLog index 6b0bdaf828..ba4da2061a 100644 --- a/src/mathed/ChangeLog +++ b/src/mathed/ChangeLog @@ -1,3 +1,7 @@ +2006-03-17 Martin Vermeer + + * math_hullinset.h (canTrackChanges): renamed from isTextInset. + 2006-03-14 Georg Baum * math_parser.C (parse1): Parse \tag and \tag* correctly diff --git a/src/mathed/math_hullinset.h b/src/mathed/math_hullinset.h index 9767f0f883..d50400b14d 100644 --- a/src/mathed/math_hullinset.h +++ b/src/mathed/math_hullinset.h @@ -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(); /// diff --git a/src/paragraph_pimpl.C b/src/paragraph_pimpl.C index 76065063c5..4ffd914f3e 100644 --- a/src/paragraph_pimpl.C +++ b/src/paragraph_pimpl.C @@ -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; diff --git a/src/rowpainter.C b/src/rowpainter.C index 55ab558241..1c029c7a54 100644 --- a/src/rowpainter.C +++ b/src/rowpainter.C @@ -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(&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(); } } diff --git a/src/text3.C b/src/text3.C index d913e026a7..f34b24ab10 100644 --- a/src/text3.C +++ b/src/text3.C @@ -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 diff --git a/status.14x b/status.14x index 9c8d53cf72..d628903027 100644 --- a/status.14x +++ b/status.14x @@ -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).