]> git.lyx.org Git - lyx.git/blobdiff - src/TextMetrics.cpp
FindAdv: A try to handle backslashes in text
[lyx.git] / src / TextMetrics.cpp
index c7d9e18acbcaedf593076d9cea5c03ec82a2c02f..0f2ef90b9d7ae51d0c49507a7dbfd72096a7f4e5 100644 (file)
 
 #include "insets/InsetText.h"
 
-#include "mathed/InsetMathMacroTemplate.h"
+#include "mathed/MacroTable.h"
 
 #include "frontends/FontMetrics.h"
 #include "frontends/NullPainter.h"
 
-#include "support/convert.h"
 #include "support/debug.h"
 #include "support/lassert.h"
-#include "support/lyxlib.h"
-#include "support/RefChanger.h"
+#include "support/Changer.h"
 
 #include <stdlib.h>
 #include <cmath>
@@ -552,13 +550,36 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows)
                first = row.endpos();
                ++row_index;
 
-               pm.dim().wid = max(pm.dim().wid, row.width());
+               pm.dim().wid = max(pm.dim().wid, row.width() + row.right_margin);
                pm.dim().des += row.height();
        } while (first < par.size() || need_new_row);
 
        if (row_index < pm.rows().size())
                pm.rows().resize(row_index);
 
+       // This type of margin can only be handled at the global paragraph level
+       if (par.layout().margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+               int offset = 0;
+               if (par.isRTL(buffer.params())) {
+                       // globally align the paragraph to the left.
+                       int minleft = max_width_;
+                       for (Row const & row : pm.rows())
+                               minleft = min(minleft, row.left_margin);
+                       offset = right_margin - minleft;
+               } else {
+                       // globally align the paragraph to the right.
+                       int maxwid = 0;
+                       for (Row const & row : pm.rows())
+                               maxwid = max(maxwid, row.width());
+                       offset = max_width_ - right_margin - maxwid;
+               }
+
+               for (Row & row : pm.rows()) {
+                       row.left_margin += offset;
+                       row.dim().wid += offset;
+               }
+       }
+
        // The space above and below the paragraph.
        int const top = parTopSpacing(pit);
        pm.rows().front().dim().asc += top;
@@ -781,22 +802,6 @@ int TextMetrics::labelFill(Row const & row) const
 }
 
 
-#if 0
-// Not used, see TextMetrics::breakRow
-// this needs special handling - only newlines count as a break point
-static pos_type addressBreakPoint(pos_type i, Paragraph const & par)
-{
-       pos_type const end = par.size();
-
-       for (; i < end; ++i)
-               if (par.isNewline(i))
-                       return i + 1;
-
-       return end;
-}
-#endif
-
-
 int TextMetrics::labelEnd(pit_type const pit) const
 {
        // labelEnd is only needed if the layout fills a flushleft label.
@@ -888,14 +893,6 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
        // the width available for the row.
        int const width = max_width_ - row.right_margin;
 
-#if 0
-       //FIXME: As long as leftMargin() is not correctly implemented for
-       // MARGIN_RIGHT_ADDRESS_BOX, we should also not do this here.
-       // Otherwise, long rows will be painted off the screen.
-       if (par.layout().margintype == MARGIN_RIGHT_ADDRESS_BOX)
-               return addressBreakPoint(pos, par);
-#endif
-
        // check for possible inline completion
        DocIterator const & ic_it = bv_->inlineCompletionPos();
        pos_type ic_pos = -1;
@@ -1600,7 +1597,8 @@ void TextMetrics::deleteLineForward(Cursor & cur)
 
 int TextMetrics::leftMargin(pit_type pit) const
 {
-       return leftMargin(pit, text_->paragraphs()[pit].size());
+       // the + 1 is useful when the paragraph is empty
+       return leftMargin(pit, text_->paragraphs()[pit].size() + 1);
 }
 
 
@@ -1612,7 +1610,10 @@ int TextMetrics::leftMargin(pit_type const pit, pos_type const pos) const
        LASSERT(pit < int(pars.size()), return 0);
        Paragraph const & par = pars[pit];
        LASSERT(pos >= 0, return 0);
-       LASSERT(pos <= par.size(), return 0);
+       // We do not really care whether pos > par.size(), since we do not
+       // access the data. It can be actially useful, when querying the
+       // margin without indentation (see leftMargin(pit_type).
+
        Buffer const & buffer = bv_->buffer();
        //lyxerr << "TextMetrics::leftMargin: pit: " << pit << " pos: " << pos << endl;
        DocumentClass const & tclass = buffer.params().documentClass();
@@ -1727,25 +1728,10 @@ int TextMetrics::leftMargin(pit_type const pit, pos_type const pos) const
                }
                break;
 
-       case MARGIN_RIGHT_ADDRESS_BOX: {
-#if 0
-               // The left margin depends on the widest row in this paragraph.
-               // This code is wrong because it depends on the rows, but at the
-               // same time this function is used in redoParagraph to construct
-               // the rows.
-               ParagraphMetrics const & pm = par_metrics_[pit];
-               int minfill = max_width_;
-               for (row : pm.rows())
-                       if (row.fill() < minfill)
-                               minfill = row.fill();
-               l_margin += bfm.signedWidth(layout.leftmargin);
-               l_margin += minfill;
-#endif
-               // also wrong, but much shorter.
-               l_margin += max_width_ / 2;
+       case MARGIN_RIGHT_ADDRESS_BOX:
+               // This is handled globally in redoParagraph().
                break;
        }
-       }
 
        if (!par.params().leftIndent().zero())
                l_margin += par.params().leftIndent().inPixels(max_width_, lfm.em());
@@ -1766,8 +1752,8 @@ int TextMetrics::leftMargin(pit_type const pit, pos_type const pos) const
            && !text_->inset().neverIndent()
            // display style insets do not need indentation
            && !(!par.empty()
-                && par.isInset(pos)
-                && par.getInset(pos)->rowFlags() & Inset::Display)
+                && par.isInset(0)
+                && par.getInset(0)->rowFlags() & Inset::Display)
            && (!(tclass.isDefaultLayout(par.layout())
                || tclass.isPlainLayout(par.layout()))
                || buffer.params().paragraph_separation
@@ -1814,8 +1800,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
                return;
        size_t const nrows = pm.rows().size();
        // Remember left and right margin for drawing math numbers
-       Changer changeleft = make_change(pi.leftx, x + leftMargin(pit));
-       Changer changeright = make_change(pi.rightx, x + width() - rightMargin(pit));
+       Changer changeleft = changeVar(pi.leftx, x + leftMargin(pit));
+       Changer changeright = changeVar(pi.rightx, x + width() - rightMargin(pit));
 
        // Use fast lane in nodraw stage.
        if (pi.pain.isNull()) {
@@ -1920,16 +1906,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
                        LYXERR(Debug::PAINTING, "Clear rect@("
                               << max(row_x, 0) << ", " << y - row.ascent() << ")="
                               << width() << " x " << row.height());
-                       // FIXME: this is a hack. We clear an amount equal to
-                       // cursor width. This will not work if the caret has a
-                       // ridiculous width like 6. (see ticket #10797)
-                       // This is the same formula as in GuiWorkArea.
-                       int const caret_width = lyxrc.cursor_width
-                               ? lyxrc.cursor_width
-                               : 1 + int((lyxrc.currentZoom + 50) / 200.0);
-                       pi.pain.fillRectangle(max(row_x, 0), y - row.ascent(),
-                                             width() + caret_width,
-                                             row.height(), pi.background_color);
+                       pi.pain.fillRectangle(row_x, y - row.ascent(),
+                                             width(), row.height(), pi.background_color);
                }
 
                // Instrumentation for testing row cache (see also