From 0d876bc179f099b5b9ebe427180bce9a996e730f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Gullik=20Bj=C3=B8nnes?= Date: Tue, 1 Apr 2003 16:55:48 +0000 Subject: [PATCH] rowlist10 git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6674 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/ChangeLog | 33 +++++ src/Makefile.am | 3 +- src/RowList.C | 302 ---------------------------------------- src/RowList.h | 122 +--------------- src/bufferview_funcs.C | 2 +- src/frontends/ChangeLog | 4 + src/frontends/screen.C | 5 +- src/frontends/screen.h | 7 +- src/insets/ChangeLog | 4 + src/insets/insettext.C | 8 +- src/lyxfunc.C | 6 +- src/lyxrow.C | 182 +----------------------- src/lyxrow.h | 47 +------ src/lyxrow_funcs.C | 184 ++++++++++++++++++++++++ src/lyxrow_funcs.h | 25 ++++ src/lyxtext.h | 8 +- src/rowpainter.C | 40 +++--- src/rowpainter.h | 1 + src/text.C | 250 +++++++++++++++++---------------- src/text2.C | 86 +++++++----- src/text3.C | 18 +-- 21 files changed, 488 insertions(+), 849 deletions(-) delete mode 100644 src/RowList.C create mode 100644 src/lyxrow_funcs.C create mode 100644 src/lyxrow_funcs.h diff --git a/src/ChangeLog b/src/ChangeLog index 19ff5abe71..f7fd4809e6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,36 @@ +2003-04-01 Lars Gullik Bjønnes + + * lyxtext.h: adjust + * rowpainter.C: adjust + * text.C: adjust + * text2.C: adjust + * text3.C: adjust + + * lyxrow_funcs. [Ch]: new files + + * lyxrow.[Ch]: remove next and previous pointers + (next,previous): remove accessor functions + (isParEnd): move to lyxrow_funcs + (lastPos): move to lyxrow_funcs + (nextRowIsAllInset): move to lyxrow_funcs + (lastPrintablePos): move to lyxrow_funcs + (numberOfSeparators): move to lyxrow_funcs + (numberOfHfills): move to lyxrow_funcs + (numberOfLabelHfills): move to lyxrow_funcs + (hfillExpansion): move to lyxrow_funcs + + * lyxfunc.C: adjust + + * bufferview_funcs.C (toggleAndShow): adjust + + * RowList.h: Remove class RowList from file leave just a + std::list. + + * RowList.C: delete file + + * Makefile.am (lyx_SOURCES): remove RowList.C, add lyxrow_funcs.C + and lyxrow_funcs.h + 2003-04-01 Lars Gullik Bjønnes * text3.C (cursorPrevious): adjust diff --git a/src/Makefile.am b/src/Makefile.am index d211314c28..ae921568aa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,7 +76,6 @@ lyx_SOURCES = \ ParagraphParameters.h \ ParameterStruct.h \ PrinterParams.h \ - RowList.C \ RowList.h \ ShareContainer.h \ Spacing.C \ @@ -172,6 +171,8 @@ lyx_SOURCES = \ lyxrc.h \ lyxrow.C \ lyxrow.h \ + lyxrow_funcs.C \ + lyxrow_funcs.h \ lyxserver.C \ lyxserver.h \ lyxtext.h \ diff --git a/src/RowList.C b/src/RowList.C deleted file mode 100644 index 3693c9c048..0000000000 --- a/src/RowList.C +++ /dev/null @@ -1,302 +0,0 @@ -#include - -#include "RowList.h" - -#include "lyxrow.h" - -////////// The RowList::iterator - -RowList::iterator::iterator() - : ptr(0) -{} - - -RowList::iterator::iterator(Row * p) - : ptr(p) -{} - - -RowList::iterator::reference -RowList::iterator::operator*() -{ - return *ptr; -} - - -RowList::iterator::pointer -RowList::iterator::operator->() -{ - return ptr; -} - - -RowList::iterator & -RowList::iterator::operator++() -{ - ptr = ptr->next(); - return *this; -} - - -RowList::iterator -RowList::iterator::operator++(int) -{ - iterator tmp = *this; - ++*this; - return tmp; -} - - -RowList::iterator & -RowList::iterator::operator--() -{ - ptr = ptr->previous(); - return *this; -} - - -RowList::iterator -RowList::iterator::operator--(int) -{ - iterator tmp = *this; - --*this; - return tmp; -} - - -bool operator==(RowList::iterator const & i1, - RowList::iterator const & i2) -{ - return &(*const_cast(i1)) - == &(*const_cast(i2)); -} - - -bool operator!=(RowList::iterator const & i1, - RowList::iterator const & i2) -{ - return !(i1 == i2); -} - - -////////// The RowList::const_iterator - -RowList::const_iterator::const_iterator() - : ptr(0) -{} - - -RowList::const_iterator::const_iterator(Row * p) - : ptr(p) -{} - - -RowList::const_iterator::const_reference -RowList::const_iterator::operator*() -{ - return *ptr; -} - - -RowList::const_iterator::const_pointer -RowList::const_iterator::operator->() -{ - return ptr; -} - - -RowList::const_iterator & -RowList::const_iterator::operator++() -{ - ptr = ptr->next(); - return *this; -} - - -RowList::const_iterator -RowList::const_iterator::operator++(int) -{ - const_iterator tmp = *this; - ++*this; - return tmp; -} - - -RowList::const_iterator & -RowList::const_iterator::operator--() -{ - ptr = ptr->previous(); - return *this; -} - - -RowList::const_iterator -RowList::const_iterator::operator--(int) -{ - const_iterator tmp = *this; - --*this; - return tmp; -} - - -bool operator==(RowList::const_iterator const & i1, - RowList::const_iterator const & i2) -{ - return &(*const_cast(i1)) - == &(*const_cast(i2)); -} - - -bool operator!=(RowList::const_iterator const & i1, - RowList::const_iterator const & i2) -{ - return !(i1 == i2); -} - - -////////// The RowList proper -RowList::RowList() - : rowlist(0) -{} - - -RowList::iterator -RowList::insert(RowList::iterator it, Row * row) -{ - if (rowlist == 0) { - rowlist = row; - } else if (it != end()) { - Row * prev = it->previous(); - row->next(&*it); - row->previous(prev); - if (prev) - prev->next(row); - else - rowlist = row; - it->previous(row); - } else { - // Find last par. - Row * last = rowlist; - while (last->next()) - last = last->next(); - last->next(row); - row->previous(last); - } - return iterator(row); -} - - -void RowList::clear() -{ - while (rowlist) { - Row * tmp = rowlist->next(); - delete rowlist; - rowlist = tmp; - } -} - - -void RowList::erase(RowList::iterator it) -{ - Row * prev = it->previous(); - Row * next = it->next(); - - if (prev) - prev->next(next); - else - rowlist = next; - - if (next) - next->previous(prev); - - delete &*it; -} - - -RowList::iterator RowList::begin() -{ - return iterator(rowlist); -} - - -RowList::const_iterator RowList::begin() const -{ - return const_iterator(rowlist); -} - - -RowList::iterator RowList::end() -{ - return iterator(); -} - - -RowList::const_iterator RowList::end() const -{ - return const_iterator(); -} - - -Row const & RowList::front() const -{ - return *rowlist; -} - - -Row & RowList::front() -{ - return *rowlist; -} - - -Row const & RowList::back() const -{ - Row * tmp = rowlist; - while (tmp->next()) - tmp = tmp->next(); - return *tmp; -} - - -Row & RowList::back() -{ - Row * tmp = rowlist; - while (tmp->next()) - tmp = tmp->next(); - return *tmp; -} - - -void RowList::push_back(Row * p) -{ - if (!rowlist) { - rowlist = p; - return; - } - - Row * pos = rowlist; - while (pos->next()) - pos = pos->next(); - pos->next(p); - p->previous(pos); -} - - -int RowList::size() const -{ - // When we switch to a std::container this will be O(1) - // instead of O(n). (Lgb) - Row * tmp = rowlist; - int c = 0; - while (tmp) { - ++c; - tmp = tmp->next(); - } - return c; -} - - -bool RowList::empty() const -{ - return rowlist == 0; -} diff --git a/src/RowList.h b/src/RowList.h index 7fe84e322f..c42f18d718 100644 --- a/src/RowList.h +++ b/src/RowList.h @@ -3,126 +3,10 @@ #ifndef ROW_LIST_H #define ROW_LIST_H -#include +#include "lyxrow.h" -class Row; +#include -/// -class RowList { -public: - /// - class iterator { - public: - /// - typedef std::bidirectional_iterator_tag iterator_category; - /// - typedef Row * value_type; - /// - typedef ptrdiff_t difference_type; - /// - typedef Row * pointer; - /// - typedef Row & reference; - /// - iterator(); - /// - iterator(value_type); - /// - reference operator*(); - /// - pointer operator->(); - /// - iterator & operator++(); - /// - iterator operator++(int); - /// - iterator & operator--(); - /// - iterator operator--(int); - private: - /// - Row * ptr; - }; - /// - class const_iterator { - public: - /// - typedef std::bidirectional_iterator_tag iterator_category; - /// - typedef Row * value_type; - /// - typedef ptrdiff_t difference_type; - /// - typedef Row const * const_pointer; - /// - typedef Row const & const_reference; - /// - const_iterator(); - /// - const_iterator(value_type); - /// - const_reference operator*(); - /// - const_pointer operator->(); - /// - const_iterator & operator++(); - /// - const_iterator operator++(int); - /// - const_iterator & operator--(); - /// - const_iterator operator--(int); - private: - /// - Row * ptr; - }; - /// - RowList(); - /// - iterator insert(iterator it, Row * row); - /// - void clear(); - /// - void erase(iterator it); - /// - iterator begin(); - /// - const_iterator begin() const; - /// - iterator end(); - /// - const_iterator end() const; - /// - void push_back(Row *); - /// - Row const & front() const; - /// - Row & front(); - /// - Row const & back() const; - /// - Row & back(); - /// - int size() const; - /// - bool empty() const; -private: - /// - Row * rowlist; -}; - -/// -bool operator==(RowList::iterator const & i1, - RowList::iterator const & i2); -/// -bool operator!=(RowList::iterator const & i1, - RowList::iterator const & i2); - -/// -bool operator==(RowList::const_iterator const & i1, - RowList::const_iterator const & i2); -/// -bool operator!=(RowList::const_iterator const & i1, - RowList::const_iterator const & i2); +typedef std::list RowList; #endif diff --git a/src/bufferview_funcs.C b/src/bufferview_funcs.C index caf3a78d49..6821ad8157 100644 --- a/src/bufferview_funcs.C +++ b/src/bufferview_funcs.C @@ -393,7 +393,7 @@ void toggleAndShow(BufferView * bv, LyXFont const & font, bool toggleall) if (font.language() != ignore_language || font.number() != LyXFont::IGNORE) { LyXCursor & cursor = text->cursor; - text->computeBidiTables(bv->buffer(), *cursor.row()); + text->computeBidiTables(bv->buffer(), cursor.row()); if (cursor.boundary() != text->isBoundary(bv->buffer(), cursor.par(), cursor.pos(), text->real_current_font)) diff --git a/src/frontends/ChangeLog b/src/frontends/ChangeLog index fd847b81e5..ef6ddc62a5 100644 --- a/src/frontends/ChangeLog +++ b/src/frontends/ChangeLog @@ -1,3 +1,7 @@ +2003-04-01 Lars Gullik Bjønnes + + screen.[Ch]: adjust + 2003-04-01 Lars Gullik Bjønnes * screen.C (topCursorVisible): adjust diff --git a/src/frontends/screen.C b/src/frontends/screen.C index a9f4e4ef5e..8e7d2cd872 100644 --- a/src/frontends/screen.C +++ b/src/frontends/screen.C @@ -265,7 +265,7 @@ void LyXScreen::update(BufferView & bv, int yo, int xo) case LyXText::REFRESH_ROW: { // ok I will update the current cursor row - drawOneRow(text, &bv, &*text->refresh_row, text->refresh_y, + drawOneRow(text, &bv, text->refresh_row, text->refresh_y, yo, xo); // this because if we had a major update the refresh_row could // have been set to 0! @@ -439,7 +439,8 @@ void LyXScreen::drawFromTo(LyXText * text, BufferView * bv, } -void LyXScreen::drawOneRow(LyXText * text, BufferView * bv, Row * row, +void LyXScreen::drawOneRow(LyXText * text, BufferView * bv, + RowList::iterator row, int y_text, int yo, int xo) { int const y = y_text - text->top_y() + yo; diff --git a/src/frontends/screen.h b/src/frontends/screen.h index 2c012d97d7..0c9c1b4233 100644 --- a/src/frontends/screen.h +++ b/src/frontends/screen.h @@ -13,12 +13,12 @@ #ifndef SCREEN_H #define SCREEN_H +#include "RowList.h" class LyXText; class LyXCursor; class WorkArea; class BufferView; -struct Row; /** * LyXScreen - document rendering management @@ -150,8 +150,9 @@ protected: int y_offset = 0, int x_offset = 0); /// y is a coordinate of the text - void drawOneRow(LyXText *, BufferView *, Row * row, - int y_text, int y_offset = 0, int x_offset = 0); + void drawOneRow(LyXText *, BufferView *, + RowList::iterator row, + int y_text, int y_offset = 0, int x_offset = 0); /// is the blinking cursor currently drawn bool cursor_visible_; diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index 4c7fe48c8f..7421f70424 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,3 +1,7 @@ +2003-04-01 Lars Gullik Bjønnes + + * insettext.C: adjust + 2003-04-01 Lars Gullik Bjønnes * insettext.C (draw): adjust diff --git a/src/insets/insettext.C b/src/insets/insettext.C index f91e4f5c68..e76d3cb9b0 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -1210,7 +1210,7 @@ Inset::RESULT InsetText::localDispatch(FuncRequest const & ev) break; case LFUN_PRIOR: - if (!crow(bv)->previous()) + if (crow(bv) == lt->rows().begin()) result = FINISHED_UP; else { lt->cursorPrevious(); @@ -1221,7 +1221,7 @@ Inset::RESULT InsetText::localDispatch(FuncRequest const & ev) break; case LFUN_NEXT: - if (!crow(bv)->next()) + if (boost::next(crow(bv)) == lt->rows().end()) result = FINISHED_DOWN; else { lt->cursorNext(); @@ -1805,7 +1805,7 @@ InsetText::moveLeftIntern(BufferView * bv, bool front, Inset::RESULT InsetText::moveUp(BufferView * bv) { - if (!crow(bv)->previous()) + if (crow(bv) == getLyXText(bv)->rows().begin()) return FINISHED_UP; getLyXText(bv)->cursorUp(bv); getLyXText(bv)->clearSelection(); @@ -1815,7 +1815,7 @@ Inset::RESULT InsetText::moveUp(BufferView * bv) Inset::RESULT InsetText::moveDown(BufferView * bv) { - if (!crow(bv)->next()) + if (boost::next(crow(bv)) == getLyXText(bv)->rows().end()) return FINISHED_DOWN; getLyXText(bv)->cursorDown(bv); getLyXText(bv)->clearSelection(); diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 1a79498173..5aa7e7c40e 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -821,7 +821,7 @@ void LyXFunc::dispatch(FuncRequest const & ev, bool verbose) owner->view_state_changed(); goto exit_with_message; } else if (result == FINISHED_UP) { - if (TEXT()->cursor.irow()->previous()) { + if (TEXT()->cursor.irow() != TEXT()->rows().begin()) { #if 1 TEXT()->setCursorFromCoordinates( TEXT()->cursor.ix() + inset_x, @@ -838,7 +838,7 @@ void LyXFunc::dispatch(FuncRequest const & ev, bool verbose) } goto exit_with_message; } else if (result == FINISHED_DOWN) { - if (TEXT()->cursor.irow()->next()) { + if (boost::next(TEXT()->cursor.irow()) != TEXT()->rows().end()) { #if 1 TEXT()->setCursorFromCoordinates( TEXT()->cursor.ix() + inset_x, @@ -882,7 +882,7 @@ void LyXFunc::dispatch(FuncRequest const & ev, bool verbose) } goto exit_with_message; case LFUN_DOWN: - if (TEXT()->cursor.row()->next()) + if (boost::next(TEXT()->cursor.row()) != TEXT()->rows().end()) TEXT()->cursorDown(view()); else TEXT()->cursorRight(view()); diff --git a/src/lyxrow.C b/src/lyxrow.C index 956c350ee6..99dcf70d82 100644 --- a/src/lyxrow.C +++ b/src/lyxrow.C @@ -24,13 +24,13 @@ using std::min; Row::Row() : par_(0), pos_(0), fill_(0), height_(0), width_(0), - ascent_of_text_(0), baseline_(0), next_(0), previous_(0) + ascent_of_text_(0), baseline_(0) {} Row::Row(Paragraph * pa, pos_type po) : par_(pa), pos_(po), fill_(0), height_(0), width_(0), - ascent_of_text_(0), baseline_(0), next_(0), previous_(0) + ascent_of_text_(0), baseline_(0) {} @@ -52,12 +52,6 @@ unsigned short Row::height() const } -Row * Row::next() const -{ - return next_; -} - - void Row::par(Paragraph * p) { par_ = p; @@ -142,179 +136,7 @@ unsigned int Row::baseline() const } -void Row::next(Row * r) -{ - next_ = r; -} - - -void Row::previous(Row * r) -{ - previous_ = r; -} - - -Row * Row::previous() const -{ - return previous_; -} - - bool Row::isParStart() const { return !pos(); } - - -bool Row::isParEnd() const -{ - return !next() || next()->par() != par(); -} - - -pos_type Row::lastPos() const -{ - if (par()->empty()) - return 0; - - if (isParEnd()) { - return par()->size() - 1; - } else { - return next()->pos() - 1; - } -} - - -namespace { - -bool nextRowIsAllInset(Row const & row, pos_type last) -{ - if (last + 1 >= row.par()->size()) - return false; - - if (!row.par()->isInset(last + 1)) - return false; - - Inset * i = row.par()->getInset(last + 1); - return i->needFullRow() || i->display(); -} - -}; - - -pos_type Row::lastPrintablePos() const -{ - pos_type const last = lastPos(); - - // if this row is an end of par, just act like lastPos() - if (isParEnd()) - return last; - - bool const nextrownotinset = !nextRowIsAllInset(*this, last); - - if (nextrownotinset && par()->isSeparator(last)) - return last - 1; - - return last; -} - - -int Row::numberOfSeparators() const -{ - pos_type const last = lastPrintablePos(); - pos_type p = max(pos(), par()->beginningOfBody()); - - int n = 0; - for (; p < last; ++p) { - if (par()->isSeparator(p)) { - ++n; - } - } - return n; -} - - -int Row::numberOfHfills() const -{ - pos_type const last = lastPos(); - pos_type first = pos(); - - // hfill *DO* count at the beginning of paragraphs! - if (first) { - while (first < last && par()->isHfill(first)) { - ++first; - } - } - - first = max(first, par()->beginningOfBody()); - - int n = 0; - - // last, because the end is ignored! - for (pos_type p = first; p < last; ++p) { - if (par()->isHfill(p)) - ++n; - } - return n; -} - - -int Row::numberOfLabelHfills() const -{ - pos_type last = lastPos(); - pos_type first = pos(); - - // hfill *DO* count at the beginning of paragraphs! - if (first) { - while (first < last && par()->isHfill(first)) - ++first; - } - - last = min(last, par()->beginningOfBody()); - int n = 0; - - // last, because the end is ignored! - for (pos_type p = first; p < last; ++p) { - if (par()->isHfill(p)) - ++n; - } - return n; -} - - -bool Row::hfillExpansion(pos_type pos) const -{ - if (!par()->isHfill(pos)) - return false; - - // at the end of a row it does not count - // unless another hfill exists on the line - if (pos >= lastPos()) { - pos_type i = this->pos(); - while (i < pos && !par()->isHfill(i)) { - ++i; - } - if (i == pos) { - return false; - } - } - - // at the beginning of a row it does not count, if it is not - // the first row of a paragaph - if (isParStart()) - return true; - - // in some labels it does not count - if (par()->layout()->margintype != MARGIN_MANUAL - && pos < par()->beginningOfBody()) - return false; - - // if there is anything between the first char of the row and - // the specified position that is not a newline and not a hfill, - // the hfill will count, otherwise not - pos_type i = this->pos(); - while (i < pos && (par()->isNewline(i) || par()->isHfill(i))) - ++i; - - return i != pos; -} diff --git a/src/lyxrow.h b/src/lyxrow.h index ef7e6bc33c..d239416068 100644 --- a/src/lyxrow.h +++ b/src/lyxrow.h @@ -4,7 +4,8 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author unknown + * \author Matthias Ettrich + * \author Lars Gullik Bjønnes * * Full author contact details are available in file CREDITS * @@ -59,48 +60,8 @@ public: void baseline(unsigned int b); /// unsigned int baseline() const; - /// - void next(Row * r); - /// - Row * next() const; - /// - void previous(Row * r); - /// - Row * previous() const; - /// return true if this row is the start of a paragraph bool isParStart() const; - - /// return true if this row is the end of a paragraph - bool isParEnd() const; - - /// return the position of the last character in this row - lyx::pos_type lastPos() const; - /// return the position of the last normal, printable character in this row - lyx::pos_type lastPrintablePos() const; - - /** - * Returns the number of separators. - * The separator on the very last column doesnt count. - */ - int numberOfSeparators() const; - - /** - * Returns the number of hfills. It works like a LaTeX \hfill: - * the hfills at the beginning and at the end are ignored. - * This is much more useful than not to ignore! - */ - int numberOfHfills() const; - - /// Returns the number of hfills in the manual label. See numberOfHfills(). - int numberOfLabelHfills() const; - - /** - * Returns true if a expansion is needed at the given position. - * Rules are given by LaTeX - */ - bool hfillExpansion(lyx::pos_type pos) const; - private: /// Paragraph * par_; @@ -119,10 +80,6 @@ private: unsigned int top_of_text_; /// unsigned int baseline_; - /// - Row * next_; - /// - Row * previous_; }; #endif diff --git a/src/lyxrow_funcs.C b/src/lyxrow_funcs.C new file mode 100644 index 0000000000..0e857444c8 --- /dev/null +++ b/src/lyxrow_funcs.C @@ -0,0 +1,184 @@ +#include + +#include "lyxrow_funcs.h" +#include "lyxtext.h" +#include "paragraph.h" +#include "lyxlayout.h" + +#include +#include + +using lyx::pos_type; +using std::max; +using std::min; + + +bool isParEnd(LyXText const & lt, RowList::iterator rit) +{ + RowList::iterator next_row = boost::next(rit); + + return next_row == lt.rows().end() || + next_row->par() != rit->par(); +} + + +// It seems that this is only used in LyXText, it +// perhaps this function should be moved into LyXText. (Lgb) +pos_type lastPos(LyXText const & lt, RowList::iterator rit) +{ + if (rit->par()->empty()) + return 0; + + if (isParEnd(lt, rit)) { + return rit->par()->size() - 1; + } else { + return boost::next(rit)->pos() - 1; + } +} + + +namespace { + +bool nextRowIsAllInset(Row const & row, pos_type last) +{ + Paragraph const * par = row.par(); + + if (last + 1 >= par->size()) + return false; + + if (!par->isInset(last + 1)) + return false; + + Inset const * i = par->getInset(last + 1); + return i->needFullRow() || i->display(); +} + +} // anon namespace + + +pos_type lastPrintablePos(LyXText const & lt, RowList::iterator rit) +{ + pos_type const last = lastPos(lt, rit); + + // if this row is an end of par, just act like lastPos() + if (isParEnd(lt, rit)) + return last; + + bool const nextrownotinset = !nextRowIsAllInset(*rit, last); + + if (nextrownotinset && rit->par()->isSeparator(last)) + return last - 1; + + return last; +} + + +int numberOfSeparators(LyXText const & lt, RowList::iterator rit) +{ + pos_type const last = lastPrintablePos(lt, rit); + Paragraph const * par = rit->par(); + + int n = 0; + + pos_type p = max(rit->pos(), par->beginningOfBody()); + for (; p < last; ++p) { + if (par->isSeparator(p)) { + ++n; + } + } + return n; +} + + +// This is called _once_ from LyXText and should at least be moved into +// an anonymous namespace there. (Lgb) +int numberOfHfills(LyXText const & lt, RowList::iterator rit) +{ + pos_type const last = lastPos(lt, rit); + pos_type first = rit->pos(); + Paragraph const * par = rit->par(); + + // hfill *DO* count at the beginning of paragraphs! + if (first) { + while (first < last && par->isHfill(first)) { + ++first; + } + } + + first = max(first, par->beginningOfBody()); + + int n = 0; + + // last, because the end is ignored! + for (pos_type p = first; p < last; ++p) { + if (par->isHfill(p)) + ++n; + } + return n; +} + + +// This is called _once_ from LyXText and should at least be moved into +// an anonymous namespace there. (Lgb) +int numberOfLabelHfills(LyXText const & lt, RowList::iterator rit) +{ + pos_type last = lastPos(lt, rit); + pos_type first = rit->pos(); + Paragraph const * par = rit->par(); + + // hfill *DO* count at the beginning of paragraphs! + if (first) { + while (first < last && par->isHfill(first)) + ++first; + } + + last = min(last, par->beginningOfBody()); + int n = 0; + + // last, because the end is ignored! + for (pos_type p = first; p < last; ++p) { + if (par->isHfill(p)) + ++n; + } + return n; +} + + +bool hfillExpansion(LyXText const & lt, RowList::iterator rit, pos_type pos) +{ + Paragraph const * par = rit->par(); + + if (!par->isHfill(pos)) + return false; + + // at the end of a row it does not count + // unless another hfill exists on the line + if (pos >= lastPos(lt, rit)) { + pos_type i = rit->pos(); + while (i < pos && !par->isHfill(i)) { + ++i; + } + if (i == pos) { + return false; + } + } + + // at the beginning of a row it does not count, if it is not + // the first row of a paragaph + if (rit->isParStart()) + return true; + + // in some labels it does not count + if (par->layout()->margintype != MARGIN_MANUAL + && pos < par->beginningOfBody()) + return false; + + // if there is anything between the first char of the row and + // the specified position that is not a newline and not a hfill, + // the hfill will count, otherwise not + pos_type i = rit->pos(); + while (i < pos && (par->isNewline(i) || par->isHfill(i))) + ++i; + + return i != pos; +} diff --git a/src/lyxrow_funcs.h b/src/lyxrow_funcs.h new file mode 100644 index 0000000000..0ed8955b5a --- /dev/null +++ b/src/lyxrow_funcs.h @@ -0,0 +1,25 @@ +// -*- C++ -*- + +#ifndef LYXROW_FUNCS_H +#define LYXROW_FUNCS_H + +#include "RowList.h" +#include "support/types.h" + +class LyXText; + +bool isParEnd(LyXText const & lt, RowList::iterator rit); + +lyx::pos_type lastPos(LyXText const & lt, RowList::iterator rit); + +lyx::pos_type lastPrintablePos(LyXText const & lt, RowList::iterator rit); + +int numberOfSeparators(LyXText const & lt, RowList::iterator rit); + +int numberOfHfills(LyXText const & lt, RowList::iterator rit); + +int numberOfLabelHfills(LyXText const & lt, RowList::iterator rit); + +bool hfillExpansion(LyXText const & lt, RowList::iterator rit, lyx::pos_type pos); + +#endif diff --git a/src/lyxtext.h b/src/lyxtext.h index 44ce1d749e..f55b9833bb 100644 --- a/src/lyxtext.h +++ b/src/lyxtext.h @@ -476,7 +476,7 @@ public: int workWidth(Inset * inset) const; /// - void computeBidiTables(Buffer const *, Row const & row) const; + void computeBidiTables(Buffer const *, RowList::iterator row) const; /// Maps positions in the visual string to positions in logical string. lyx::pos_type log2vis(lyx::pos_type pos) const; /// Maps positions in the logical string to positions in visual string. @@ -568,13 +568,13 @@ public: * in LaTeX the beginning of the text fits in some cases * (for example sections) exactly the label-width. */ - int leftMargin(RowList::iterator rit) const; + int leftMargin(Row const & row) const; /// int rightMargin(Buffer const &, Row const & row) const; /** this calculates the specified parameters. needed when setting * the cursor and when creating a visible row */ - void prepareToPrint(RowList::iterator rit, float & x, + void prepareToPrint(RowList::iterator row, float & x, float & fill_separator, float & fill_hfill, float & fill_label_hfill, @@ -600,7 +600,7 @@ private: lyx::pos_type rowBreakPoint(Row const & row) const; /// returns the minimum space a row needs on the screen in pixel - int fill(Row & row, int workwidth) const; + int fill(RowList::iterator row, int workwidth) const; /** * returns the minimum space a manual label needs on the diff --git a/src/rowpainter.C b/src/rowpainter.C index 11072c727c..bc9f330130 100644 --- a/src/rowpainter.C +++ b/src/rowpainter.C @@ -31,7 +31,7 @@ #include "lyxrow.h" #include "rowpainter.h" #include "lyxrc.h" - +#include "lyxrow_funcs.h" using std::max; using lyx::pos_type; @@ -53,10 +53,10 @@ BufferView * perv(BufferView const & bv) } // namespace anon -RowPainter::RowPainter(BufferView const & bv, LyXText const & text, RowList::iterator rit) +RowPainter::RowPainter(BufferView const & bv, + LyXText const & text, RowList::iterator rit) : bv_(bv), pain_(bv_.painter()), text_(text), row_(rit), par_(*rit->par()) -{ -} +{} /// "temporary" @@ -97,7 +97,7 @@ char const RowPainter::transformChar(char c, lyx::pos_type pos) const int RowPainter::leftMargin() const { - return text_.leftMargin(row_); + return text_.leftMargin(*row_); } @@ -185,7 +185,7 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos) void RowPainter::paintChars(pos_type & vpos, bool hebrew, bool arabic) { pos_type pos = text_.vis2log(vpos); - pos_type const last = row_->lastPrintablePos(); + pos_type const last = lastPrintablePos(text_, row_); LyXFont orig_font(getFont(pos)); // first character @@ -359,7 +359,7 @@ void RowPainter::paintSelection() pain_.fillRectangle(xo_, yo_, int(x_), row_->height(), LColor::selection); pos_type const body_pos = par_.beginningOfBody(); - pos_type const last = row_->lastPrintablePos(); + pos_type const last = lastPrintablePos(text_, row_); float tmpx = x_; for (pos_type vpos = row_->pos(); vpos <= last; ++vpos) { @@ -375,7 +375,7 @@ void RowPainter::paintSelection() tmpx -= singleWidth(body_pos - 1); } - if (row_->hfillExpansion(pos)) { + if (hfillExpansion(text_, row_, pos)) { tmpx += singleWidth(pos); if (pos >= body_pos) tmpx += hfill_; @@ -411,13 +411,13 @@ void RowPainter::paintSelection() void RowPainter::paintChangeBar() { pos_type const start = row_->pos(); - pos_type const end = row_->lastPrintablePos(); + pos_type const end = lastPrintablePos(text_, row_); if (!par_.isChanged(start, end)) return; - int const height = (row_->next() - ? row_->height() + row_->next()->top_of_text() + int const height = (boost::next(row_) != text_.rows().end() + ? row_->height() + boost::next(row_)->top_of_text() : row_->baseline()); pain_.fillRectangle(4, yo_, 5, height, LColor::changebar); @@ -450,11 +450,11 @@ void RowPainter::paintDepthBar() return; Paragraph::depth_type prev_depth = 0; - if (row_->previous()) - prev_depth = row_->previous()->par()->getDepth(); + if (row_ != text_.rows().begin()) + prev_depth = boost::prior(row_)->par()->getDepth(); Paragraph::depth_type next_depth = 0; - if (row_->next()) - next_depth = row_->next()->par()->getDepth(); + if (boost::next(row_) != text_.rows().end()) + next_depth = boost::next(row_)->par()->getDepth(); for (Paragraph::depth_type i = 1; i <= depth; ++i) { int x = (PAPER_MARGIN / 5) * i + xo_; @@ -620,7 +620,7 @@ void RowPainter::paintFirst() } // the top margin - if (!row_->previous() && !text_.isInInset()) + if (row_ == text_.rows().begin() && !text_.isInInset()) y_top += PAPER_MARGIN; // draw a top pagebreak @@ -767,7 +767,7 @@ void RowPainter::paintLast() int y_bottom = row_->height() - 1; // the bottom margin - if (!row_->next() && !text_.isInInset()) + if (boost::next(row_) == text_.rows().end() && !text_.isInInset()) y_bottom -= PAPER_MARGIN; int const ww = bv_.workWidth(); @@ -846,7 +846,7 @@ void RowPainter::paintLast() void RowPainter::paintText() { - pos_type const last = row_->lastPrintablePos(); + pos_type const last = lastPrintablePos(text_, row_); pos_type body_pos = par_.beginningOfBody(); if (body_pos > 0 && (body_pos - 1 > last || @@ -914,7 +914,7 @@ void RowPainter::paintText() pain_.line(int(x_), y1, int(x_), y0, LColor::added_space); - if (row_->hfillExpansion(pos)) { + if (hfillExpansion(text_, row_, pos)) { int const y2 = (y0 + y1) / 2; if (pos >= body_pos) { @@ -998,7 +998,7 @@ void RowPainter::paint(int y_offset, int x_offset, int y) paintFirst(); } - if (row_->isParEnd()) { + if (isParEnd(text_, row_)) { paintLast(); } diff --git a/src/rowpainter.h b/src/rowpainter.h index efbd99b547..861580b936 100644 --- a/src/rowpainter.h +++ b/src/rowpainter.h @@ -1,3 +1,4 @@ +// -** C++ -*- /** * \file rowpainter.h * This file is part of LyX, the document processor. diff --git a/src/text.C b/src/text.C index f8b12daf21..2a7c7cc445 100644 --- a/src/text.C +++ b/src/text.C @@ -33,6 +33,7 @@ #include "WordLangTuple.h" #include "paragraph_funcs.h" #include "rowpainter.h" +#include "lyxrow_funcs.h" #include "insets/insettext.h" @@ -149,7 +150,7 @@ int LyXText::workWidth(Inset * inset) const Row dummyrow; dummyrow.par(par); dummyrow.pos(pos); - return workWidth() - leftMargin(&dummyrow); + return workWidth() - leftMargin(dummyrow); } else { int dummy_y; RowList::iterator row = getRow(par, pos, dummy_y); @@ -162,7 +163,7 @@ int LyXText::workWidth(Inset * inset) const // FIXME: I don't understand this code - jbl unsigned int maxw = 0; - while (!frow->isParEnd()) { + while (!isParEnd(*this, frow)) { if ((frow != row) && (maxw < frow->width())) maxw = frow->width(); ++frow; @@ -339,7 +340,7 @@ bool LyXText::bidi_InRange(lyx::pos_type pos) const void LyXText::computeBidiTables(Buffer const * buf, - Row const & row) const + RowList::iterator row) const { bidi_same_direction = true; if (!lyxrc.rtl_support) { @@ -347,15 +348,15 @@ void LyXText::computeBidiTables(Buffer const * buf, return; } - Inset * inset = row.par()->inInset(); + Inset * inset = row->par()->inInset(); if (inset && inset->owner() && inset->owner()->lyxCode() == Inset::ERT_CODE) { bidi_start = -1; return; } - bidi_start = row.pos(); - bidi_end = row.lastPrintablePos(); + bidi_start = row->pos(); + bidi_end = lastPrintablePos(*this, row); if (bidi_start > bidi_end) { bidi_start = -1; @@ -377,25 +378,25 @@ void LyXText::computeBidiTables(Buffer const * buf, pos_type stack[2]; bool const rtl_par = - row.par()->isRightToLeftPar(buf->params); + row->par()->isRightToLeftPar(buf->params); int level = 0; bool rtl = false; bool rtl0 = false; - pos_type const body_pos = row.par()->beginningOfBody(); + pos_type const body_pos = row->par()->beginningOfBody(); for (pos_type lpos = bidi_start; lpos <= bidi_end; ++lpos) { - bool is_space = row.par()->isLineSeparator(lpos); + bool is_space = row->par()->isLineSeparator(lpos); pos_type const pos = (is_space && lpos + 1 <= bidi_end && - !row.par()->isLineSeparator(lpos + 1) && - !row.par()->isNewline(lpos + 1)) + !row->par()->isLineSeparator(lpos + 1) && + !row->par()->isNewline(lpos + 1)) ? lpos + 1 : lpos; - LyXFont font = row.par()->getFontSettings(buf->params, pos); + LyXFont font = row->par()->getFontSettings(buf->params, pos); if (pos != lpos && 0 < lpos && rtl0 && font.isRightToLeft() && font.number() == LyXFont::ON && - row.par()->getFontSettings(buf->params, lpos - 1).number() + row->par()->getFontSettings(buf->params, lpos - 1).number() == LyXFont::ON) { - font = row.par()->getFontSettings(buf->params, lpos); + font = row->par()->getFontSettings(buf->params, lpos); is_space = false; } @@ -405,7 +406,7 @@ void LyXText::computeBidiTables(Buffer const * buf, int new_level; if (lpos == body_pos - 1 - && row.pos() < body_pos - 1 + && row->pos() < body_pos - 1 && is_space) { new_level = (rtl_par) ? 1 : 0; new_rtl = new_rtl0 = rtl_par; @@ -500,19 +501,19 @@ bool LyXText::isBoundary(Buffer const * buf, Paragraph * par, } -int LyXText::leftMargin(RowList::iterator rit) const +int LyXText::leftMargin(Row const & row) const { Inset * ins; - if (rit->pos() < rit->par()->size()) - if ((rit->par()->getChar(rit->pos()) == Paragraph::META_INSET) && - (ins = rit->par()->getInset(rit->pos())) && + if (row.pos() < row.par()->size()) + if ((row.par()->getChar(row.pos()) == Paragraph::META_INSET) && + (ins = row.par()->getInset(row.pos())) && (ins->needFullRow() || ins->display())) return LEFT_MARGIN; LyXTextClass const & tclass = bv()->buffer()->params.getLyXTextClass(); - LyXLayout_ptr const & layout = rit->par()->layout(); + LyXLayout_ptr const & layout = row.par()->layout(); string parindent = layout->parindent; @@ -523,12 +524,12 @@ int LyXText::leftMargin(RowList::iterator rit) const // this is the way, LyX handles the LaTeX-Environments. // I have had this idea very late, so it seems to be a // later added hack and this is true - if (!rit->par()->getDepth()) { - if (rit->par()->layout() == tclass.defaultLayout()) { + if (!row.par()->getDepth()) { + if (row.par()->layout() == tclass.defaultLayout()) { // find the previous same level paragraph - if (rit->par()->previous()) { - Paragraph * newpar = rit->par() - ->depthHook(rit->par()->getDepth()); + if (row.par()->previous()) { + Paragraph * newpar = row.par() + ->depthHook(row.par()->getDepth()); if (newpar && newpar->layout()->nextnoindent) parindent.erase(); @@ -537,7 +538,7 @@ int LyXText::leftMargin(RowList::iterator rit) const } else { // find the next level paragraph - Paragraph * newpar = rit->par()->outerHook(); + Paragraph * newpar = row.par()->outerHook(); // make a corresponding row. Needed to call LeftMargin() @@ -546,16 +547,16 @@ int LyXText::leftMargin(RowList::iterator rit) const Row dummyrow; dummyrow.par(newpar); dummyrow.pos(newpar->size()); - x = leftMargin(&dummyrow); + x = leftMargin(dummyrow); } else { // this is no longer an error, because this function // is used to clear impossible depths after changing // a layout. Since there is always a redo, // LeftMargin() is always called - rit->par()->params().depth(0); + row.par()->params().depth(0); } - if (newpar && rit->par()->layout() == tclass.defaultLayout()) { + if (newpar && row.par()->layout() == tclass.defaultLayout()) { if (newpar->params().noindent()) parindent.erase(); else { @@ -565,17 +566,17 @@ int LyXText::leftMargin(RowList::iterator rit) const } } - LyXFont const labelfont = getLabelFont(bv()->buffer(), rit->par()); + LyXFont const labelfont = getLabelFont(bv()->buffer(), row.par()); switch (layout->margintype) { case MARGIN_DYNAMIC: if (!layout->leftmargin.empty()) { x += font_metrics::signedWidth(layout->leftmargin, tclass.defaultfont()); } - if (!rit->par()->getLabelstring().empty()) { + if (!row.par()->getLabelstring().empty()) { x += font_metrics::signedWidth(layout->labelindent, labelfont); - x += font_metrics::width(rit->par()->getLabelstring(), + x += font_metrics::width(row.par()->getLabelstring(), labelfont); x += font_metrics::width(layout->labelsep, labelfont); } @@ -583,9 +584,9 @@ int LyXText::leftMargin(RowList::iterator rit) const case MARGIN_MANUAL: x += font_metrics::signedWidth(layout->labelindent, labelfont); // The width of an empty par, even with manual label, should be 0 - if (!rit->par()->empty() && rit->pos() >= rit->par()->beginningOfBody()) { - if (!rit->par()->getLabelWidthString().empty()) { - x += font_metrics::width(rit->par()->getLabelWidthString(), + if (!row.par()->empty() && row.pos() >= row.par()->beginningOfBody()) { + if (!row.par()->getLabelWidthString().empty()) { + x += font_metrics::width(row.par()->getLabelWidthString(), labelfont); x += font_metrics::width(layout->labelsep, labelfont); } @@ -593,23 +594,23 @@ int LyXText::leftMargin(RowList::iterator rit) const break; case MARGIN_STATIC: x += font_metrics::signedWidth(layout->leftmargin, tclass.defaultfont()) * 4 - / (rit->par()->getDepth() + 4); + / (row.par()->getDepth() + 4); break; case MARGIN_FIRST_DYNAMIC: if (layout->labeltype == LABEL_MANUAL) { - if (rit->pos() >= rit->par()->beginningOfBody()) { + if (row.pos() >= row.par()->beginningOfBody()) { x += font_metrics::signedWidth(layout->leftmargin, labelfont); } else { x += font_metrics::signedWidth(layout->labelindent, labelfont); } - } else if (rit->pos() + } else if (row.pos() // Special case to fix problems with // theorems (JMarc) || (layout->labeltype == LABEL_STATIC && layout->latextype == LATEX_ENVIRONMENT - && ! rit->par()->isFirstInSequence())) { + && ! row.par()->isFirstInSequence())) { x += font_metrics::signedWidth(layout->leftmargin, labelfont); } else if (layout->labeltype != LABEL_TOP_ENVIRONMENT @@ -619,7 +620,7 @@ int LyXText::leftMargin(RowList::iterator rit) const x += font_metrics::signedWidth(layout->labelindent, labelfont); x += font_metrics::width(layout->labelsep, labelfont); - x += font_metrics::width(rit->par()->getLabelstring(), + x += font_metrics::width(row.par()->getLabelstring(), labelfont); } break; @@ -631,14 +632,14 @@ int LyXText::leftMargin(RowList::iterator rit) const // are *NOT* allowed in the LaTeX realisation of this layout. // find the first row of this paragraph - RowList::iterator tmprit = rit; - while (tmprit != rowlist_.begin() - && boost::prior(tmprit)->par() == rit->par()) - --tmprit; + RowList::iterator tmprit = rowlist_.begin(); + while (tmprit != rowlist_.end() + && tmprit->par() != row.par()) + ++tmprit; int minfill = tmprit->fill(); while (boost::next(tmprit) != rowlist_.end() && - boost::next(tmprit)->par() == rit->par()) { + boost::next(tmprit)->par() == row.par()) { ++tmprit; if (tmprit->fill() < minfill) minfill = tmprit->fill(); @@ -652,9 +653,9 @@ int LyXText::leftMargin(RowList::iterator rit) const } if ((workWidth() > 0) && - !rit->par()->params().leftIndent().zero()) + !row.par()->params().leftIndent().zero()) { - LyXLength const len = rit->par()->params().leftIndent(); + LyXLength const len = row.par()->params().leftIndent(); int const tw = inset_owner ? inset_owner->latexTextWidth(bv()) : workWidth(); x += len.inPixels(tw); @@ -662,26 +663,26 @@ int LyXText::leftMargin(RowList::iterator rit) const LyXAlignment align; // wrong type - if (rit->par()->params().align() == LYX_ALIGN_LAYOUT) + if (row.par()->params().align() == LYX_ALIGN_LAYOUT) align = layout->align; else - align = rit->par()->params().align(); + align = row.par()->params().align(); // set the correct parindent - if (rit->pos() == 0) { + if (row.pos() == 0) { if ((layout->labeltype == LABEL_NO_LABEL || layout->labeltype == LABEL_TOP_ENVIRONMENT || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT || (layout->labeltype == LABEL_STATIC && layout->latextype == LATEX_ENVIRONMENT - && ! rit->par()->isFirstInSequence())) + && ! row.par()->isFirstInSequence())) && align == LYX_ALIGN_BLOCK - && !rit->par()->params().noindent() + && !row.par()->params().noindent() // in tabulars and ert paragraphs are never indented! - && (!rit->par()->inInset() || !rit->par()->inInset()->owner() || - (rit->par()->inInset()->owner()->lyxCode() != Inset::TABULAR_CODE && - rit->par()->inInset()->owner()->lyxCode() != Inset::ERT_CODE)) - && (rit->par()->layout() != tclass.defaultLayout() || + && (!row.par()->inInset() || !row.par()->inInset()->owner() || + (row.par()->inInset()->owner()->lyxCode() != Inset::TABULAR_CODE && + row.par()->inInset()->owner()->lyxCode() != Inset::ERT_CODE)) + && (row.par()->layout() != tclass.defaultLayout() || bv()->buffer()->params.paragraph_separation == BufferParams::PARSEP_INDENT)) { x += font_metrics::signedWidth(parindent, @@ -757,7 +758,7 @@ int LyXText::labelEnd(Row const & row) const Row tmprow = row; tmprow.pos(row.par()->size()); // return the beginning of the body - return leftMargin(&tmprow); + return leftMargin(tmprow); } // LabelEnd is only needed if the layout @@ -812,7 +813,7 @@ LyXText::rowBreakPoint(Row const & row) const // or the end of the par, then choose the possible break // nearest that. - int const left = leftMargin(const_cast(&row)); + int const left = leftMargin(const_cast(row)); int x = left; // pixel width since last breakpoint @@ -907,36 +908,36 @@ LyXText::rowBreakPoint(Row const & row) const // returns the minimum space a row needs on the screen in pixel -int LyXText::fill(Row & row, int paper_width) const +int LyXText::fill(RowList::iterator row, int paper_width) const { if (paper_width < 0) return 0; int w; // get the pure distance - pos_type const last = row.lastPrintablePos(); + pos_type const last = lastPrintablePos(*this, row); // special handling of the right address boxes - if (row.par()->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) { - int const tmpfill = row.fill(); - row.fill(0); // the minfill in MarginLeft() - w = leftMargin(&row); - row.fill(tmpfill); + if (row->par()->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) { + int const tmpfill = row->fill(); + row->fill(0); // the minfill in MarginLeft() + w = leftMargin(*row); + row->fill(tmpfill); } else - w = leftMargin(&row); + w = leftMargin(*row); - Paragraph * par = row.par(); + Paragraph * par = row->par(); LyXLayout_ptr const & layout = par->layout(); pos_type const body_pos = par->beginningOfBody(); - pos_type i = row.pos(); + pos_type i = row->pos(); while (i <= last) { if (body_pos > 0 && i == body_pos) { w += font_metrics::width(layout->labelsep, getLabelFont(bv()->buffer(), par)); if (par->isLineSeparator(i - 1)) w -= singleWidth(par, i - 1); - int left_margin = labelEnd(row); + int left_margin = labelEnd(*row); if (w < left_margin) w = left_margin; } @@ -947,12 +948,12 @@ int LyXText::fill(Row & row, int paper_width) const w += font_metrics::width(layout->labelsep, getLabelFont(bv()->buffer(), par)); if (last >= 0 && par->isLineSeparator(last)) w -= singleWidth(par, last); - int const left_margin = labelEnd(row); + int const left_margin = labelEnd(*row); if (w < left_margin) w = left_margin; } - int const fill = paper_width - w - rightMargin(*bv()->buffer(), row); + int const fill = paper_width - w - rightMargin(*bv()->buffer(), *row); return fill; } @@ -1002,6 +1003,10 @@ LColor::color LyXText::backgroundColor() const void LyXText::setHeightOfRow(RowList::iterator rit) { + // No need to do anything then... + if (rit == rows().end()) + return; + // get the maximum ascent and the maximum descent int asc = 0; int desc = 0; @@ -1049,7 +1054,7 @@ void LyXText::setHeightOfRow(RowList::iterator rit) layout->spacing.getValue() * spacing_val); - pos_type const pos_end = rit->lastPos(); + pos_type const pos_end = lastPos(*this, rit); int labeladdon = 0; int maxwidth = 0; @@ -1334,8 +1339,8 @@ void LyXText::appendParagraph(RowList::iterator rowit) if (z < last) { ++z; - rowit = rowlist_.insert(rowit->next(), - new Row(rowit->par(), z)); + Row newrow(rowit->par(), z); + rowit = rowlist_.insert(boost::next(rowit), newrow); } else { done = true; } @@ -1343,8 +1348,8 @@ void LyXText::appendParagraph(RowList::iterator rowit) // Set the dimensions of the row // fixed fill setting now by calling inset->update() in // SingleWidth when needed! - tmprow->fill(fill(*tmprow, workWidth())); - setHeightOfRow(&*tmprow); + tmprow->fill(fill(tmprow, workWidth())); + setHeightOfRow(tmprow); } while (!done); } @@ -1367,7 +1372,8 @@ void LyXText::breakAgain(RowList::iterator rit) boost::next(rit)->par() != rit->par())) { // insert a new row ++z; - rit = rowlist_.insert(boost::next(rit), new Row(rit->par(), z)); + Row newrow(rit->par(), z); + rit = rowlist_.insert(boost::next(rit), newrow); } else { ++rit; ++z; @@ -1381,7 +1387,8 @@ void LyXText::breakAgain(RowList::iterator rit) // if there are some rows too much, delete them // only if you broke the whole paragraph! RowList::iterator tmprit2 = rit; - while (boost::next(tmprit2) != end && boost::next(tmprit2)->par() == rit->par()) { + while (boost::next(tmprit2) != end + && boost::next(tmprit2)->par() == rit->par()) { ++tmprit2; } while (tmprit2 != rit) { @@ -1392,7 +1399,7 @@ void LyXText::breakAgain(RowList::iterator rit) } // set the dimensions of the row - tmprit->fill(fill(*tmprit, workWidth())); + tmprit->fill(fill(tmprit, workWidth())); setHeightOfRow(tmprit); } while (not_ready); } @@ -1405,13 +1412,16 @@ void LyXText::breakAgainOneRow(RowList::iterator rit) pos_type z = rowBreakPoint(*rit); RowList::iterator tmprit = rit; + RowList::iterator end = rows().end(); if (z < rit->par()->size()) { - if (boost::next(rit) == rows().end() - || (boost::next(rit) != rows().end() && boost::next(rit)->par() != rit->par())) { + if (boost::next(rit) == end || + (boost::next(rit) != end && + boost::next(rit)->par() != rit->par())) { // insert a new row ++z; - rit = rowlist_.insert(boost::next(rit), new Row(rit->par(), z)); + Row newrow(rit->par(), z); + rit = rowlist_.insert(boost::next(rit), newrow); } else { ++rit; ++z; @@ -1422,7 +1432,7 @@ void LyXText::breakAgainOneRow(RowList::iterator rit) // if there are some rows too much, delete them // only if you broke the whole paragraph! RowList::iterator tmprit2 = rit; - while (boost::next(tmprit2) != rows().end() + while (boost::next(tmprit2) != end && boost::next(tmprit2)->par() == rit->par()) { ++tmprit2; } @@ -1433,7 +1443,7 @@ void LyXText::breakAgainOneRow(RowList::iterator rit) } // set the dimensions of the row - tmprit->fill(fill(*tmprit, workWidth())); + tmprit->fill(fill(tmprit, workWidth())); setHeightOfRow(tmprit); } @@ -1516,7 +1526,7 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout) removeParagraph(cursor.row()); // set the dimensions of the cursor row - cursor.row()->fill(fill(*cursor.row(), workWidth())); + cursor.row()->fill(fill(cursor.row(), workWidth())); setHeightOfRow(cursor.row()); @@ -1528,7 +1538,7 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout) && cursor.par()->next()->isNewline(0)) cursor.par()->next()->erase(0); - insertParagraph(cursor.par()->next(), cursor.row()->next()); + insertParagraph(cursor.par()->next(), boost::next(cursor.row())); updateCounters(); // This check is necessary. Otherwise the new empty paragraph will @@ -1538,8 +1548,8 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout) else setCursor(cursor.par(), 0); - if (cursor.row()->next()) - breakAgain(cursor.row()->next()); + if (boost::next(cursor.row()) != rows().end()) + breakAgain(boost::next(cursor.row())); need_break_row = rows().end(); } @@ -1687,26 +1697,27 @@ void LyXText::insertChar(char c) } // Is there a break one row above - if (row->previous() && row->previous()->par() == row->par() + if (row != rows().begin() && + boost::prior(row)->par() == row->par() && (cursor.par()->isLineSeparator(cursor.pos()) || cursor.par()->isNewline(cursor.pos()) || ((cursor.pos() + 1 < cursor.par()->size()) && cursor.par()->isInset(cursor.pos() + 1)) || cursor.row()->fill() == -1)) { - pos_type z = rowBreakPoint(*row->previous()); + pos_type z = rowBreakPoint(*boost::prior(row)); if (z >= row->pos()) { row->pos(z + 1); // set the dimensions of the row above - row->previous()->fill(fill( - *row->previous(), + boost::prior(row)->fill(fill( + boost::prior(row), workWidth())); - setHeightOfRow(row->previous()); + setHeightOfRow(boost::prior(row)); - y -= row->previous()->height(); + y -= boost::prior(row)->height(); postPaint(y); @@ -1718,8 +1729,9 @@ void LyXText::insertChar(char c) false, cursor.boundary()); // cursor MUST be in row now. - if (row->next() && row->next()->par() == row->par()) - need_break_row = row->next(); + if (boost::next(row) != rows().end() && + boost::next(row)->par() == row->par()) + need_break_row = boost::next(row); else need_break_row = rows().end(); @@ -1737,17 +1749,19 @@ void LyXText::insertChar(char c) if (row->fill() >= 0) { // needed because a newline will set fill to -1. Otherwise // we would not get a rebreak! - row->fill(fill(*row, workWidth())); + row->fill(fill(row, workWidth())); } if (c == Paragraph::META_INSET || row->fill() < 0) { postPaint(y); breakAgainOneRow(row); // will the cursor be in another row now? - if (row->lastPos() <= cursor.pos() + 1 && row->next()) { - if (row->next() && row->next()->par() == row->par()) + if (lastPos(*this, row) <= cursor.pos() + 1 && + boost::next(row) != rows().end()) { + if (boost::next(row) != rows().end() && + boost::next(row)->par() == row->par()) // this should always be true - row = row->next(); + ++row; breakAgainOneRow(row); } current_font = rawtmpfont; @@ -1759,8 +1773,9 @@ void LyXText::insertChar(char c) != cursor.boundary()) setCursor(cursor.par(), cursor.pos(), false, !cursor.boundary()); - if (row->next() && row->next()->par() == row->par()) - need_break_row = row->next(); + if (boost::next(row) != rows().end() && + boost::next(row)->par() == row->par()) + need_break_row = boost::next(row); else need_break_row = rows().end(); } else { @@ -1818,7 +1833,6 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x, bool bidi) const { float nlh; - float ns; float w = rit->fill(); fill_hfill = 0; @@ -1833,7 +1847,7 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x, ? rightMargin(*bv()->buffer(), *rit) : 0; } else x = (workWidth() > 0) - ? leftMargin(rit) : 0; + ? leftMargin(*rit) : 0; // is there a manual margin with a manual label LyXLayout_ptr const & layout = rit->par()->layout(); @@ -1841,7 +1855,7 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x, if (layout->margintype == MARGIN_MANUAL && layout->labeltype == LABEL_MANUAL) { /// We might have real hfills in the label part - nlh = rit->numberOfLabelHfills(); + nlh = numberOfLabelHfills(*this, rit); // A manual label par (e.g. List) has an auto-hfill // between the label text and the body of the @@ -1857,7 +1871,7 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x, } // are there any hfills in the row? - float const nh = rit->numberOfHfills(); + float const nh = numberOfHfills(*this, rit); if (nh) { if (w > 0) @@ -1894,16 +1908,16 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x, switch (align) { case LYX_ALIGN_BLOCK: { - ns = rit->numberOfSeparators(); + float const ns = numberOfSeparators(*this, rit); RowList::iterator next_row = boost::next(rit); + if (ns && next_row != rowlist_.end() && next_row->par() == rit->par() && !(next_row->par()->isNewline(next_row->pos() - 1)) && !(next_row->par()->isInset(next_row->pos()) && next_row->par()->getInset(next_row->pos()) && next_row->par()->getInset(next_row->pos())->display()) - ) - { + ) { fill_separator = w / ns; } else if (is_rtl) { x += w; @@ -1921,10 +1935,10 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x, if (!bidi) return; - computeBidiTables(bv()->buffer(), *rit); + computeBidiTables(bv()->buffer(), rit); if (is_rtl) { pos_type body_pos = rit->par()->beginningOfBody(); - pos_type last = rit->lastPos(); + pos_type last = lastPos(*this, rit); if (body_pos > 0 && (body_pos - 1 > last || @@ -2612,7 +2626,7 @@ void LyXText::backspace() pos_type z; // remember that a space at the end of a row doesnt count // when calculating the fill - if (cursor.pos() < row->lastPos() || + if (cursor.pos() < lastPos(*this, row) || !cursor.par()->isLineSeparator(cursor.pos())) { row->fill(row->fill() + singleWidth( cursor.par(), @@ -2697,7 +2711,7 @@ void LyXText::backspace() // set the dimensions of the row above y -= tmprow->height(); - tmprow->fill(fill(*tmprow, workWidth())); + tmprow->fill(fill(tmprow, workWidth())); setHeightOfRow(tmprow); postPaint(y); @@ -2718,14 +2732,14 @@ void LyXText::backspace() // break the cursor row again if (boost::next(row) != rows().end() && boost::next(row)->par() == row->par() && - (row->lastPos() == row->par()->size() - 1 || - rowBreakPoint(*row) != row->lastPos())) { + (lastPos(*this, row) == row->par()->size() - 1 || + rowBreakPoint(*row) != lastPos(*this, row))) { // it can happen that a paragraph loses one row // without a real breakup. This is when a word // is to long to be broken. Well, I don t care this // hack ;-) - if (row->lastPos() == row->par()->size() - 1) + if (lastPos(*this, row) == row->par()->size() - 1) removeRow(boost::next(row)); postPaint(y); @@ -2734,7 +2748,7 @@ void LyXText::backspace() // will the cursor be in another row now? if (boost::next(row) != rows().end() && boost::next(row)->par() == row->par() && - row->lastPos() <= cursor.pos()) { + lastPos(*this, row) <= cursor.pos()) { ++row; breakAgainOneRow(row); } @@ -2748,7 +2762,7 @@ void LyXText::backspace() need_break_row = rows().end(); } else { // set the dimensions of the row - row->fill(fill(*row, workWidth())); + row->fill(fill(row, workWidth())); int const tmpheight = row->height(); setHeightOfRow(row); if (tmpheight == row->height()) { diff --git a/src/text2.C b/src/text2.C index 0f30089627..043605db46 100644 --- a/src/text2.C +++ b/src/text2.C @@ -29,6 +29,7 @@ #include "language.h" #include "ParagraphParameters.h" #include "counters.h" +#include "lyxrow_funcs.h" #include "insets/inseterror.h" #include "insets/insetbibitem.h" @@ -58,6 +59,7 @@ LyXText::LyXText(BufferView * bv) anchor_row_ = rows().end(); need_break_row = rows().end(); refresh_row = rows().end(); + clearPaint(); } @@ -69,6 +71,7 @@ LyXText::LyXText(BufferView * bv, InsetText * inset) anchor_row_ = rows().end(); need_break_row = rows().end(); refresh_row = rows().end(); + clearPaint(); } @@ -308,7 +311,8 @@ void LyXText::removeParagraph(RowList::iterator rit) void LyXText::insertParagraph(Paragraph * par, RowList::iterator rowit) { // insert a new row, starting at position 0 - RowList::iterator rit = rowlist_.insert(rowit, new Row(par, 0)); + Row newrow(par, 0); + RowList::iterator rit = rowlist_.insert(rowit, newrow); // and now append the whole paragraph before the new row appendParagraph(rit); @@ -889,18 +893,22 @@ void LyXText::cursorEnd() { if (cursor.par()->empty()) return; +#warning FIXME +// There is a lot of unneeded recalculation going on here: +// - boost::next(curosr.row()) +// - lastPost(*this, cursor.row()) - if (!cursor.row()->next() - || cursor.row()->next()->par() != cursor.row()->par()) { - setCursor(cursor.par(), cursor.row()->lastPos() + 1); + if (boost::next(cursor.row()) == rows().end() + || boost::next(cursor.row())->par() != cursor.row()->par()) { + setCursor(cursor.par(), lastPos(*this, cursor.row()) + 1); } else { if (!cursor.par()->empty() && - (cursor.par()->getChar(cursor.row()->lastPos()) == ' ' - || cursor.par()->isNewline(cursor.row()->lastPos()))) { - setCursor(cursor.par(), cursor.row()->lastPos()); + (cursor.par()->getChar(lastPos(*this, cursor.row())) == ' ' + || cursor.par()->isNewline(lastPos(*this, cursor.row())))) { + setCursor(cursor.par(), lastPos(*this, cursor.row())); } else { setCursor(cursor.par(), - cursor.row()->lastPos() + 1); + lastPos(*this, cursor.row()) + 1); } } } @@ -1579,11 +1587,11 @@ void LyXText::checkParagraph(Paragraph * par, pos_type pos) } int const tmpheight = row->height(); - pos_type const tmplast = row->lastPos(); + pos_type const tmplast = lastPos(*this, row); - breakAgain(&*row); - if (row->height() == tmpheight && row->lastPos() == tmplast) { - postRowPaint(&*row, y); + breakAgain(row); + if (row->height() == tmpheight && lastPos(*this, row) == tmplast) { + postRowPaint(row, y); } else { postPaint(y); } @@ -1591,7 +1599,7 @@ void LyXText::checkParagraph(Paragraph * par, pos_type pos) // check the special right address boxes if (par->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) { tmpcursor.par(par); - tmpcursor.row(&*row); + tmpcursor.row(row); tmpcursor.y(y); tmpcursor.x(0); tmpcursor.x_fix(0); @@ -1693,13 +1701,13 @@ void LyXText::setCursor(LyXCursor & cur, Paragraph * par, y -= row->height(); } - cur.row(&*row); + cur.row(row); // y is now the beginning of the cursor row y += row->baseline(); // y is now the cursor baseline cur.y(y); - pos_type last = old_row->lastPrintablePos(); + pos_type last = lastPrintablePos(*this, old_row); // None of these should happen, but we're scaredy-cats if (pos > par->size()) { @@ -1718,18 +1726,18 @@ void LyXText::setCursor(LyXCursor & cur, Paragraph * par, } // now get the cursors x position - float x = getCursorX(&*row, pos, last, boundary); + float x = getCursorX(row, pos, last, boundary); cur.x(int(x)); cur.x_fix(cur.x()); if (old_row != row) { - x = getCursorX(&*old_row, pos, last, boundary); + x = getCursorX(old_row, pos, last, boundary); cur.ix(int(x)); } else cur.ix(cur.x()); //if the cursor is in a visible row, anchor to it int topy = top_y(); if (topy < y && y < topy + bv()->workHeight()) - anchor_row(&*row); + anchor_row(row); } @@ -1777,7 +1785,8 @@ float LyXText::getCursorX(RowList::iterator rit, if (rit->par()->isLineSeparator(body_pos - 1)) x -= singleWidth(rit->par(), body_pos - 1); } - if (rit->hfillExpansion(pos)) { + + if (hfillExpansion(*this, rit, pos)) { x += singleWidth(rit->par(), pos); if (pos >= body_pos) x += fill_hfill; @@ -1880,7 +1889,7 @@ LyXText::getColumnNearX(RowList::iterator rit, int & x, bool & boundary) const fill_hfill, fill_label_hfill); pos_type vc = rit->pos(); - pos_type last = rit->lastPrintablePos(); + pos_type last = lastPrintablePos(*this, rit); pos_type c = 0; LyXLayout_ptr const & layout = rit->par()->layout(); @@ -1912,7 +1921,7 @@ LyXText::getColumnNearX(RowList::iterator rit, int & x, bool & boundary) const tmpx -= singleWidth(rit->par(), body_pos - 1); } - if (rit->hfillExpansion(c)) { + if (hfillExpansion(*this, rit, c)) { tmpx += singleWidth(rit->par(), c); if (c >= body_pos) tmpx += fill_hfill; @@ -1996,10 +2005,11 @@ namespace { * and the next row is filled by an inset that spans an entire * row. */ - bool beforeFullRowInset(Row & row, LyXCursor & cur) { - if (!row.next()) + bool beforeFullRowInset(LyXText & lt, RowList::iterator row, + LyXCursor & cur) { + if (boost::next(row) == lt.rows().end()) return false; - Row const & next = *row.next(); + Row const & next = *boost::next(row); if (next.pos() != cur.pos() || next.par() != cur.par()) return false; @@ -2019,23 +2029,23 @@ void LyXText::setCursorFromCoordinates(LyXCursor & cur, int x, int y) RowList::iterator row = getRowNearY(y); bool bound = false; - pos_type const column = getColumnNearX(&*row, x, bound); + pos_type const column = getColumnNearX(row, x, bound); cur.par(row->par()); cur.pos(row->pos() + column); cur.x(x); cur.y(y + row->baseline()); - cur.row(&*row); + cur.row(row); - if (beforeFullRowInset(*row, cur)) { - pos_type last = row->lastPrintablePos(); - float x = getCursorX(row->next(), cur.pos(), last, bound); + if (beforeFullRowInset(*this, row, cur)) { + pos_type last = lastPrintablePos(*this, row); + float x = getCursorX(boost::next(row), cur.pos(), last, bound); cur.ix(int(x)); - cur.iy(y + row->height() + row->next()->baseline()); - cur.irow(row->next()); + cur.iy(y + row->height() + boost::next(row)->baseline()); + cur.irow(boost::next(row)); } else { cur.iy(cur.y()); cur.ix(cur.x()); - cur.irow(&*row); + cur.irow(row); } cur.boundary(bound); } @@ -2257,9 +2267,9 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor) deleted = true; - if (old_cursor.row()->previous()) { + if (old_cursor.row() != rows().begin()) { const_cast(this)->postPaint(old_cursor.y() - old_cursor.row()->baseline() - - old_cursor.row()->previous()->height()); + - boost::prior(old_cursor.row())->height()); tmpcursor = cursor; cursor = old_cursor; // that undo can restore the right cursor position Paragraph * endpar = old_cursor.par()->next(); @@ -2284,14 +2294,14 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor) * The next row can change its height, if * there is another layout before */ if (refresh_row != rows().end()) { - if (refresh_row->next()) { - breakAgain(refresh_row->next()); + if (boost::next(refresh_row) != rows().end()) { + breakAgain(boost::next(refresh_row)); updateCounters(); } setHeightOfRow(refresh_row); } } else { - Row * nextrow = old_cursor.row()->next(); + RowList::iterator nextrow = boost::next(old_cursor.row()); const_cast(this)->postPaint( old_cursor.y() - old_cursor.row()->baseline()); @@ -2319,7 +2329,7 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor) the parindent that can occur or dissappear. The next row can change its height, if there is another layout before */ - if (nextrow) { + if (nextrow != rows().end()) { breakAgain(nextrow); updateCounters(); } diff --git a/src/text3.C b/src/text3.C index d5c5d595af..12adb07c32 100644 --- a/src/text3.C +++ b/src/text3.C @@ -240,7 +240,7 @@ void LyXText::cursorPrevious() { int y = top_y(); - if (!cursor.row()->previous()) { + if (cursor.row() == rows().begin()) { if (y > 0) { int new_y = bv()->text->top_y() - bv()->workHeight(); bv()->screen().draw(bv()->text, bv(), new_y < 0 ? 0 : new_y); @@ -279,10 +279,10 @@ void LyXText::cursorPrevious() } } bv()->screen().draw(bv()->text, bv(), new_y < 0 ? 0 : new_y); - if (cursor.row()->previous()) { + if (cursor.row() != rows().begin()) { LyXCursor cur; - setCursor(cur, cursor.row()->previous()->par(), - cursor.row()->previous()->pos(), false); + setCursor(cur, boost::prior(cursor.row())->par(), + boost::prior(cursor.row())->pos(), false); if (cur.y() > top_y()) { cursorUp(true); } @@ -295,7 +295,7 @@ void LyXText::cursorNext() { int topy = top_y(); - if (!cursor.row()->next()) { + if (boost::next(cursor.row()) == rows().end()) { int y = cursor.y() - cursor.row()->baseline() + cursor.row()->height(); if (y > topy + bv()->workHeight()) { @@ -340,10 +340,10 @@ void LyXText::cursorNext() } } bv()->screen().draw(bv()->text, bv(), new_y); - if (cursor.row()->next()) { + if (boost::next(cursor.row()) != rows().end()) { LyXCursor cur; - setCursor(cur, cursor.row()->next()->par(), - cursor.row()->next()->pos(), false); + setCursor(cur, boost::next(cursor.row())->par(), + boost::next(cursor.row())->pos(), false); if (cur.y() < top_y() + bv()->workHeight()) { cursorDown(true); } @@ -416,7 +416,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) setUndo(bv, Undo::EDIT, tmp, tmp->next()); tmp->params().startOfAppendix(false); int tmpy; - setHeightOfRow(&*getRow(tmp, 0, tmpy)); + setHeightOfRow(getRow(tmp, 0, tmpy)); break; } }