See attached.

Instead of 'manually inlining' the critical parts, we pass the LyXFont
around (getting the font was the expensive part).

No change in speed.

Btw: I intend to make the fill_ and maybe even the margin data part of
the LyXRow struct, at least for a while, by e.g. calling
'prepareToPrint' (or similar) during the paragraph break.

This would enable us to consolidate the 'prepareToPrint' calls in one
place and might give some insight in the margin problems.

This costs quite some memory as the LyXRow structur might grow by 20-40
bytes, i.e. 400k for a 10000-line doc.

This could consolidated later by factoring out per paragraph data like
the margin stuff, and/or moving back to a 'just in time computation'.


This also contains a new 'LyXRow::end_' member to indicate the
one-past-end pos of the chars covered by this row. If that's
propagated/used all over the place we could replace a lot of
RowList::iterators by Row const &.

Unfortunately, there is a lot of +/- 1 "logic" in rowBreakPoint etc, so
that's less straight forward as it sounds..

Andre'


-- 
Those who desire to give up Freedom in order to gain Security, will not have,
nor do they deserve, either one.     (T. Jefferson or B. Franklin or both...)
? 1.diff
? 2.diff
? fullredraw.diff
? par-row.diff
? insets/1.diff
Index: lyxrow.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxrow.C,v
retrieving revision 1.29
diff -u -p -r1.29 lyxrow.C
--- lyxrow.C    14 Aug 2003 08:34:13 -0000      1.29
+++ lyxrow.C    22 Aug 2003 07:41:54 -0000
@@ -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;
 }
 
Index: lyxrow.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxrow.h,v
retrieving revision 1.33
diff -u -p -r1.33 lyxrow.h
--- lyxrow.h    14 Aug 2003 08:34:13 -0000      1.33
+++ lyxrow.h    22 Aug 2003 07:41:54 -0000
@@ -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_;
Index: lyxrow_funcs.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxrow_funcs.C,v
retrieving revision 1.10
diff -u -p -r1.10 lyxrow_funcs.C
--- lyxrow_funcs.C      15 Aug 2003 08:03:50 -0000      1.10
+++ lyxrow_funcs.C      22 Aug 2003 07:41:54 -0000
@@ -4,18 +4,32 @@
 #include "lyxtext.h"
 #include "paragraph.h"
 #include "lyxlayout.h"
+#include "debug.h"
+
+#include "support/LAssert.h"
 
 #include <boost/next_prior.hpp>
 #include <algorithm>
 
 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, 
        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;
Index: lyxtext.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxtext.h,v
retrieving revision 1.219
diff -u -p -r1.219 lyxtext.h
--- lyxtext.h   15 Aug 2003 14:54:17 -0000      1.219
+++ lyxtext.h   22 Aug 2003 07:41:54 -0000
@@ -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;
 
Index: rowpainter.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/rowpainter.C,v
retrieving revision 1.52
diff -u -p -r1.52 rowpainter.C
--- rowpainter.C        19 Aug 2003 16:46:46 -0000      1.52
+++ rowpainter.C        22 Aug 2003 07:41:54 -0000
@@ -152,7 +152,8 @@ int RowPainter::singleWidth(lyx::pos_typ
 
 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);
 }
 
 
Index: text.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text.C,v
retrieving revision 1.422
diff -u -p -r1.422 text.C
--- text.C      18 Aug 2003 08:35:25 -0000      1.422
+++ text.C      22 Aug 2003 07:41:54 -0000
@@ -192,17 +192,20 @@ int LyXText::singleWidth(ParagraphList::
                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(Paragrap
                        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::iterato
                                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(ParagraphLi
                                        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(ParagraphLi
                                        }
                                } else {
                                        // Fall-back to normal case
-                                       maxwidth += singleWidth(pit, pos, c);
+                                       maxwidth += singleWidth(pit, pos, c, font);
                                        // And flush font cache
                                        endPosOfFontSpan = 0;
                                }
Index: text2.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v
retrieving revision 1.439
diff -u -p -r1.439 text2.C
--- text2.C     15 Aug 2003 14:54:19 -0000      1.439
+++ text2.C     22 Aug 2003 07:41:54 -0000
@@ -550,32 +550,23 @@ void LyXText::redoParagraph(ParagraphLis
        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(L
 {
        // 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());
+       cur.y(y + rit->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 {
+       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::deleteEmptyParagraphMechan
           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::deleteEmptyParagraphMechan
        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;

Reply via email to