]> git.lyx.org Git - lyx.git/blobdiff - src/TextMetrics.cpp
Change the interface to a paragraph's layout. We still store a LayoutPtr, but now...
[lyx.git] / src / TextMetrics.cpp
index 078b5907d4690fddcf7235bf6d084341e3dfa278..385c023a86dba0d7c9fc23e7899051b6d20612c8 100644 (file)
@@ -32,7 +32,6 @@
 #include "InsetList.h"
 #include "Layout.h"
 #include "Length.h"
-#include "LyXFunc.h"
 #include "LyXRC.h"
 #include "MetricsInfo.h"
 #include "paragraph_funcs.h"
@@ -248,7 +247,7 @@ Font TextMetrics::displayFont(pit_type pit, pos_type pos) const
 
        ParagraphList const & pars = text_->paragraphs();
        Paragraph const & par = pars[pit];
-       LayoutPtr const & layout = par.layout();
+       Layout const & layout = par.layout();
        Buffer const & buffer = bv_->buffer();
        // FIXME: broken?
        BufferParams const & params = buffer.params();
@@ -259,10 +258,10 @@ Font TextMetrics::displayFont(pit_type pit, pos_type pos) const
                Font f = par.getFontSettings(params, pos);
                if (!text_->isMainText(buffer))
                        applyOuterFont(f);
-               bool lab = layout->labeltype == LABEL_MANUAL && pos < body_pos;
+               bool lab = layout.labeltype == LABEL_MANUAL && pos < body_pos;
 
-               FontInfo const & lf = lab ? layout->labelfont : layout->font;
-               FontInfo rlf = lab ? layout->reslabelfont : layout->resfont;
+               FontInfo const & lf = lab ? layout.labelfont : layout.font;
+               FontInfo rlf = lab ? layout.reslabelfont : layout.resfont;
                
                // In case the default family has been customized
                if (lf.family() == INHERIT_FAMILY)
@@ -273,7 +272,7 @@ Font TextMetrics::displayFont(pit_type pit, pos_type pos) const
 
        // The uncommon case need not be optimized as much
        FontInfo const & layoutfont = pos < body_pos ? 
-               layout->labelfont : layout->font;
+               layout.labelfont : layout.font;
 
        Font font = par.getFontSettings(params, pos);
        font.fontInfo().realize(layoutfont);
@@ -509,10 +508,10 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
                row.x = leftMargin(max_width_, pit, row.pos());
 
        // is there a manual margin with a manual label
-       LayoutPtr const & layout = par.layout();
+       Layout const & layout = par.layout();
 
-       if (layout->margintype == MARGIN_MANUAL
-           && layout->labeltype == LABEL_MANUAL) {
+       if (layout.margintype == MARGIN_MANUAL
+           && layout.labeltype == LABEL_MANUAL) {
                /// We might have real hfills in the label part
                int nlh = numberOfLabelHfills(par, row);
 
@@ -541,7 +540,7 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
                // set x how you need it
                int align;
                if (par.params().align() == LYX_ALIGN_LAYOUT)
-                       align = layout->align;
+                       align = layout.align;
                else
                        align = par.params().align();
 
@@ -603,7 +602,7 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
                    && (body_pos > end || !par.isLineSeparator(body_pos - 1)))
                {
                        row.x += theFontMetrics(text_->labelFont(buffer, par)).
-                               width(layout->labelsep);
+                               width(layout.labelsep);
                        if (body_pos <= end)
                                row.x += row.label_hfill;
                }
@@ -681,7 +680,7 @@ static pos_type addressBreakPoint(pos_type i, Paragraph const & par)
 int TextMetrics::labelEnd(pit_type const pit) const
 {
        // labelEnd is only needed if the layout fills a flushleft label.
-       if (text_->getPar(pit).layout()->margintype != MARGIN_MANUAL)
+       if (text_->getPar(pit).layout().margintype != MARGIN_MANUAL)
                return 0;
        // return the beginning of the body
        return leftMargin(max_width_, pit);
@@ -698,9 +697,9 @@ pit_type TextMetrics::rowBreakPoint(int width, pit_type const pit,
        if (pos == end || width < 0)
                return end;
 
-       LayoutPtr const & layout = par.layout();
+       Layout const & layout = par.layout();
 
-       if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX)
+       if (layout.margintype == MARGIN_RIGHT_ADDRESS_BOX)
                return addressBreakPoint(pos, par);
 
        pos_type const body_pos = par.beginOfBody();
@@ -743,7 +742,7 @@ pit_type TextMetrics::rowBreakPoint(int width, pit_type const pit,
                if (body_pos && i == body_pos) {
                        FontMetrics const & fm = theFontMetrics(
                                text_->labelFont(buffer, par));
-                       int add = fm.width(layout->labelsep);
+                       int add = fm.width(layout.labelsep);
                        if (par.isLineSeparator(i - 1))
                                add -= singleWidth(pit, i - 1);
 
@@ -840,7 +839,7 @@ int TextMetrics::rowWidth(int right_margin, pit_type const pit,
                        if (body_pos > 0 && i == body_pos) {
                                FontMetrics const & fm = theFontMetrics(
                                        text_->labelFont(buffer, par));
-                               w += fm.width(par.layout()->labelsep);
+                               w += fm.width(par.layout().labelsep);
                                if (par.isLineSeparator(i - 1))
                                        w -= singleWidth(pit, i - 1);
                                w = max(w, label_end);
@@ -859,7 +858,7 @@ int TextMetrics::rowWidth(int right_margin, pit_type const pit,
        if (body_pos > 0 && body_pos >= end) {
                FontMetrics const & fm = theFontMetrics(
                        text_->labelFont(buffer, par));
-               w += fm.width(par.layout()->labelsep);
+               w += fm.width(par.layout().labelsep);
                if (end > 0 && par.isLineSeparator(end - 1))
                        w -= singleWidth(pit, end - 1);
                w = max(w, label_end);
@@ -881,7 +880,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
        // ok, let us initialize the maxasc and maxdesc value.
        // Only the fontsize count. The other properties
        // are taken from the layoutfont. Nicer on the screen :)
-       LayoutPtr const & layout = par.layout();
+       Layout const & layout = par.layout();
 
        // as max get the first character of this row then it can
        // increase but not decrease the height. Just some point to
@@ -900,7 +899,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
        FontMetrics const & fontmetrics = theFontMetrics(font);
 
        // these are minimum values
-       double const spacing_val = layout->spacing.getValue()
+       double const spacing_val = layout.spacing.getValue()
                * text_->spacing(buffer, par);
        //lyxerr << "spacing_val = " << spacing_val << endl;
        int maxasc  = int(fontmetrics.maxAscent()  * spacing_val);
@@ -949,8 +948,8 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
                        && par.ownerCode() != ERT_CODE
                        && par.ownerCode() != LISTINGS_CODE
                        && pit > 0
-                       && ((layout->isParagraph() && par.getDepth() == 0)
-                           || (pars[pit - 1].layout()->isParagraph()
+                       && ((layout.isParagraph() && par.getDepth() == 0)
+                           || (pars[pit - 1].layout().isParagraph()
                                && pars[pit - 1].getDepth() == 0)))
                {
                                maxasc += bufparams.getDefSkip().inPixels(*bv_);
@@ -961,25 +960,25 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
 
                // This is special code for the chapter, since the label of this
                // layout is printed in an extra row
-               if (layout->counter == "chapter"
+               if (layout.counter == "chapter"
                    && !par.params().labelString().empty()) {
                        labeladdon = int(labelfont_metrics.maxHeight()
-                                    * layout->spacing.getValue()
+                                    * layout.spacing.getValue()
                                     * text_->spacing(buffer, par));
                }
 
                // special code for the top label
-               if ((layout->labeltype == LABEL_TOP_ENVIRONMENT
-                    || layout->labeltype == LABEL_BIBLIO
-                    || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT)
+               if ((layout.labeltype == LABEL_TOP_ENVIRONMENT
+                    || layout.labeltype == LABEL_BIBLIO
+                    || layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT)
                    && isFirstInSequence(pit, pars)
                    && !par.labelString().empty())
                {
                        labeladdon = int(
                                  labelfont_metrics.maxHeight()
-                                       * layout->spacing.getValue()
+                                       * layout.spacing.getValue()
                                        * text_->spacing(buffer, par)
-                               + (layout->topsep + layout->labelbottomsep) * dh);
+                               + (layout.topsep + layout.labelbottomsep) * dh);
                }
 
                // Add the layout spaces, for example before and after
@@ -993,20 +992,20 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
                    && prevpar.getDepth() == par.getDepth()
                    && prevpar.getLabelWidthString()
                                        == par.getLabelWidthString()) {
-                       layoutasc = layout->itemsep * dh;
+                       layoutasc = layout.itemsep * dh;
                } else if (pit != 0 || first != 0) {
-                       if (layout->topsep > 0)
-                               layoutasc = layout->topsep * dh;
+                       if (layout.topsep > 0)
+                               layoutasc = layout.topsep * dh;
                }
 
                prev = outerHook(pit, pars);
                if (prev != pit_type(pars.size())) {
-                       maxasc += int(pars[prev].layout()->parsep * dh);
+                       maxasc += int(pars[prev].layout().parsep * dh);
                } else if (pit != 0) {
                        Paragraph const & prevpar = pars[pit - 1];
                        if (prevpar.getDepth() != 0 ||
                                        prevpar.layout() == layout) {
-                               maxasc += int(layout->parsep * dh);
+                               maxasc += int(layout.parsep * dh);
                        }
                }
        }
@@ -1023,18 +1022,18 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
                        double unusual = 0;
 
                        if (pars[cpit].getDepth() > pars[nextpit].getDepth()) {
-                               usual = pars[cpit].layout()->bottomsep * dh;
+                               usual = pars[cpit].layout().bottomsep * dh;
                                cpit = depthHook(cpit, pars, pars[nextpit].getDepth());
                                if (pars[cpit].layout() != pars[nextpit].layout()
                                        || pars[nextpit].getLabelWidthString() != pars[cpit].getLabelWidthString())
                                {
-                                       unusual = pars[cpit].layout()->bottomsep * dh;
+                                       unusual = pars[cpit].layout().bottomsep * dh;
                                }
                                layoutdesc = max(unusual, usual);
                        } else if (pars[cpit].getDepth() == pars[nextpit].getDepth()) {
                                if (pars[cpit].layout() != pars[nextpit].layout()
                                        || pars[nextpit].getLabelWidthString() != pars[cpit].getLabelWidthString())
-                                       layoutdesc = int(pars[cpit].layout()->bottomsep * dh);
+                                       layoutdesc = int(pars[cpit].layout().bottomsep * dh);
                        }
                }
        }
@@ -1080,7 +1079,7 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit,
        pos_type vc = row.pos();
        pos_type end = row.endpos();
        pos_type c = 0;
-       LayoutPtr const & layout = par.layout();
+       Layout const & layout = par.layout();
 
        bool left_side = false;
 
@@ -1105,7 +1104,7 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit,
                if (body_pos > 0 && c == body_pos - 1) {
                        FontMetrics const & fm = theFontMetrics(
                                text_->labelFont(buffer, par));
-                       tmpx += row.label_hfill + fm.width(layout->labelsep);
+                       tmpx += row.label_hfill + fm.width(layout.labelsep);
                        if (par.isLineSeparator(body_pos - 1))
                                tmpx -= singleWidth(pit, body_pos - 1);
                }
@@ -1539,7 +1538,7 @@ int TextMetrics::cursorX(CursorSlice const & sl,
                if (body_pos > 0 && pos == body_pos - 1) {
                        FontMetrics const & labelfm = theFontMetrics(
                                text_->labelFont(buffer, par));
-                       x += row.label_hfill + labelfm.width(par.layout()->labelsep);
+                       x += row.label_hfill + labelfm.width(par.layout().labelsep);
                        if (par.isLineSeparator(body_pos - 1))
                                x -= singleWidth(pit, body_pos - 1);
                }
@@ -1611,73 +1610,6 @@ int TextMetrics::cursorY(CursorSlice const & sl, bool boundary) const
 }
 
 
-void TextMetrics::cursorPrevious(Cursor & cur)
-{
-       if (bv_->isTopScreen()) {
-               lyx::dispatch(FuncRequest(cur.selection()
-                       ? LFUN_BUFFER_BEGIN_SELECT : LFUN_BUFFER_BEGIN));
-               cur.finishUndo();
-               cur.updateFlags(Update::None);
-               return;
-       }
-
-       pos_type cpos = cur.pos();
-       pit_type cpar = cur.pit();
-
-       // Memorize current position.
-       Point p = bv_->getPos(cur, cur.boundary());
-       // Scroll one full page.
-       lyx::dispatch(FuncRequest(LFUN_SCROLL, "page up"));
-       // Try to place the cursor to the same coordinates.
-       setCursorFromCoordinates(cur, p.x_, p.y_);
-       // And move one line up in order to acknowledge in inset movement and/or
-       // selection.
-       cur.dispatch(FuncRequest(cur.selection()? LFUN_UP_SELECT: LFUN_UP));
-
-       if (cpar == cur.pit() && cpos == cur.pos())
-               // we have a row which is taller than the workarea. The
-               // simplest solution is to move to the previous row instead.
-               cur.dispatch(FuncRequest(cur.selection()? LFUN_UP_SELECT: LFUN_UP));
-
-       cur.finishUndo();
-       cur.updateFlags(Update::Force | Update::FitCursor);
-}
-
-
-void TextMetrics::cursorNext(Cursor & cur)
-{
-       if (bv_->isBottomScreen()) {
-               lyx::dispatch(FuncRequest(cur.selection()
-                       ? LFUN_BUFFER_END_SELECT : LFUN_BUFFER_END));
-               cur.finishUndo();
-               cur.updateFlags(Update::None);
-               return;
-       }
-
-       pos_type cpos = cur.pos();
-       pit_type cpar = cur.pit();
-
-       // Memorize current position.
-       Point p = bv_->getPos(cur, cur.boundary());
-       // Scroll one full page.
-       lyx::dispatch(FuncRequest(LFUN_SCROLL, "page down"));
-       // Try to place the cursor to the same coordinates.
-       setCursorFromCoordinates(cur, p.x_, p.y_);
-       // And move one line down in order to acknowledge in inset movement and/or
-       // selection.
-       cur.dispatch(FuncRequest(cur.selection()? LFUN_DOWN_SELECT: LFUN_DOWN));
-
-       if (cpar == cur.pit() && cpos == cur.pos())
-               // we have a row which is taller than the workarea. The
-               // simplest solution is to move to the next row instead.
-               cur.dispatch(
-                       FuncRequest(cur.selection()? LFUN_DOWN_SELECT: LFUN_DOWN));
-
-       cur.finishUndo();
-       cur.updateFlags(Update::Force | Update::FitCursor);
-}
-
-
 // the cursor set functions have a special mechanism. When they
 // realize you left an empty paragraph, they will delete it.
 
@@ -1768,9 +1700,9 @@ int TextMetrics::leftMargin(int max_width,
        Buffer const & buffer = bv_->buffer();
        //lyxerr << "TextMetrics::leftMargin: pit: " << pit << " pos: " << pos << endl;
        DocumentClass const & tclass = buffer.params().documentClass();
-       LayoutPtr const & layout = par.layout();
+       Layout const & layout = par.layout();
 
-       docstring parindent = layout->parindent;
+       docstring parindent = layout.parindent;
 
        int l_margin = 0;
 
@@ -1784,15 +1716,15 @@ int TextMetrics::leftMargin(int max_width,
                // find the next level paragraph
                pit_type newpar = outerHook(pit, pars);
                if (newpar != pit_type(pars.size())) {
-                       if (pars[newpar].layout()->isEnvironment()) {
+                       if (pars[newpar].layout().isEnvironment()) {
                                l_margin = leftMargin(max_width, newpar);
                        }
-                       //FIXME Should this check for emptyLayout() as well?
-                       if (par.layout() == tclass.defaultLayout()) {
+                       if (tclass.isDefaultLayout(par.layout()) 
+                           || tclass.isEmptyLayout(par.layout())) {
                                if (pars[newpar].params().noindent())
                                        parindent.erase();
                                else
-                                       parindent = pars[newpar].layout()->parindent;
+                                       parindent = pars[newpar].layout().parindent;
                        }
                }
        }
@@ -1800,34 +1732,34 @@ 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 (par.layout() == tclass.defaultLayout()
-           && pit > 0 && pars[pit - 1].layout()->nextnoindent)
+       if (tclass.isDefaultLayout(par.layout())
+           && pit > 0 && pars[pit - 1].layout().nextnoindent)
                parindent.erase();
 
        FontInfo const labelfont = text_->labelFont(buffer, par);
        FontMetrics const & labelfont_metrics = theFontMetrics(labelfont);
 
-       switch (layout->margintype) {
+       switch (layout.margintype) {
        case MARGIN_DYNAMIC:
-               if (!layout->leftmargin.empty()) {
+               if (!layout.leftmargin.empty()) {
                        l_margin += theFontMetrics(buffer.params().getFont()).signedWidth(
-                               layout->leftmargin);
+                               layout.leftmargin);
                }
                if (!par.labelString().empty()) {
-                       l_margin += labelfont_metrics.signedWidth(layout->labelindent);
+                       l_margin += labelfont_metrics.signedWidth(layout.labelindent);
                        l_margin += labelfont_metrics.width(par.labelString());
-                       l_margin += labelfont_metrics.width(layout->labelsep);
+                       l_margin += labelfont_metrics.width(layout.labelsep);
                }
                break;
 
        case MARGIN_MANUAL: {
-               l_margin += labelfont_metrics.signedWidth(layout->labelindent);
+               l_margin += labelfont_metrics.signedWidth(layout.labelindent);
                // The width of an empty par, even with manual label, should be 0
                if (!par.empty() && pos >= par.beginOfBody()) {
                        if (!par.getLabelWidthString().empty()) {
                                docstring labstr = par.getLabelWidthString();
                                l_margin += labelfont_metrics.width(labstr);
-                               l_margin += labelfont_metrics.width(layout->labelsep);
+                               l_margin += labelfont_metrics.width(layout.labelsep);
                        }
                }
                break;
@@ -1835,30 +1767,30 @@ int TextMetrics::leftMargin(int max_width,
 
        case MARGIN_STATIC: {
                l_margin += theFontMetrics(buffer.params().getFont()).
-                       signedWidth(layout->leftmargin) * 4     / (par.getDepth() + 4);
+                       signedWidth(layout.leftmargin) * 4      / (par.getDepth() + 4);
                break;
        }
 
        case MARGIN_FIRST_DYNAMIC:
-               if (layout->labeltype == LABEL_MANUAL) {
+               if (layout.labeltype == LABEL_MANUAL) {
                        if (pos >= par.beginOfBody()) {
-                               l_margin += labelfont_metrics.signedWidth(layout->leftmargin);
+                               l_margin += labelfont_metrics.signedWidth(layout.leftmargin);
                        } else {
-                               l_margin += labelfont_metrics.signedWidth(layout->labelindent);
+                               l_margin += labelfont_metrics.signedWidth(layout.labelindent);
                        }
                } else if (pos != 0
                           // Special case to fix problems with
                           // theorems (JMarc)
-                          || (layout->labeltype == LABEL_STATIC
-                              && layout->latextype == LATEX_ENVIRONMENT
+                          || (layout.labeltype == LABEL_STATIC
+                              && layout.latextype == LATEX_ENVIRONMENT
                               && !isFirstInSequence(pit, pars))) {
-                       l_margin += labelfont_metrics.signedWidth(layout->leftmargin);
-               } else if (layout->labeltype != LABEL_TOP_ENVIRONMENT
-                          && layout->labeltype != LABEL_BIBLIO
-                          && layout->labeltype !=
+                       l_margin += labelfont_metrics.signedWidth(layout.leftmargin);
+               } else if (layout.labeltype != LABEL_TOP_ENVIRONMENT
+                          && layout.labeltype != LABEL_BIBLIO
+                          && layout.labeltype !=
                           LABEL_CENTERED_TOP_ENVIRONMENT) {
-                       l_margin += labelfont_metrics.signedWidth(layout->labelindent);
-                       l_margin += labelfont_metrics.width(layout->labelsep);
+                       l_margin += labelfont_metrics.signedWidth(layout.labelindent);
+                       l_margin += labelfont_metrics.width(layout.labelsep);
                        l_margin += labelfont_metrics.width(par.labelString());
                }
                break;
@@ -1874,7 +1806,7 @@ int TextMetrics::leftMargin(int max_width,
                for ( ; rit != end; ++rit)
                        if (rit->fill() < minfill)
                                minfill = rit->fill();
-               l_margin += theFontMetrics(params.getFont()).signedWidth(layout->leftmargin);
+               l_margin += theFontMetrics(params.getFont()).signedWidth(layout.leftmargin);
                l_margin += minfill;
 #endif
                // also wrong, but much shorter.
@@ -1889,18 +1821,18 @@ int TextMetrics::leftMargin(int max_width,
        LyXAlignment align;
 
        if (par.params().align() == LYX_ALIGN_LAYOUT)
-               align = layout->align;
+               align = layout.align;
        else
                align = par.params().align();
 
        // set the correct parindent
        if (pos == 0
-           && (layout->labeltype == LABEL_NO_LABEL
-              || layout->labeltype == LABEL_TOP_ENVIRONMENT
-              || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT
-              || (layout->labeltype == LABEL_STATIC
-                        && layout->latextype == LATEX_ENVIRONMENT
-                  && !isFirstInSequence(pit, pars)))
+           && (layout.labeltype == LABEL_NO_LABEL
+              || layout.labeltype == LABEL_TOP_ENVIRONMENT
+              || layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT
+              || (layout.labeltype == LABEL_STATIC
+                  && layout.latextype == LATEX_ENVIRONMENT
+                  && !isFirstInSequence(pit, pars)))
            && align == LYX_ALIGN_BLOCK
            && !par.params().noindent()
            // in some insets, paragraphs are never indented
@@ -1909,9 +1841,10 @@ int TextMetrics::leftMargin(int max_width,
            && !(!par.empty()
                    && par.isInset(pos)
                    && par.getInset(pos)->display())
-           && (par.layout() != tclass.defaultLayout() //should this check emptyLayout()?
-               || buffer.params().paragraph_separation ==
-                  BufferParams::PARSEP_INDENT))
+                       && ((tclass.isDefaultLayout(par.layout()) 
+                || tclass.isEmptyLayout(par.layout()))
+               || buffer.params().paragraph_separation == BufferParams::PARSEP_INDENT)
+           )
        {
                l_margin += theFontMetrics(buffer.params().getFont()).signedWidth(
                        parindent);