On Sun, Oct 02, 2005 at 01:26:06PM +0200, Andre' Poenitz wrote:
> So we should try hard to pass through the critical path just once.  I'll
> send later today a preliminary patch that folds rowBreakPoint() and
> setRowWidth(), i.e. reduces this by a factor of two and gives an overall
> gain of 8-12% when typing into a single long paragraph of about 1200
> chars. I won't be able to take care of this patch after I send it to the
> list, so I wouldn't mind if somebody took over.

Promised patch attached.

Andre'
--- text.C.orig 2005-09-27 23:30:41.000000000 +0200
+++ text.C      2005-09-27 23:39:38.000000000 +0200
@@ -654,28 +654,32 @@
 };
 
 
-void LyXText::rowBreakPoint(pit_type const pit, Row & row) const
+int LyXText::rowBreakPoint(pit_type const pit, Row & row) const
 {
        Paragraph const & par = pars_[pit];
        pos_type const end = par.size();
        pos_type const pos = row.pos();
        if (pos == end) {
                row.endpos(end);
-               return;
+               return 0;
        }
 
        // maximum pixel width of a row
        int width = maxwidth_ - rightMargin(par); // - leftMargin(pit, row);
        if (width < 0) {
                row.endpos(end);
-               return;
+               return 0;
        }
 
        LyXLayout_ptr const & layout = par.layout();
 
        if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
                row.endpos(addressBreakPoint(pos, par));
-               return;
+               // FIXME: Correct?
+               int v = 0;
+               for (int i = pos; i < row.endpos(); ++i)
+                       v += singleWidth(par, i);
+               return v;
        }
 
        pos_type const body_pos = par.beginOfBody();
@@ -687,6 +691,8 @@
 
        int const left = leftMargin(pit, pos);
        int x = left;
+       int w = left;
+       int v = w;
 
        // pixel width since last breakpoint
        int chunkwidth = 0;
@@ -703,12 +709,14 @@
                        int add = font_metrics::width(layout->labelsep, 
getLabelFont(par));
                        if (par.isLineSeparator(i - 1))
                                add -= singleWidth(par, i - 1);
-
+                       w += add;
+                       w = max(w, labelEnd(pit));
                        add = std::max(add, labelEnd(pit) - x);
                        thiswidth += add;
                }
 
                x += thiswidth;
+               w += thiswidth;
                chunkwidth += thiswidth;
 
                // break before a character that will fall off
@@ -716,11 +724,14 @@
                if (x >= width) {
                        // if no break before, break here
                        if (point == end || chunkwidth >= width - left) {
-                               if (i > pos)
+                               if (i > pos) {
                                        point = i;
-                               else
+                                       v = w - thiswidth;
+                               }
+                               else {
                                        point = i + 1;
-
+                                       v = w;
+                               }
                        }
                        // exit on last registered breakpoint:
                        break;
@@ -728,17 +739,20 @@
 
                if (par.isNewline(i)) {
                        point = i + 1;
+                       v = w;
                        break;
                }
                // Break before...
                if (i + 1 < end) {
                        if (par.isInset(i + 1) && par.getInset(i + 
1)->display()) {
                                point = i + 1;
+                               v = w;
                                break;
                        }
                        // ...and after.
                        if (par.isInset(i) && par.getInset(i)->display()) {
                                point = i + 1;
+                               v = w;
                                break;
                        }
                }
@@ -748,58 +762,43 @@
                        if (par.isLineSeparator(i)) {
                                // register breakpoint:
                                point = i + 1;
+                               v = w;
+                               lyxerr << "case 6" << endl;
                                chunkwidth = 0;
                        }
                }
        }
 
        // maybe found one, but the par is short enough.
-       if (i == end && x < width)
+       if (i == end && x < width) {
                point = end;
+               v = x;
+       }
 
        // manual labels cannot be broken in LaTeX. But we
        // want to make our on-screen rendering of footnotes
        // etc. still break
-       if (body_pos && point < body_pos)
+       if (body_pos && point < body_pos)  {
+               lyxerr << "case 8" << endl;
                point = body_pos;
-
-       row.endpos(point);
-}
-
-
-void LyXText::setRowWidth(pit_type const pit, Row & row) const
-{
-       // get the pure distance
-       pos_type const end = row.endpos();
-
-       Paragraph const & par = pars_[pit];
-       string const & labelsep = par.layout()->labelsep;
-       int w = leftMargin(pit, row.pos());
-
-       pos_type const body_pos = par.beginOfBody();
-       pos_type i = row.pos();
-
-       if (i < end) {
-               FontIterator fi = FontIterator(*this, par, i);
-               for ( ; i < end; ++i, ++fi) {
-                       if (body_pos > 0 && i == body_pos) {
-                               w += font_metrics::width(labelsep, 
getLabelFont(par));
-                               if (par.isLineSeparator(i - 1))
-                                       w -= singleWidth(par, i - 1);
-                               w = max(w, labelEnd(pit));
-                       }
-                       char const c = par.getChar(i);
-                       w += singleWidth(par, i, c, *fi);
-               }
        }
 
+#if 0
        if (body_pos > 0 && body_pos >= end) {
-               w += font_metrics::width(labelsep, getLabelFont(par));
+               w += font_metrics::width(layout->labelsep, getLabelFont(par));
                if (end > 0 && par.isLineSeparator(end - 1))
                        w -= singleWidth(par, end - 1);
                w = max(w, labelEnd(pit));
        }
+#endif
+       row.endpos(point);
+       return v;
+}
 
+
+void LyXText::setRowWidth(pit_type const pit, Row & row, int w) const
+{
+       Paragraph const & par = pars_[pit];
        row.width(w + rightMargin(par));
 }
 
@@ -1705,8 +1704,8 @@
        pos_type z = 0;
        do {
                Row row(z);
-               rowBreakPoint(pit, row);
-               setRowWidth(pit, row);
+               int const w = rowBreakPoint(pit, row);
+               setRowWidth(pit, row, w);
                setHeightOfRow(pit, row);
                par.rows().push_back(row);
                dim.wid = std::max(dim.wid, row.width());
--- lyxtext.h.orig      2005-09-27 23:30:56.000000000 +0200
+++ lyxtext.h   2005-09-27 23:39:59.000000000 +0200
@@ -384,9 +384,9 @@
 
        /// sets row.end to the pos value *after* which a row should break.
        /// for example, the pos after which isNewLine(pos) == true
-       void rowBreakPoint(pit_type pit, Row & row) const;
+       int rowBreakPoint(pit_type pit, Row & row) const;
        /// sets row.width to the minimum space a row needs on the screen in 
pixel
-       void setRowWidth(pit_type pit, Row & row) const;
+       void setRowWidth(pit_type pit, Row & row, int w) const;
        /// the minimum space a manual label needs on the screen in pixels
        int labelFill(Paragraph const & par, Row const & row) const;
        /// FIXME

Reply via email to