From b7f49f9b42d5345209d09ae933d901411912cd80 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Fri, 22 Aug 2003 07:49:57 +0000 Subject: [PATCH] * lyxrow.[Ch]: add end_ member * lyxrow_funcs.C: use LyXRow::end_ * lyxtext.h (singleWidth): add LyXFont parameter * rowpainter.C: * text2.C: adjust LyXText::singleWidth() calls * text.C (redoParagraph): simplify row breaking logic git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7580 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/ChangeLog | 13 +++++++++ src/lyxrow.C | 20 +++++++++++--- src/lyxrow.h | 8 +++++- src/lyxrow_funcs.C | 24 ++++++++++++++-- src/lyxtext.h | 8 ++---- src/rowpainter.C | 3 +- src/text.C | 68 ++++++++++++---------------------------------- src/text2.C | 61 ++++++++++++++++++----------------------- 8 files changed, 107 insertions(+), 98 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 6c8ab57e01..23e72dca2f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,4 +1,17 @@ +2003-08-22 André Pönitz + + * lyxrow.[Ch]: add end_ member + + * lyxrow_funcs.C: use LyXRow::end_ + + * lyxtext.h (singleWidth): add LyXFont parameter + + * rowpainter.C: + * text2.C: adjust LyXText::singleWidth() calls + + * text.C (redoParagraph): simplify row breaking logic + 2003-08-19 André Pönitz * funcrequest.C: initialize button_ member diff --git a/src/lyxrow.C b/src/lyxrow.C index 204dbf5ea9..40adfda748 100644 --- a/src/lyxrow.C +++ b/src/lyxrow.C @@ -21,13 +21,13 @@ using std::max; using std::min; Row::Row() - : pos_(0), fill_(0), height_(0), width_(0), y_(0), + : pos_(0), end_(0), fill_(0), height_(0), width_(0), y_(0), ascent_of_text_(0), baseline_(0) {} -Row::Row(pos_type po) - : pos_(po), fill_(0), height_(0), width_(0), y_(0), +Row::Row(pos_type pos) + : pos_(pos), end_(0), fill_(0), height_(0), width_(0), y_(0), ascent_of_text_(0), baseline_(0) {} @@ -62,6 +62,18 @@ pos_type Row::pos() const } +void Row::end(pos_type p) +{ + end_ = p; +} + + +pos_type Row::end() const +{ + return end_; +} + + void Row::fill(int f) { fill_ = f; @@ -141,6 +153,6 @@ void Row::dump(const char * s) const << " fill: " << fill_ << " ascent_of_text: " << ascent_of_text_ << " top_of_text: " << top_of_text_ - << " y: " << y_ << "\n"; + << " y: " << y_ << std::endl; } diff --git a/src/lyxrow.h b/src/lyxrow.h index b1612974e8..7c6fbf7526 100644 --- a/src/lyxrow.h +++ b/src/lyxrow.h @@ -29,6 +29,10 @@ public: /// lyx::pos_type pos() const; /// + void end(lyx::pos_type p); + /// + lyx::pos_type end() const; + /// void fill(int f); /// int fill() const; @@ -61,8 +65,10 @@ public: /// current debugging only void dump(const char * = "") const; private: - /// + /// first pos covered by this row lyx::pos_type pos_; + /// one behind last pos covered by this row + lyx::pos_type end_; /** what is missing to a full row. Can be negative. Needed for hfills, flushright, block etc. */ mutable int fill_; diff --git a/src/lyxrow_funcs.C b/src/lyxrow_funcs.C index 85154f9d13..3b6c0b44fe 100644 --- a/src/lyxrow_funcs.C +++ b/src/lyxrow_funcs.C @@ -4,18 +4,32 @@ #include "lyxtext.h" #include "paragraph.h" #include "lyxlayout.h" +#include "debug.h" + +#include "support/LAssert.h" #include #include using lyx::pos_type; +using lyx::support::Assert; using std::max; using std::min; +using std::endl; bool isParEnd(Paragraph const & par, RowList::iterator rit) { +#if 0 + if ((boost::next(rit) == par.rows.end()) != (rit->end() >= par.size())) { + lyxerr << endl; + lyxerr << "broken row 1: end: " << rit->end() << " next: " + << boost::next(rit)->pos() << endl; + lyxerr << endl; + Assert(false); + } +#endif return boost::next(rit) == par.rows.end(); } @@ -28,14 +42,20 @@ pos_type lastPos(Paragraph const & par, RowList::iterator rit) if (isParEnd(par, rit)) return par.size() - 1; + if (1 && boost::next(rit)->pos() != rit->end()) { + lyxerr << endl; + lyxerr << "broken row 2: end: " << rit->end() << " next: " + << boost::next(rit)->pos() << endl; + lyxerr << endl; + Assert(false); + } return boost::next(rit)->pos() - 1; } namespace { -bool nextRowIsAllInset( - Paragraph const & par, pos_type last) +bool nextRowIsAllInset(Paragraph const & par, pos_type last) { if (last + 1 >= par.size()) return false; diff --git a/src/lyxtext.h b/src/lyxtext.h index c1cb635c7c..ca313e558f 100644 --- a/src/lyxtext.h +++ b/src/lyxtext.h @@ -402,9 +402,7 @@ public: int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const; /// int singleWidth(ParagraphList::iterator pit, - lyx::pos_type pos, char c) const; - /// rebuild row cache - void rebuildRows(ParagraphList::iterator pit); + lyx::pos_type pos, char c, LyXFont const & Font) const; /// return the color of the canvas LColor::color backgroundColor() const; @@ -450,8 +448,8 @@ private: */ - /// return the pos value *before* which a row should break. - /// for example, the pos at which IsNewLine(pos) == true + /// sets row.end to the pos value *after* which a row should break. + /// for example, the pos after which isNewLine(pos) == true lyx::pos_type rowBreakPoint(ParagraphList::iterator pit, Row const & row) const; diff --git a/src/rowpainter.C b/src/rowpainter.C index f1adf7e0ee..e0a14df12c 100644 --- a/src/rowpainter.C +++ b/src/rowpainter.C @@ -152,7 +152,8 @@ int RowPainter::singleWidth(lyx::pos_type pos) const int RowPainter::singleWidth(lyx::pos_type pos, char c) const { - return text_.singleWidth(pit_, pos, c); + LyXFont const & font = text_.getFont(pit_, pos); + return text_.singleWidth(pit_, pos, c, font); } diff --git a/src/text.C b/src/text.C index aac2638915..235e74aaef 100644 --- a/src/text.C +++ b/src/text.C @@ -192,17 +192,20 @@ int LyXText::singleWidth(ParagraphList::iterator pit, pos_type pos) const return 0; char const c = pit->getChar(pos); - return singleWidth(pit, pos, c); + LyXFont const & font = getFont(pit, pos); + return singleWidth(pit, pos, c, font); } int LyXText::singleWidth(ParagraphList::iterator pit, - pos_type pos, char c) const + pos_type pos, char c, LyXFont const & font) const { - if (pos >= pit->size()) + if (pos >= pit->size()) { + lyxerr << "in singleWidth(), pos: " << pos << endl; + Assert(false); return 0; + } - LyXFont const & font = getFont(pit, pos); // The most common case is handled first (Asger) if (IsPrintable(c)) { @@ -729,29 +732,9 @@ pos_type LyXText::rowBreakPoint(ParagraphList::iterator pit, int left_margin = labelEnd(pit, row); if (thiswidth + x < left_margin) thiswidth = left_margin - x; - thiswidth += singleWidth(pit, i, c); + thiswidth += singleWidth(pit, i, c, font); } else { - // Manual inlined optimised version of common case of "thiswidth = singleWidth(pit, i, c);" - if (IsPrintable(c)) { - if (pos > endPosOfFontSpan) { - // We need to get the next font - font = getFont(pit, i); - endPosOfFontSpan = pit->getEndPosOfFontSpan(i); - } - if (! font.language()->RightToLeft()) { - thiswidth = font_metrics::width(c, font); - } else { - // Fall-back to normal case - thiswidth = singleWidth(pit, i, c); - // And flush font cache - endPosOfFontSpan = 0; - } - } else { - // Fall-back to normal case - thiswidth = singleWidth(pit, i, c); - // And flush font cache - endPosOfFontSpan = 0; - } + thiswidth = singleWidth(pit, i, c, font); } x += thiswidth; @@ -860,30 +843,13 @@ int LyXText::fill(ParagraphList::iterator pit, if (w < left_margin) w = left_margin; } - { // Manual inlined an optimised version of the common case of "w += singleWidth(pit, i);" - char const c = pit->getChar(i); - - if (IsPrintable(c)) { - if (i > endPosOfFontSpan) { - // We need to get the next font - font = getFont(pit, i); - endPosOfFontSpan = pit->getEndPosOfFontSpan(i); - } - if (!font.language()->RightToLeft()) { - w += font_metrics::width(c, font); - } else { - // Fall-back to the normal case - w += singleWidth(pit, i, c); - // And flush font cache - endPosOfFontSpan = 0; - } - } else { - // Fall-back to the normal case - w += singleWidth(pit, i, c); - // And flush font cache - endPosOfFontSpan = 0; - } + char const c = pit->getChar(i); + if (IsPrintable(c) && i > endPosOfFontSpan) { + // We need to get the next font + font = getFont(pit, i); + endPosOfFontSpan = pit->getEndPosOfFontSpan(i); } + w += singleWidth(pit, i, c, font); ++i; } } @@ -1020,7 +986,7 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, RowList::iterator rit) maxwidth += font_metrics::width(c, font); } else { // Fall-back to normal case - maxwidth += singleWidth(pit, pos, c); + maxwidth += singleWidth(pit, pos, c, font); // And flush font cache endPosOfFontSpan = 0; } @@ -1047,7 +1013,7 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, RowList::iterator rit) } } else { // Fall-back to normal case - maxwidth += singleWidth(pit, pos, c); + maxwidth += singleWidth(pit, pos, c, font); // And flush font cache endPosOfFontSpan = 0; } diff --git a/src/text2.C b/src/text2.C index e2ae52d493..6c644bd944 100644 --- a/src/text2.C +++ b/src/text2.C @@ -550,32 +550,23 @@ void LyXText::redoParagraph(ParagraphList::iterator pit) RowList::iterator rit = pit->rows.begin(); RowList::iterator end = pit->rows.end(); - // remove rows of paragraph + // remove rows of paragraph, keep track of height changes for (int i = 0; rit != end; ++rit, ++i) height -= rit->height(); - pit->rows.clear(); // rebreak the paragraph - // insert a new row, starting at position 0 - - pos_type z = 0; - pit->rows.push_back(Row(z)); - bool done = false; - while (!done) { - z = rowBreakPoint(pit, pit->rows.back()); - - RowList::iterator tmprow = boost::prior(pit->rows.end()); - - if (z >= pit->size()) - done = true; - else { - ++z; - pit->rows.push_back(Row(z)); - } + for (pos_type z = 0; z < pit->size() + 1; ) { + Row row(z); + z = rowBreakPoint(pit, row) + 1; + row.end(z); + pit->rows.push_back(row); + } - tmprow->fill(fill(pit, tmprow, workWidth())); - setHeightOfRow(pit, tmprow); + // set height and fill of rows + for (rit = pit->rows.begin(); rit != end; ++rit) { + rit->fill(fill(pit, rit, workWidth())); + setHeightOfRow(pit, rit); } //lyxerr << "redoParagraph: " << pit->rows.size() << " rows\n"; @@ -1666,23 +1657,25 @@ void LyXText::setCursorFromCoordinates(LyXCursor & cur, int x, int y) { // Get the row first. ParagraphList::iterator pit; - RowList::iterator row = getRowNearY(y, pit); + RowList::iterator rit = getRowNearY(y, pit); bool bound = false; - pos_type const column = getColumnNearX(pit, row, x, bound); + pos_type const column = getColumnNearX(pit, rit, x, bound); cur.par(pit); - cur.pos(row->pos() + column); + cur.pos(rit->pos() + column); cur.x(x); - cur.y(y + row->baseline()); - -// if (beforeFullRowInset(*this, cur)) { -// pos_type const last = lastPrintablePos(*this, pit, row); -// RowList::iterator next_row = nextRow(row); -// cur.ix(int(getCursorX(pit, next_row, cur.pos(), last, bound))); -// cur.iy(y + row->height() + next_row->baseline()); -// } else { + cur.y(y + rit->baseline()); + + if (beforeFullRowInset(*this, cur)) { + pos_type const last = lastPrintablePos(*pit, rit); + RowList::iterator next_rit = rit; + ParagraphList::iterator next_pit = pit; + nextRow(next_pit, next_rit); + cur.ix(int(getCursorX(pit, next_rit, cur.pos(), last, bound))); + cur.iy(y + rit->height() + next_rit->baseline()); + } else { cur.iy(cur.y()); cur.ix(cur.x()); -// } + } cur.boundary(bound); } @@ -1833,7 +1826,7 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor) There are still some small problems that can lead to double spaces stored in the document file or space at the beginning of paragraphs. This happens if you have - the cursor betwenn to spaces and then save. Or if you + the cursor between to spaces and then save. Or if you cut and paste and the selection have a space at the beginning and then save right after the paste. I am sure none of these are very hard to fix, but I will @@ -1897,7 +1890,7 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor) if (old_cursor.par()->empty() || (old_cursor.par()->size() == 1 && old_cursor.par()->isLineSeparator(0))) { - // ok, we will delete anything + // ok, we will delete something LyXCursor tmpcursor; deleted = true; -- 2.39.2