]> git.lyx.org Git - lyx.git/blobdiff - src/TextMetrics.cpp
* InsetTabular.cpp:
[lyx.git] / src / TextMetrics.cpp
index cd8fbeb2edde48bc4d54687168dfc444ccaa20d9..fd576c31b2a254a460999dddede9be56606a9b37 100644 (file)
@@ -27,7 +27,6 @@
 #include "CoordCache.h"
 #include "Cursor.h"
 #include "CutAndPaste.h"
-#include "FuncRequest.h"
 #include "HSpace.h"
 #include "InsetList.h"
 #include "Layout.h"
@@ -134,8 +133,6 @@ TextMetrics::TextMetrics(BufferView * bv, Text * text)
        dim_.wid = max_width_;
        dim_.asc = 10;
        dim_.des = 10;
-
-       //text_->updateLabels(bv->buffer());
 }
 
 
@@ -179,17 +176,6 @@ ParagraphMetrics & TextMetrics::parMetrics(pit_type pit, bool redo)
 }
 
 
-int TextMetrics::parPosition(pit_type pit) const
-{
-       if (pit < par_metrics_.begin()->first)
-               return -1000000;
-       if (pit > par_metrics_.rbegin()->first)
-               return +1000000;
-
-       return par_metrics_[pit].position();
-}
-
-
 bool TextMetrics::metrics(MetricsInfo & mi, Dimension & dim, int min_width)
 {
        LASSERT(mi.base.textwidth > 0, /**/);
@@ -244,11 +230,9 @@ int TextMetrics::rightMargin(pit_type const pit) const
 
 void TextMetrics::applyOuterFont(Font & font) const
 {
-       Font lf(font_);
-       lf.fontInfo().reduce(bv_->buffer().params().getFont().fontInfo());
-       Font tmp(font); 
-       tmp.fontInfo().realize(lf.fontInfo()); 
-       font = tmp;
+       FontInfo lf(font_.fontInfo());
+       lf.reduce(bv_->buffer().params().getFont().fontInfo());
+       font.fontInfo().realize(lf); 
 }
 
 
@@ -319,11 +303,8 @@ bool TextMetrics::isRTL(CursorSlice const & sl, bool boundary) const
 
 bool TextMetrics::isRTLBoundary(pit_type pit, pos_type pos) const
 {
-       if (!lyxrc.rtl_support)
-               return false;
-
        // no RTL boundary at paragraph start
-       if (pos == 0)
+       if (!lyxrc.rtl_support || pos == 0)
                return false;
 
        Font const & left_font = displayFont(pit, pos - 1);
@@ -332,16 +313,20 @@ bool TextMetrics::isRTLBoundary(pit_type pit, pos_type pos) const
 }
 
 
+// isRTLBoundary returns false on a real end-of-line boundary,
+// because otherwise the two boundary types get mixed up.
+// This is the whole purpose of this being in TextMetrics.
 bool TextMetrics::isRTLBoundary(pit_type pit, pos_type pos,
                Font const & font) const
 {
-       if (!lyxrc.rtl_support)
+       if (!lyxrc.rtl_support
+           // no RTL boundary at paragraph start
+           || pos == 0
+           // if the metrics have not been calculated, then we are not
+           // on screen and can safely ignore issues about boundaries.
+           || !contains(pit))
                return false;
 
-       // no RTL boundary at paragraph start
-       if (pos == 0)
-               return false;
-       
        ParagraphMetrics & pm = par_metrics_[pit];
        // no RTL boundary in empty paragraph
        if (pm.rows().empty())
@@ -356,13 +341,6 @@ bool TextMetrics::isRTLBoundary(pit_type pit, pos_type pos,
                return false;
 
        Paragraph const & par = text_->getPar(pit);
-       bool left = font.isVisibleRightToLeft();
-       bool right;
-       if (pos == par.size())
-               right = par.isRTL(bv_->buffer().params());
-       else
-               right = displayFont(pit, pos).isVisibleRightToLeft();
-       
        // no RTL boundary at line break:
        // abc|\n    -> move right ->   abc\n       (and not:    abc\n|
        // FED                          FED|                     FED     )
@@ -372,6 +350,13 @@ bool TextMetrics::isRTLBoundary(pit_type pit, pos_type pos,
                        || par.isSeparator(pos - 1)))
                return false;
        
+       bool left = font.isVisibleRightToLeft();
+       bool right;
+       if (pos == par.size())
+               right = par.isRTL(bv_->buffer().params());
+       else
+               right = displayFont(pit, pos).isVisibleRightToLeft();
+       
        return left != right;
 }
 
@@ -379,7 +364,7 @@ bool TextMetrics::isRTLBoundary(pit_type pit, pos_type pos,
 bool TextMetrics::redoParagraph(pit_type const pit)
 {
        Paragraph & par = text_->getPar(pit);
-       // IMPORTANT NOTE: We pass 'false' explicitely in order to not call
+       // IMPORTANT NOTE: We pass 'false' explicitly in order to not call
        // redoParagraph() recursively inside parMetrics.
        Dimension old_dim = parMetrics(pit, false).dim();
        ParagraphMetrics & pm = par_metrics_[pit];
@@ -389,21 +374,6 @@ bool TextMetrics::redoParagraph(pit_type const pit)
        main_text_ = (text_ == &buffer.text());
        bool changed = false;
 
-       // FIXME: This check ought to be done somewhere else. It is the reason
-       // why text_ is not     const. But then, where else to do it?
-       // Well, how can you end up with either (a) a biblio environment that
-       // has no InsetBibitem or (b) a biblio environment with more than one
-       // InsetBibitem? I think the answer is: when paragraphs are merged;
-       // when layout is set; when material is pasted.
-       int const moveCursor = par.checkBiblio(buffer);
-       if (moveCursor > 0)
-               const_cast<Cursor &>(bv_->cursor()).posForward();
-       else if (moveCursor < 0) {
-               Cursor & cursor = const_cast<Cursor &>(bv_->cursor());
-               if (cursor.pos() >= -moveCursor)
-                       cursor.posBackward();
-       }
-
        // Optimisation: this is used in the next two loops
        // so better to calculate that once here.
        int const right_margin = rightMargin(pm);
@@ -416,7 +386,10 @@ bool TextMetrics::redoParagraph(pit_type const pit)
                LYXERR(Debug::INFO, "MacroContext not initialised!"
                        << " Going through the buffer again and hope"
                        << " the context is better then.");
-               bv_->buffer().updateLabels();
+               // FIXME audit updateBuffer calls
+               // This should not be here, but it is not clear yet where else it
+               // should be.
+               bv_->buffer().updateBuffer();
                parPos = text_->macrocontextPosition();
                LASSERT(!parPos.empty(), /**/);
                parPos.pit() = pit;
@@ -1234,10 +1207,18 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit,
                return 0;
        }
 
-       // if the first character is a separator, we are in RTL
-       // text. This character will not be painted on screen
+       // This (rtl_support test) is not needed, but gives
+       // some speedup if rtl_support == false
+       bool const lastrow = lyxrc.rtl_support && row.endpos() == par.size();
+
+       // If lastrow is false, we don't need to compute
+       // the value of rtl.
+       bool const rtl = lastrow ? text_->isRTL(par) : false;
+
+       // if the first character is a separator, and we are in RTL
+       // text, this character will not be painted on screen
        // and thus we should not count it and skip to the next.
-       if (par.isSeparator(bidi.vis2log(vc)))
+       if (rtl && par.isSeparator(bidi.vis2log(vc)))
                ++vc;
 
        while (vc < end && tmpx <= x) {
@@ -1265,13 +1246,7 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit,
        LASSERT(vc <= end, /**/);  // This shouldn't happen.
 
        boundary = false;
-       // This (rtl_support test) is not needed, but gives
-       // some speedup if rtl_support == false
-       bool const lastrow = lyxrc.rtl_support && row.endpos() == par.size();
 
-       // If lastrow is false, we don't need to compute
-       // the value of rtl.
-       bool const rtl = lastrow ? text_->isRTL(par) : false;
        if (lastrow &&
            ((rtl  &&  left_side && vc == row.pos() && x < tmpx - 5) ||
             (!rtl && !left_side && vc == end  && x > tmpx + 5))) {
@@ -2017,7 +1992,7 @@ int TextMetrics::leftMargin(int max_width,
               || (layout.labeltype == LABEL_STATIC
                   && layout.latextype == LATEX_ENVIRONMENT
                   && !text_->isFirstInSequence(pit)))
-           && align == LYX_ALIGN_BLOCK
+           && (align == LYX_ALIGN_BLOCK || align == LYX_ALIGN_LEFT)
            && !par.params().noindent()
            // in some insets, paragraphs are never indented
            && !text_->inset().neverIndent()
@@ -2027,14 +2002,15 @@ int TextMetrics::leftMargin(int max_width,
                    && par.getInset(pos)->display())
                        && (!(tclass.isDefaultLayout(par.layout())
                 || tclass.isPlainLayout(par.layout()))
-               || buffer.params().paragraph_separation == BufferParams::ParagraphIndentSeparation)
+               || buffer.params().paragraph_separation 
+                               == BufferParams::ParagraphIndentSeparation)
            )
                {
-                       // use the parindent of the layout when the default indentation is used
-                       // otherwise use the indentation set in the document settings
+                       // use the parindent of the layout when the default indentation is
+                       // used otherwise use the indentation set in the document settings
                        if (buffer.params().getIndentation().asLyXCommand() == "default")
-                               l_margin += theFontMetrics(buffer.params().getFont()).signedWidth(
-                               parindent);
+                               l_margin += theFontMetrics(
+                                       buffer.params().getFont()).signedWidth(parindent);
                        else
                                l_margin += buffer.params().getIndentation().inPixels(*bv_);
                }
@@ -2093,7 +2069,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co
                // This is our text.
                && cur.text() == text_
                // if the anchor is outside, this is not our selection
-               && cur.anchor().text() == text_
+               && cur.normalAnchor().text() == text_
                && pit >= sel_beg.pit() && pit <= sel_end.pit();
 
        // We store the begin and end pos of the selection relative to this par
@@ -2144,15 +2120,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co
 
                // Take this opportunity to spellcheck the row contents.
                if (row_has_changed && lyxrc.spellcheck_continuously) {
-                       WordLangTuple wl;
-                       // dummy variable, not used.
-                       static docstring_list suggestions;
-                       pos_type from = row.pos();
-                       pos_type to = row.endpos();
-                       while (from < row.endpos()) {
-                               text_->getPar(pit).spellCheck(from, to, wl, suggestions, false);
-                               from = to + 1;
-                       }
+                       text_->getPar(pit).spellCheck();
                }
 
                // Don't paint the row if a full repaint has not been requested
@@ -2172,9 +2140,6 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co
                                width(), row.height(), pi.background_color);
                }
                
-               if (row.selection())
-                       drawRowSelection(pi, x, row, cur, pit);
-
                // Instrumentation for testing row cache (see also
                // 12 lines lower):
                if (lyxerr.debugging(Debug::PAINTING) && inside
@@ -2191,6 +2156,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co
                // for inner insets as the Row has been cleared out.
                bool tmp = pi.full_repaint;
                pi.full_repaint = true;
+
+               rp.paintSelection();
                rp.paintAppendix();
                rp.paintDepthBar();
                rp.paintChangeBar();
@@ -2205,6 +2172,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co
                if (i == 0 && is_rtl)
                        rp.paintFirst();
                y += row.descent();
+
                // Restore full_repaint status.
                pi.full_repaint = tmp;
        }
@@ -2215,102 +2183,6 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co
 }
 
 
-void TextMetrics::drawRowSelection(PainterInfo & pi, int x, Row const & row,
-               Cursor const & curs, pit_type pit) const
-{
-       DocIterator beg = curs.selectionBegin();
-       beg.pit() = pit;
-       beg.pos() = row.sel_beg;
-
-       DocIterator end = curs.selectionEnd();
-       end.pit() = pit;
-       end.pos() = row.sel_end;
-
-       bool const begin_boundary = beg.pos() >= row.endpos();
-       bool const end_boundary = row.sel_end == row.endpos();
-
-       DocIterator cur = beg;
-       cur.boundary(begin_boundary);
-       int x1 = cursorX(beg.top(), begin_boundary);
-       int x2 = cursorX(end.top(), end_boundary);
-       int const y1 = bv_->getPos(cur, cur.boundary()).y_ - row.ascent();
-       int const y2 = y1 + row.height();
-
-       int const rm = text_->isMainText() ? bv_->rightMargin() : 0;
-       int const lm = text_->isMainText() ? bv_->leftMargin() : 0;
-
-       // draw the margins
-       if (row.begin_margin_sel) {
-               if (text_->isRTL(beg.paragraph())) {
-                       pi.pain.fillRectangle(x + x1, y1,  width() - rm - x1, y2 - y1,
-                               Color_selection);
-               } else {
-                       pi.pain.fillRectangle(x + lm, y1, x1 - lm, y2 - y1,
-                               Color_selection);
-               }
-       }
-
-       if (row.end_margin_sel) {
-               if (text_->isRTL(beg.paragraph())) {
-                       pi.pain.fillRectangle(x + lm, y1, x2 - lm, y2 - y1,
-                               Color_selection);
-               } else {
-                       pi.pain.fillRectangle(x + x2, y1, width() - rm - x2, y2 - y1,
-                               Color_selection);
-               }
-       }
-
-       // if we are on a boundary from the beginning, it's probably
-       // a RTL boundary and we jump to the other side directly as this
-       // segement is 0-size and confuses the logic below
-       if (cur.boundary())
-               cur.boundary(false);
-
-       // go through row and draw from RTL boundary to RTL boundary
-       while (cur < end) {
-               bool drawNow = false;
-
-               // simplified cursorForward code below which does not
-               // descend into insets and which does not go into the
-               // next line. Compare the logic with the original cursorForward
-
-               // if left of boundary -> just jump to right side, but
-               // for RTL boundaries don't, because: abc|DDEEFFghi -> abcDDEEF|Fghi
-               if (cur.boundary()) {
-                       cur.boundary(false);
-               }       else if (isRTLBoundary(cur.pit(), cur.pos() + 1)) {
-                       // in front of RTL boundary -> Stay on this side of the boundary
-                       // because:  ab|cDDEEFFghi -> abc|DDEEFFghi
-                       ++cur.pos();
-                       cur.boundary(true);
-                       drawNow = true;
-               } else {
-                       // move right
-                       ++cur.pos();
-
-                       // line end?
-                       if (cur.pos() == row.endpos())
-                               cur.boundary(true);
-               }
-
-               if (x1 == -1) {
-                       // the previous segment was just drawn, now the next starts
-                       x1 = cursorX(cur.top(), cur.boundary());
-               }
-
-               if (!(cur < end) || drawNow) {
-                       x2 = cursorX(cur.top(), cur.boundary());
-                       pi.pain.fillRectangle(x + min(x1,x2), y1, abs(x2 - x1), y2 - y1,
-                               Color_selection);
-
-                       // reset x1, so it is set again next round (which will be on the
-                       // right side of a boundary or at the selection end)
-                       x1 = -1;
-               }
-       }
-}
-
-
 void TextMetrics::completionPosAndDim(Cursor const & cur, int & x, int & y,
        Dimension & dim) const
 {
@@ -2322,8 +2194,10 @@ void TextMetrics::completionPosAndDim(Cursor const & cur, int & x, int & y,
        wordStart.pos() -= word.length();
 
        // get position on screen of the word start and end
-       Point lxy = cur.bv().getPos(wordStart, false);
-       Point rxy = cur.bv().getPos(bvcur, bvcur.boundary());
+       //FIXME: Is it necessary to explicitly set this to false?
+       wordStart.boundary(false);
+       Point lxy = cur.bv().getPos(wordStart);
+       Point rxy = cur.bv().getPos(bvcur);
 
        // calculate dimensions of the word
        dim = rowHeight(bvcur.pit(), wordStart.pos(), bvcur.pos(), false);