]> git.lyx.org Git - lyx.git/blobdiff - src/TextMetrics.cpp
Fix scale parameter for fonts.
[lyx.git] / src / TextMetrics.cpp
index e122d6a6a1d74f005b66460fb9c8a45b33922811..1b434a503c75a9951abf42542af3080c57adff28 100644 (file)
@@ -348,6 +348,7 @@ bool TextMetrics::isRTLBoundary(pit_type pit, pos_type pos,
        // FED                          FED|                     FED     )
        if (startpos == pos && endpos == pos && endpos != par.size()
                && (par.isNewline(pos - 1)
+                       || par.isEnvSeparator(pos - 1)
                        || par.isLineSeparator(pos - 1)
                        || par.isSeparator(pos - 1)))
                return false;
@@ -628,6 +629,7 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
                        if (ns
                            && row.endpos() < par.size()
                            && !par.isNewline(row.endpos() - 1)
+                           && !par.isEnvSeparator(row.endpos() - 1)
                            && !disp_inset
                                ) {
                                row.separator = w / ns;
@@ -693,13 +695,13 @@ int TextMetrics::labelFill(pit_type const pit, Row const & row) const
        Paragraph const & par = text_->getPar(pit);
 
        pos_type last = par.beginOfBody();
-       LBUFERR(last > 0);
+       LBUFERR(last > 0 || par.isEnvSeparator(0));
 
        // -1 because a label ends with a space that is in the label
        --last;
 
        // a separator at this end does not count
-       if (par.isLineSeparator(last))
+       if (last >= 0 && par.isLineSeparator(last))
                --last;
 
        int w = 0;
@@ -897,7 +899,7 @@ pos_type TextMetrics::rowBreakPoint(int width, pit_type const pit,
                        break;
                }
 
-               if (par.isNewline(i)) {
+               if (par.isNewline(i) || par.isEnvSeparator(i)) {
                        point = i + 1;
                        break;
                }
@@ -1152,11 +1154,10 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
                pit_type nextpit = pit + 1;
                if (nextpit != pit_type(pars.size())) {
                        pit_type cpit = pit;
-                       double usual = 0;
-                       double unusual = 0;
 
                        if (pars[cpit].getDepth() > pars[nextpit].getDepth()) {
-                               usual = pars[cpit].layout().bottomsep * dh;
+                               double usual = pars[cpit].layout().bottomsep * dh;
+                               double unusual = 0;
                                cpit = text_->depthHook(cpit, pars[nextpit].getDepth());
                                if (pars[cpit].layout() != pars[nextpit].layout()
                                        || pars[nextpit].getLabelWidthString() != pars[cpit].getLabelWidthString())
@@ -1270,7 +1271,7 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit,
        if (lastrow &&
            ((rtl_on_lastrow  &&  left_side && vc == row.pos() && x < tmpx - 5) ||
             (!rtl_on_lastrow && !left_side && vc == end  && x > tmpx + 5))) {
-               if (!par.isNewline(end - 1))
+               if (!(par.isNewline(end - 1) || par.isEnvSeparator(end - 1)))
                        c = end;
        } else if (vc == row.pos()) {
                c = bidi.vis2log(vc);
@@ -1319,7 +1320,9 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit,
        if (!c || end == par.size())
                return col;
 
-       if (c==end && !par.isLineSeparator(c-1) && !par.isNewline(c-1)) {
+       if (c==end && !par.isLineSeparator(c-1)
+                  && !par.isNewline(c-1)
+                  && !par.isEnvSeparator(c-1)) {
                boundary = true;
                return col;
        }
@@ -1492,37 +1495,30 @@ Inset * TextMetrics::editXY(Cursor & cur, int x, int y,
        int yy = y; // is modified by getPitAndRowNearY
        Row const & row = getPitAndRowNearY(yy, pit, assert_in_view, up);
 
-       bool bound = false; // is modified by getColumnNearX
-       int xx = x; // is modified by getColumnNearX
-       pos_type const pos = row.pos()
-               + getColumnNearX(pit, row, xx, bound);
        cur.pit() = pit;
-       cur.pos() = pos;
-       cur.boundary(bound);
-       cur.setTargetX(x);
 
-       // try to descend into nested insets
-       Inset * inset = checkInsetHit(x, yy);
-       //lyxerr << "inset " << inset << " hit at x: " << x << " y: " << y << endl;
-       if (!inset) {
+       // Do we cover an inset?
+       InsetList::InsetTable * it = checkInsetHit(pit, x, yy);
+
+       if (!it) {
+               // No inset, set position in the text
+               bool bound = false; // is modified by getColumnNearX
+               int xx = x; // is modified by getColumnNearX
+               cur.pos() = row.pos()
+                       + getColumnNearX(pit, row, xx, bound);
+               cur.boundary(bound);
                cur.setCurrentFont();
+               cur.setTargetX(xx);
                return 0;
        }
 
-       ParagraphList const & pars = text_->paragraphs();
-       Inset const * inset_before = pos ? pars[pit].getInset(pos - 1) : 0;
-
-       // This should be just before or just behind the
-       // cursor position set above.
-       LASSERT(inset == inset_before
-               || inset == pars[pit].getInset(pos), return 0);
-
-       // Make sure the cursor points to the position before
-       // this inset.
-       if (inset == inset_before) {
-               --cur.pos();
-               cur.boundary(false);
-       }
+       Inset * inset = it->inset;
+       //lyxerr << "inset " << inset << " hit at x: " << x << " y: " << y << endl;
+
+       // Set position in front of inset
+       cur.pos() = it->pos;
+       cur.boundary(false);
+       cur.setTargetX(x);
 
        // Try to descend recursively inside the inset.
        inset = inset->editXY(cur, x, yy);
@@ -1571,11 +1567,8 @@ void TextMetrics::setCursorFromCoordinates(Cursor & cur, int const x, int const
 
 
 //takes screen x,y coordinates
-Inset * TextMetrics::checkInsetHit(int x, int y)
+InsetList::InsetTable * TextMetrics::checkInsetHit(pit_type pit, int x, int y)
 {
-       pit_type pit = getPitNearY(y);
-       LASSERT(pit != -1, return 0);
-
        Paragraph const & par = text_->paragraphs()[pit];
        ParagraphMetrics const & pm = par_metrics_[pit];
 
@@ -1604,7 +1597,7 @@ Inset * TextMetrics::checkInsetHit(int x, int y)
                        && y >= p.y_ - dim.asc
                        && y <= p.y_ + dim.des) {
                        LYXERR(Debug::DEBUG, "Hit inset: " << inset);
-                       return inset;
+                       return const_cast<InsetList::InsetTable *>(&(*iit));
                }
        }
 
@@ -1613,6 +1606,20 @@ Inset * TextMetrics::checkInsetHit(int x, int y)
 }
 
 
+//takes screen x,y coordinates
+Inset * TextMetrics::checkInsetHit(int x, int y)
+{
+       pit_type const pit = getPitNearY(y);
+       LASSERT(pit != -1, return 0);
+       InsetList::InsetTable * it = checkInsetHit(pit, x, y);
+
+       if (!it)
+               return 0;
+
+       return it->inset;
+}
+
+
 int TextMetrics::cursorX(CursorSlice const & sl,
                bool boundary) const
 {
@@ -1811,7 +1818,8 @@ bool TextMetrics::cursorEnd(Cursor & cur)
        bool boundary = false;
        if (end != cur.lastpos()) {
                if (!cur.paragraph().isLineSeparator(end-1)
-                   && !cur.paragraph().isNewline(end-1))
+                   && !cur.paragraph().isNewline(end-1)
+                   && !cur.paragraph().isEnvSeparator(end-1))
                        boundary = true;
                else
                        --end;
@@ -1892,6 +1900,15 @@ int TextMetrics::leftMargin(int max_width,
                if (newpar != pit_type(pars.size())) {
                        if (pars[newpar].layout().isEnvironment()) {
                                l_margin = leftMargin(max_width, newpar);
+                               // Remove the parindent that has been added
+                               // if the paragraph was empty.
+                               if (pars[newpar].empty() &&
+                                   buffer.params().paragraph_separation ==
+                                   BufferParams::ParagraphIndentSeparation) {
+                                       docstring pi = pars[newpar].layout().parindent;
+                                       l_margin -= theFontMetrics(
+                                               buffer.params().getFont()).signedWidth(pi);
+                               }
                        }
                        if (tclass.isDefaultLayout(par.layout())
                            || tclass.isPlainLayout(par.layout())) {
@@ -1903,12 +1920,20 @@ int TextMetrics::leftMargin(int max_width,
                }
        }
 
-       // This happens after sections in standard classes. The 1.3.x
-       // code compared depths too, but it does not seem necessary
-       // (JMarc)
-       if (tclass.isDefaultLayout(par.layout())
-           && pit > 0 && pars[pit - 1].layout().nextnoindent)
+       // This happens after sections or environments in standard classes.
+       // We have to check the previous layout at same depth.
+       if (buffer.params().paragraph_separation ==
+                       BufferParams::ParagraphSkipSeparation)
                parindent.erase();
+       else if (pit > 0 && pars[pit - 1].getDepth() >= par.getDepth()) {
+               pit_type prev = text_->depthHook(pit, par.getDepth());
+               if (par.layout() == pars[prev].layout()) {
+                       if (prev != pit - 1
+                           && pars[pit - 1].layout().nextnoindent)
+                               parindent.erase();
+               } else if (pars[prev].layout().nextnoindent)
+                       parindent.erase();
+       }
 
        FontInfo const labelfont = text_->labelFont(par);
        FontMetrics const & labelfont_metrics = theFontMetrics(labelfont);