]> git.lyx.org Git - lyx.git/blobdiff - src/text.C
Lars says _(_(b)) is a bug ... fix
[lyx.git] / src / text.C
index 602abcc7ae3bb852e7fa1d01044d881a4eb56575..46259d4d8b7b5f20dc52bf6fc9ba559670616bea 100644 (file)
 
 #include "lyxtext.h"
 #include "lyxrow.h"
-#include "lyxtextclasslist.h"
 #include "paragraph.h"
 #include "gettext.h"
 #include "bufferparams.h"
 #include "buffer.h"
 #include "debug.h"
+#include "intl.h"
 #include "lyxrc.h"
 #include "encoding.h"
 #include "frontends/LyXView.h"
 #include "frontends/Painter.h"
 #include "frontends/font_metrics.h"
 #include "frontends/screen.h"
+#include "frontends/WorkArea.h"
 #include "bufferview_funcs.h"
 #include "BufferView.h"
 #include "language.h"
 #include "ParagraphParameters.h"
 #include "undo_funcs.h"
+#include "WordLangTuple.h"
+#include "paragraph_funcs.h"
 
 #include "insets/insetbib.h"
 #include "insets/insettext.h"
@@ -78,7 +81,7 @@ int LyXText::workWidth(BufferView * bview, Inset * inset) const
                Buffer::inset_iterator it = bview->buffer()->inset_iterator_begin();
                Buffer::inset_iterator end = bview->buffer()->inset_iterator_end();
                for (; it != end; ++it) {
-                       if (*it == inset) {
+                       if (&(*it) == inset) {
                                par = it.getPar();
                                pos = it.getPos();
                                break;
@@ -90,10 +93,9 @@ int LyXText::workWidth(BufferView * bview, Inset * inset) const
                return workWidth(bview);
        }
 
-       LyXLayout const & layout =
-               textclasslist[bview->buffer()->params.textclass][par->layout()];
+       LyXLayout_ptr const & layout = par->layout();
 
-       if (layout.margintype != MARGIN_RIGHT_ADDRESS_BOX) {
+       if (layout->margintype != MARGIN_RIGHT_ADDRESS_BOX) {
                // Optimization here: in most cases, the real row is
                // not needed, but only the par/pos values. So we just
                // construct a dummy row for leftMargin. (JMarc)
@@ -148,12 +150,14 @@ unsigned char LyXText::transformChar(unsigned char c, Paragraph * par,
                }
 
        if (Encodings::is_arabic(next_char)) {
-               if (Encodings::is_arabic(prev_char))
+               if (Encodings::is_arabic(prev_char) &&
+                       !Encodings::is_arabic_special(prev_char))
                        return Encodings::TransformChar(c, Encodings::FORM_MEDIAL);
                else
                        return Encodings::TransformChar(c, Encodings::FORM_INITIAL);
        } else {
-               if (Encodings::is_arabic(prev_char))
+               if (Encodings::is_arabic(prev_char) &&
+                       !Encodings::is_arabic_special(prev_char))
                        return Encodings::TransformChar(c, Encodings::FORM_FINAL);
                else
                        return Encodings::TransformChar(c, Encodings::FORM_ISOLATED);
@@ -215,7 +219,7 @@ int LyXText::singleWidth(BufferView * bview, Paragraph * par,
                return font_metrics::width(c, font);
 
        } else if (IsHfillChar(c)) {
-               // Because of the representation as vertical lines 
+               // Because of the representation as vertical lines
                return 3;
        } else if (c == Paragraph::META_INSET) {
                Inset * tmpinset = par->getInset(pos);
@@ -631,6 +635,8 @@ void LyXText::drawChars(DrawRowParams & p, pos_type & vpos,
                if (orig_font != getFont(p.bv->buffer(), p.row->par(), pos))
                        break;
 
+               if (arabic)
+                       c = transformChar(c, p.row->par(), pos);
                str += c;
                ++vpos;
        }
@@ -677,7 +683,7 @@ bool LyXText::draw(DrawRowParams & p, pos_type & vpos)
        if ((!hebrew && !arabic)
                || (hebrew && !Encodings::IsComposeChar_hebrew(c))
                || (arabic && !Encodings::IsComposeChar_arabic(c))) {
-               drawChars(p, vpos, true, false);
+               drawChars(p, vpos, hebrew, arabic);
        } else if (hebrew) {
                drawHebrewComposeChar(p, vpos);
        } else if (arabic) {
@@ -686,21 +692,10 @@ bool LyXText::draw(DrawRowParams & p, pos_type & vpos)
 
        drawForeignMark(p, orig_x, orig_font);
 
-#ifdef INHERIT_LANGUAGE
-#ifdef WITH_WARNINGS
-       if ((font.language() == inherit_language) ||
-               (font.language() == ignore_language))
-               lyxerr << "No this shouldn't happen!\n";
-#endif
-#endif
        return true;
 }
 
 
-// Returns the left beginning of the text.
-// This information cannot be taken from the layouts-objekt, because in
-// LaTeX the beginning of the text fits in some cases (for example sections)
-// exactly the label-width.
 int LyXText::leftMargin(BufferView * bview, Row const * row) const
 {
        Inset * ins;
@@ -710,39 +705,38 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                return LYX_PAPER_MARGIN;
 
        LyXTextClass const & tclass =
-               textclasslist[bview->buffer()->params.textclass];
-       LyXLayout const & layout = tclass[row->par()->layout()];
+               bview->buffer()->params.getLyXTextClass();
+       LyXLayout_ptr const & layout = row->par()->layout();
 
-       string parindent = layout.parindent;
+       string parindent = layout->parindent;
 
        int x = LYX_PAPER_MARGIN;
-       
+
        x += font_metrics::signedWidth(tclass.leftmargin(), tclass.defaultfont());
 
        // this is the way, LyX handles the LaTeX-Environments.
        // I have had this idea very late, so it seems to be a
        // later added hack and this is true
        if (!row->par()->getDepth()) {
-               if (row->par()->layout() == tclass.defaultLayoutName()) {
+               if (row->par()->layout() == tclass.defaultLayout()) {
                        // find the previous same level paragraph
                        if (row->par()->previous()) {
                                Paragraph * newpar = row->par()
                                        ->depthHook(row->par()->getDepth());
                                if (newpar &&
-                                   tclass[newpar->layout()].nextnoindent)
+                                   newpar->layout()->nextnoindent)
                                        parindent.erase();
                        }
                }
        } else {
                // find the next level paragraph
 
-               Paragraph * newpar =
-                       row->par()->outerHook();
+               Paragraph * newpar = row->par()->outerHook();
 
                // make a corresponding row. Needed to call LeftMargin()
 
                // check wether it is a sufficent paragraph
-               if (newpar && tclass[newpar->layout()].isEnvironment()) {
+               if (newpar && newpar->layout()->isEnvironment()) {
                        Row dummyrow;
                        dummyrow.par(newpar);
                        dummyrow.pos(newpar->size());
@@ -755,67 +749,69 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                        row->par()->params().depth(0);
                }
 
-               if (newpar && row->par()->layout() == tclass.defaultLayoutName()) {
+               if (newpar && row->par()->layout() == tclass.defaultLayout()) {
                        if (newpar->params().noindent())
                                parindent.erase();
-                       else
-                               parindent = tclass[newpar->layout()].parindent;
+                       else {
+                               parindent = newpar->layout()->parindent;
+                       }
+
                }
        }
 
        LyXFont const labelfont = getLabelFont(bview->buffer(), row->par());
-       switch (layout.margintype) {
+       switch (layout->margintype) {
        case MARGIN_DYNAMIC:
-               if (!layout.leftmargin.empty()) {
-                       x += font_metrics::signedWidth(layout.leftmargin,
+               if (!layout->leftmargin.empty()) {
+                       x += font_metrics::signedWidth(layout->leftmargin,
                                                  tclass.defaultfont());
                }
                if (!row->par()->getLabelstring().empty()) {
-                       x += font_metrics::signedWidth(layout.labelindent,
+                       x += font_metrics::signedWidth(layout->labelindent,
                                                  labelfont);
                        x += font_metrics::width(row->par()->getLabelstring(),
                                            labelfont);
-                       x += font_metrics::width(layout.labelsep, labelfont);
+                       x += font_metrics::width(layout->labelsep, labelfont);
                }
                break;
        case MARGIN_MANUAL:
-               x += font_metrics::signedWidth(layout.labelindent, labelfont);
+               x += font_metrics::signedWidth(layout->labelindent, labelfont);
                if (row->pos() >= beginningOfMainBody(bview->buffer(), row->par())) {
                        if (!row->par()->getLabelWidthString().empty()) {
                                x += font_metrics::width(row->par()->getLabelWidthString(),
                                               labelfont);
-                               x += font_metrics::width(layout.labelsep, labelfont);
+                               x += font_metrics::width(layout->labelsep, labelfont);
                        }
                }
                break;
        case MARGIN_STATIC:
-               x += font_metrics::signedWidth(layout.leftmargin, tclass.defaultfont()) * 4
+               x += font_metrics::signedWidth(layout->leftmargin, tclass.defaultfont()) * 4
                        / (row->par()->getDepth() + 4);
                break;
        case MARGIN_FIRST_DYNAMIC:
-               if (layout.labeltype == LABEL_MANUAL) {
+               if (layout->labeltype == LABEL_MANUAL) {
                        if (row->pos() >= beginningOfMainBody(bview->buffer(), row->par())) {
-                               x += font_metrics::signedWidth(layout.leftmargin,
+                               x += font_metrics::signedWidth(layout->leftmargin,
                                                          labelfont);
                        } else {
-                               x += font_metrics::signedWidth(layout.labelindent,
+                               x += font_metrics::signedWidth(layout->labelindent,
                                                          labelfont);
                        }
                } else if (row->pos()
                           // Special case to fix problems with
                           // theorems (JMarc)
-                          || (layout.labeltype == LABEL_STATIC
-                              && layout.latextype == LATEX_ENVIRONMENT
+                          || (layout->labeltype == LABEL_STATIC
+                              && layout->latextype == LATEX_ENVIRONMENT
                               && ! row->par()->isFirstInSequence())) {
-                       x += font_metrics::signedWidth(layout.leftmargin,
+                       x += font_metrics::signedWidth(layout->leftmargin,
                                                  labelfont);
-               } else if (layout.labeltype != LABEL_TOP_ENVIRONMENT
-                          && layout.labeltype != LABEL_BIBLIO
-                          && layout.labeltype !=
+               } else if (layout->labeltype != LABEL_TOP_ENVIRONMENT
+                          && layout->labeltype != LABEL_BIBLIO
+                          && layout->labeltype !=
                           LABEL_CENTERED_TOP_ENVIRONMENT) {
-                       x += font_metrics::signedWidth(layout.labelindent,
+                       x += font_metrics::signedWidth(layout->labelindent,
                                                  labelfont);
-                       x += font_metrics::width(layout.labelsep, labelfont);
+                       x += font_metrics::width(layout->labelsep, labelfont);
                        x += font_metrics::width(row->par()->getLabelstring(),
                                            labelfont);
                }
@@ -839,8 +835,8 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                        if (tmprow->fill() < minfill)
                                minfill = tmprow->fill();
                }
-               
-               x += font_metrics::signedWidth(layout.leftmargin,
+
+               x += font_metrics::signedWidth(layout->leftmargin,
                        tclass.defaultfont());
                x += minfill;
        }
@@ -853,23 +849,23 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                LyXLength const len = row->par()->params().leftIndent();
                int const tw = inset_owner ?
                        inset_owner->latexTextWidth(bview) : workWidth(bview);
-               x += len.inPixels(tw, bview->text->defaultHeight());
+               x += len.inPixels(tw);
        }
 
        LyXAlignment align; // wrong type
 
        if (row->par()->params().align() == LYX_ALIGN_LAYOUT)
-               align = layout.align;
+               align = layout->align;
        else
                align = row->par()->params().align();
 
        // set the correct parindent
        if (row->pos() == 0) {
-               if ((layout.labeltype == LABEL_NO_LABEL
-                    || layout.labeltype == LABEL_TOP_ENVIRONMENT
-                    || layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT
-                    || (layout.labeltype == LABEL_STATIC
-                        && layout.latextype == LATEX_ENVIRONMENT
+               if ((layout->labeltype == LABEL_NO_LABEL
+                    || layout->labeltype == LABEL_TOP_ENVIRONMENT
+                    || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT
+                    || (layout->labeltype == LABEL_STATIC
+                        && layout->latextype == LATEX_ENVIRONMENT
                         && ! row->par()->isFirstInSequence()))
                    && align == LYX_ALIGN_BLOCK
                    && !row->par()->params().noindent()
@@ -877,12 +873,12 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                        && (!row->par()->inInset() || !row->par()->inInset()->owner() ||
                                (row->par()->inInset()->owner()->lyxCode() != Inset::TABULAR_CODE &&
                                 row->par()->inInset()->owner()->lyxCode() != Inset::ERT_CODE))
-                   && (row->par()->layout() != tclass.defaultLayoutName() ||
+                   && (row->par()->layout() != tclass.defaultLayout() ||
                        bview->buffer()->params.paragraph_separation ==
                        BufferParams::PARSEP_INDENT)) {
                        x += font_metrics::signedWidth(parindent,
                                                  tclass.defaultfont());
-               } else if (layout.labeltype == LABEL_BIBLIO) {
+               } else if (layout->labeltype == LABEL_BIBLIO) {
                        // ale970405 Right width for bibitems
                        x += bibitemMaxWidth(bview, tclass.defaultfont());
                }
@@ -900,8 +896,8 @@ int LyXText::rightMargin(Buffer const * buf, Row const * row) const
                (ins->needFullRow() || ins->display()))
                return LYX_PAPER_MARGIN;
 
-       LyXTextClass const & tclass = textclasslist[buf->params.textclass];
-       LyXLayout const & layout = tclass[row->par()->layout()];
+       LyXTextClass const & tclass = buf->params.getLyXTextClass();
+       LyXLayout_ptr const & layout = row->par()->layout();
 
        int x = LYX_PAPER_MARGIN
                + font_metrics::signedWidth(tclass.rightmargin(),
@@ -923,7 +919,7 @@ int LyXText::rightMargin(Buffer const * buf, Row const * row) const
                // make a corresponding row. Needed to call LeftMargin()
 
                // check wether it is a sufficent paragraph
-               if (newpar && tclass[newpar->layout()].isEnvironment()) {
+               if (newpar && newpar->layout()->isEnvironment()) {
                        Row dummyrow;
                        dummyrow.par(newpar);
                        dummyrow.pos(0);
@@ -938,7 +934,8 @@ int LyXText::rightMargin(Buffer const * buf, Row const * row) const
        }
 
        //lyxerr << "rightmargin: " << layout->rightmargin << endl;
-       x += font_metrics::signedWidth(layout.rightmargin, tclass.defaultfont())
+       x += font_metrics::signedWidth(layout->rightmargin,
+                                      tclass.defaultfont())
                * 4 / (row->par()->getDepth() + 4);
        return x;
 }
@@ -946,17 +943,16 @@ int LyXText::rightMargin(Buffer const * buf, Row const * row) const
 
 int LyXText::labelEnd(BufferView * bview, Row const * row) const
 {
-       if (textclasslist[bview->buffer()->params.textclass][row->par()->layout()].margintype
-           == MARGIN_MANUAL) {
+       if (row->par()->layout()->margintype == MARGIN_MANUAL) {
                Row tmprow;
                tmprow = *row;
                tmprow.pos(row->par()->size());
-               // just the beginning of the main body 
+               // just the beginning of the main body
                return leftMargin(bview, &tmprow);
        } else {
                // LabelEnd is only needed,
-               // if the layout fills a flushleft label. 
-               return 0; 
+               // if the layout fills a flushleft label.
+               return 0;
        }
 }
 
@@ -979,11 +975,11 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
 
        pos_type const main_body =
                beginningOfMainBody(bview->buffer(), par);
-       LyXLayout const & layout =
-               textclasslist[bview->buffer()->params.textclass][par->layout()];
+       LyXLayout_ptr const & layout = par->layout();
+
        pos_type i = pos;
 
-       if (layout.margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+       if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
                // special code for right address boxes, only newlines count
                while (i < par->size()) {
                        if (par->isNewline(i)) {
@@ -1016,8 +1012,8 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
                                // valid here. if not, change it to
                                // non-display
                                if (in->display() &&
-                                   (layout.isCommand() ||
-                                    (layout.labeltype == LABEL_MANUAL
+                                   (layout->isCommand() ||
+                                    (layout->labeltype == LABEL_MANUAL
                                      && i < beginningOfMainBody(bview->buffer(), par))))
                                {
                                        // display istn't allowd
@@ -1055,7 +1051,7 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
                        }
                        ++i;
                        if (i == main_body) {
-                               x += font_metrics::width(layout.labelsep,
+                               x += font_metrics::width(layout->labelsep,
                                                    getLabelFont(bview->buffer(), par));
                                if (par->isLineSeparator(i - 1))
                                        x-= singleWidth(bview, par, i - 1);
@@ -1098,9 +1094,7 @@ int LyXText::fill(BufferView * bview, Row * row, int paper_width) const
        pos_type const last = rowLastPrintable(row);
 
        // special handling of the right address boxes
-       if (textclasslist[bview->buffer()->params.textclass][row->par()->layout()].margintype
-           == MARGIN_RIGHT_ADDRESS_BOX)
-       {
+       if (row->par()->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
                int const tmpfill = row->fill();
                row->fill(0); // the minfill in MarginLeft()
                w = leftMargin(bview, row);
@@ -1108,14 +1102,15 @@ int LyXText::fill(BufferView * bview, Row * row, int paper_width) const
        } else
                w = leftMargin(bview, row);
 
-       LyXLayout const & layout = textclasslist[bview->buffer()->params.textclass][row->par()->layout()];
+       LyXLayout_ptr const & layout = row->par()->layout();
+
        pos_type const main_body =
                beginningOfMainBody(bview->buffer(), row->par());
        pos_type i = row->pos();
 
        while (i <= last) {
                if (main_body > 0 && i == main_body) {
-                       w += font_metrics::width(layout.labelsep, getLabelFont(bview->buffer(), row->par()));
+                       w += font_metrics::width(layout->labelsep, getLabelFont(bview->buffer(), row->par()));
                        if (row->par()->isLineSeparator(i - 1))
                                w -= singleWidth(bview, row->par(), i - 1);
                        int left_margin = labelEnd(bview, row);
@@ -1126,7 +1121,7 @@ int LyXText::fill(BufferView * bview, Row * row, int paper_width) const
                ++i;
        }
        if (main_body > 0 && main_body > last) {
-               w += font_metrics::width(layout.labelsep, getLabelFont(bview->buffer(), row->par()));
+               w += font_metrics::width(layout->labelsep, getLabelFont(bview->buffer(), row->par()));
                if (last >= 0 && row->par()->isLineSeparator(last))
                        w -= singleWidth(bview, row->par(), last);
                int const left_margin = labelEnd(bview, row);
@@ -1270,8 +1265,7 @@ bool LyXText::hfillExpansion(Buffer const * buf, Row const * row_ptr,
                return true;
 
        // in some labels  it does not count
-       if (textclasslist[buf->params.textclass][row_ptr->par()->layout()].margintype
-           != MARGIN_MANUAL
+       if (row_ptr->par()->layout()->margintype != MARGIN_MANUAL
            && pos < beginningOfMainBody(buf, row_ptr->par()))
                return false;
 
@@ -1309,15 +1303,14 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
        // ok , let us initialize the maxasc and maxdesc value.
        // This depends in LaTeX of the font of the last character
        // in the paragraph. The hack below is necessary because
-       // of the possibility of open footnotes 
+       // of the possibility of open footnotes
 
        // Correction: only the fontsize count. The other properties
-       //  are taken from the layoutfont. Nicer on the screen :) 
+       //  are taken from the layoutfont. Nicer on the screen :)
        Paragraph * par = row_ptr->par();
        Paragraph * firstpar = row_ptr->par();
 
-       LyXLayout const & layout
-               = textclasslist[bview->buffer()->params.textclass][firstpar->layout()];
+       LyXLayout_ptr const & layout = firstpar->layout();
 
        // as max get the first character of this row then it can increes but not
        // decrees the height. Just some point to start with so we don't have to
@@ -1339,11 +1332,11 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
        //lyxerr << "spacing_val = " << spacing_val << endl;
 
        int maxasc = int(font_metrics::maxAscent(font) *
-                        layout.spacing.getValue() *
-                        spacing_val);
+                        layout->spacing.getValue() *
+                        spacing_val);
        int maxdesc = int(font_metrics::maxDescent(font) *
-                         layout.spacing.getValue() *
-                         spacing_val);
+                         layout->spacing.getValue() *
+                         spacing_val);
 
        pos_type const pos_end = rowLast(row_ptr);
        int labeladdon = 0;
@@ -1398,13 +1391,13 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                if (bview->buffer()->params.paragraph_separation ==
                        BufferParams::PARSEP_SKIP)
                {
-                       if (layout.isParagraph()
+                       if (layout->isParagraph()
                                && firstpar->getDepth() == 0
                                && firstpar->previous())
                        {
                                maxasc += bview->buffer()->params.getDefSkip().inPixels(bview);
                        } else if (firstpar->previous() &&
-                                  textclasslist[bview->buffer()->params.textclass][firstpar->previous()->layout()].isParagraph() &&
+                                  firstpar->previous()->layout()->isParagraph() &&
                                   firstpar->previous()->getDepth() == 0)
                        {
                                // is it right to use defskip here too? (AS)
@@ -1431,7 +1424,7 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
 
                // This is special code for the chapter, since the label of this
                // layout is printed in an extra row
-               if (layout.labeltype == LABEL_COUNTER_CHAPTER
+               if (layout->labeltype == LABEL_COUNTER_CHAPTER
                        && bview->buffer()->params.secnumdepth >= 0)
                {
                        float spacing_val = 1.0;
@@ -1442,17 +1435,17 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                        }
 
                        labeladdon = int(font_metrics::maxDescent(labelfont) *
-                                        layout.spacing.getValue() *
-                                        spacing_val)
+                                        layout->spacing.getValue() *
+                                        spacing_val)
                                + int(font_metrics::maxAscent(labelfont) *
-                                     layout.spacing.getValue() *
+                                     layout->spacing.getValue() *
                                      spacing_val);
                }
 
                // 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)
                    && row_ptr->par()->isFirstInSequence()
                    && !row_ptr->par()->getLabelstring().empty())
                {
@@ -1465,13 +1458,13 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
 
                        labeladdon = int(
                                (font_metrics::maxAscent(labelfont) *
-                                layout.spacing.getValue() *
+                                layout->spacing.getValue() *
                                 spacing_val)
                                +(font_metrics::maxDescent(labelfont) *
-                                 layout.spacing.getValue() *
+                                 layout->spacing.getValue() *
                                  spacing_val)
-                               + layout.topsep * defaultHeight()
-                               + layout.labelbottomsep *  defaultHeight());
+                               + layout->topsep * defaultHeight()
+                               + layout->labelbottomsep *  defaultHeight());
                }
 
                // and now the layout spaces, for example before and after a section,
@@ -1485,17 +1478,17 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                                prev->getDepth() == firstpar->getDepth() &&
                                prev->getLabelWidthString() == firstpar->getLabelWidthString())
                        {
-                               layoutasc = (layout.itemsep * defaultHeight());
+                               layoutasc = (layout->itemsep * defaultHeight());
                        } else if (row_ptr->previous()) {
-                               tmptop = layout.topsep;
+                               tmptop = layout->topsep;
 
                                if (row_ptr->previous()->par()->getDepth() >= row_ptr->par()->getDepth())
-                                       tmptop -= textclasslist[bview->buffer()->params.textclass][row_ptr->previous()->par()->layout()].bottomsep;
+                                       tmptop -= row_ptr->previous()->par()->layout()->bottomsep;
 
                                if (tmptop > 0)
                                        layoutasc = (tmptop * defaultHeight());
                        } else if (row_ptr->par()->params().lineTop()) {
-                               tmptop = layout.topsep;
+                               tmptop = layout->topsep;
 
                                if (tmptop > 0)
                                        layoutasc = (tmptop * defaultHeight());
@@ -1503,7 +1496,7 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
 
                        prev = row_ptr->par()->outerHook();
                        if (prev)  {
-                               maxasc += int(textclasslist[bview->buffer()->params.textclass][prev->layout()].parsep * defaultHeight());
+                               maxasc += int(prev->layout()->parsep * defaultHeight());
                        } else {
                                if (firstpar->previous() &&
                                        firstpar->previous()->getDepth() == 0 &&
@@ -1512,7 +1505,7 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                                {
                                        // avoid parsep
                                } else if (firstpar->previous()) {
-                                       maxasc += int(layout.parsep * defaultHeight());
+                                       maxasc += int(layout->parsep * defaultHeight());
                                }
                        }
                }
@@ -1533,7 +1526,7 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                // there height depends on the font of the nearest character
                if (firstpar->params().lineBottom())
                        maxdesc += 2 * font_metrics::ascent('x',
-                                                      getFont(bview->buffer(),
+                                                      getFont(bview->buffer(),
                                                               par,
                                                               max(pos_type(0), par->size() - 1)));
 
@@ -1552,13 +1545,13 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                        float unusual = 0;
 
                        if (comparepar->getDepth() > nextpar->getDepth()) {
-                               usual = (textclasslist[bview->buffer()->params.textclass][comparepar->layout()].bottomsep * defaultHeight());
+                               usual = (comparepar->layout()->bottomsep * defaultHeight());
                                comparepar = comparepar->depthHook(nextpar->getDepth());
                                if (comparepar->layout()!= nextpar->layout()
                                        || nextpar->getLabelWidthString() !=
                                        comparepar->getLabelWidthString())
                                {
-                                       unusual = (textclasslist[bview->buffer()->params.textclass][comparepar->layout()].bottomsep * defaultHeight());
+                                       unusual = (comparepar->layout()->bottomsep * defaultHeight());
                                }
                                if (unusual > usual)
                                        layoutdesc = unusual;
@@ -1569,7 +1562,7 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                                if (comparepar->layout() != nextpar->layout()
                                        || nextpar->getLabelWidthString() !=
                                        comparepar->getLabelWidthString())
-                                       layoutdesc = int(textclasslist[bview->buffer()->params.textclass][comparepar->layout()].bottomsep * defaultHeight());
+                                       layoutdesc = int(comparepar->layout()->bottomsep * defaultHeight());
                        }
                }
        }
@@ -1586,7 +1579,7 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
 
        height += row_ptr->height();
        float x = 0;
-       if (layout.margintype != MARGIN_RIGHT_ADDRESS_BOX) {
+       if (layout->margintype != MARGIN_RIGHT_ADDRESS_BOX) {
                float dummy;
                // this IS needed
                row_ptr->width(maxwidth);
@@ -1606,7 +1599,7 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
 
 
 // Appends the implicit specified paragraph behind the specified row,
-// start at the implicit given position 
+// start at the implicit given position
 void LyXText::appendParagraph(BufferView * bview, Row * row) const
 {
        bool not_ready = true;
@@ -1679,7 +1672,7 @@ void LyXText::breakAgain(BufferView * bview, Row * row) const
                        not_ready = false;
                }
 
-               // set the dimensions of the row 
+               // set the dimensions of the row
                tmprow->fill(fill(bview, tmprow, workWidth(bview)));
                setHeightOfRow(bview, tmprow);
        } while (not_ready);
@@ -1696,7 +1689,7 @@ void LyXText::breakAgainOneRow(BufferView * bview, Row * row)
        if (z < row->par()->size()) {
                if (!row->next()
                    || (row->next() && row->next()->par() != row->par())) {
-                       // insert a new row 
+                       // insert a new row
                        ++z;
                        insertRow(row, row->par(), z);
                        row = row->next();
@@ -1730,14 +1723,14 @@ void LyXText::breakAgainOneRow(BufferView * bview, Row * row)
 void LyXText::breakParagraph(BufferView * bview, char keep_layout)
 {
        LyXTextClass const & tclass =
-               textclasslist[bview->buffer()->params.textclass];
-       LyXLayout const & layout = tclass[cursor.par()->layout()];
+               bview->buffer()->params.getLyXTextClass();
+       LyXLayout_ptr const & layout = cursor.par()->layout();
 
        // this is only allowed, if the current paragraph is not empty or caption
        // and if it has not the keepempty flag aktive
-       if ((cursor.par()->size() <= 0)
-          && layout.labeltype != LABEL_SENSITIVE
-          && !layout.keepempty)
+       if (cursor.par()->empty()
+          && layout->labeltype != LABEL_SENSITIVE
+          && !layout->keepempty)
                return;
 
        setUndo(bview, Undo::FINISH, cursor.par(), cursor.par()->next());
@@ -1754,32 +1747,32 @@ void LyXText::breakParagraph(BufferView * bview, char keep_layout)
        if (keep_layout)
                keep_layout = 2;
        else
-               keep_layout = layout.isEnvironment();
+               keep_layout = layout->isEnvironment();
 
        // we need to set this before we insert the paragraph. IMO the
        // breakParagraph call should return a bool if it inserts the
        // paragraph before or behind and we should react on that one
        // but we can fix this in 1.3.0 (Jug 20020509)
-       bool const isempty = (layout.keepempty && !cursor.par()->size());
-       cursor.par()->breakParagraph(bview->buffer()->params, cursor.pos(),
-                               keep_layout);
+       bool const isempty = (layout->keepempty && cursor.par()->empty());
+       ::breakParagraph(bview->buffer()->params, cursor.par(), cursor.pos(),
+                      keep_layout);
 
        // well this is the caption hack since one caption is really enough
-       if (layout.labeltype == LABEL_SENSITIVE) {
+       if (layout->labeltype == LABEL_SENSITIVE) {
                if (!cursor.pos())
                        // set to standard-layout
-                       cursor.par()->applyLayout(tclass.defaultLayoutName());
+                       cursor.par()->applyLayout(tclass.defaultLayout());
                else
                        // set to standard-layout
-                       cursor.par()->next()->applyLayout(tclass.defaultLayoutName());
+                       cursor.par()->next()->applyLayout(tclass.defaultLayout());
        }
 
        // if the cursor is at the beginning of a row without prior newline,
        // move one row up!
        // This touches only the screen-update. Otherwise we would may have
-       // an empty row on the screen 
+       // an empty row on the screen
        if (cursor.pos() && !cursor.row()->par()->isNewline(cursor.row()->pos() - 1)
-                        && cursor.row()->pos() == cursor.pos())
+                        && cursor.row()->pos() == cursor.pos())
        {
                cursorLeft(bview);
        }
@@ -1789,7 +1782,7 @@ void LyXText::breakParagraph(BufferView * bview, char keep_layout)
        refresh_y = cursor.y() - cursor.row()->baseline();
 
        // Do not forget the special right address boxes
-       if (layout.margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+       if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
                while (refresh_row->previous() &&
                       refresh_row->previous()->par() == refresh_row->par())
                {
@@ -1804,13 +1797,13 @@ void LyXText::breakParagraph(BufferView * bview, char keep_layout)
 
        setHeightOfRow(bview, cursor.row());
 
-       while (cursor.par()->next()->size()
+       while (!cursor.par()->next()->empty()
          && cursor.par()->next()->isNewline(0))
           cursor.par()->next()->erase(0);
 
        insertParagraph(bview, cursor.par()->next(), cursor.row());
 
-       updateCounters(bview, cursor.row()->previous());
+       updateCounters(bview);
 
        // This check is necessary. Otherwise the new empty paragraph will
        // be deleted automatically. And it is more friendly for the user!
@@ -1836,7 +1829,7 @@ void LyXText::redoParagraph(BufferView * bview) const
 
 
 // insert a character, moves all the following breaks in the
-// same Paragraph one to the right and make a rebreak 
+// same Paragraph one to the right and make a rebreak
 void LyXText::insertChar(BufferView * bview, char c)
 {
        setUndo(bview, Undo::INSERT, cursor.par(), cursor.par()->next());
@@ -1844,8 +1837,7 @@ void LyXText::insertChar(BufferView * bview, char c)
        // When the free-spacing option is set for the current layout,
        // disable the double-space checking
 
-       bool const freeSpacing =
-               textclasslist[bview->buffer()->params.textclass][cursor.row()->par()->layout()].free_spacing ||
+       bool const freeSpacing = cursor.row()->par()->layout()->free_spacing ||
                cursor.row()->par()->isFreeSpacing();
 
        if (lyxrc.auto_number) {
@@ -1908,9 +1900,9 @@ void LyXText::insertChar(BufferView * bview, char c)
        // CHECK There is a bug here! (Asger)
 
        LyXFont realtmpfont = real_current_font;
-       LyXFont rawtmpfont = current_font; 
+       LyXFont rawtmpfont = current_font;
        // store the current font.  This is because of the use of cursor
-       // movements. The moving cursor would refresh the current font 
+       // movements. The moving cursor would refresh the current font
 
        // Get the font that is used to calculate the baselineskip
        pos_type const lastpos = cursor.par()->size();
@@ -2036,11 +2028,10 @@ void LyXText::insertChar(BufferView * bview, char c)
                // we would not get a rebreak!
                row->fill(fill(bview, row, workWidth(bview)));
        }
+
        if (c == Paragraph::META_INSET || row->fill() < 0) {
                refresh_y = y;
                refresh_row = row;
-               refresh_x = cursor.x();
-               refresh_pos = cursor.pos();
                status(bview, LyXText::NEED_MORE_REFRESH);
                breakAgainOneRow(bview, row);
                // will the cursor be in another row now?
@@ -2065,9 +2056,7 @@ void LyXText::insertChar(BufferView * bview, char c)
                        need_break_row = 0;
        } else {
                refresh_y = y;
-               refresh_x = cursor.x();
                refresh_row = row;
-               refresh_pos = cursor.pos();
 
                int const tmpheight = row->height();
                setHeightOfRow(bview, row);
@@ -2088,7 +2077,7 @@ void LyXText::insertChar(BufferView * bview, char c)
                redoHeightOfParagraph(bview, cursor);
        } else {
                // now the special right address boxes
-               if (textclasslist[bview->buffer()->params.textclass][cursor.par()->layout()].margintype
+               if (cursor.par()->layout()->margintype
                    == MARGIN_RIGHT_ADDRESS_BOX) {
                        redoDrawingOfParagraph(bview, cursor);
                }
@@ -2138,11 +2127,10 @@ void LyXText::prepareToPrint(BufferView * bview,
                        ? leftMargin(bview, row) : 0;
 
        // is there a manual margin with a manual label
-       LyXTextClass const & tclass = textclasslist[bview->buffer()->params.textclass];
-       LyXLayout const & layout = tclass[row->par()->layout()];
+       LyXLayout_ptr const & layout = row->par()->layout();
 
-       if (layout.margintype == MARGIN_MANUAL
-           && layout.labeltype == LABEL_MANUAL) {
+       if (layout->margintype == MARGIN_MANUAL
+           && layout->labeltype == LABEL_MANUAL) {
                // one more since labels are left aligned
                nlh = numberOfLabelHfills(bview->buffer(), row) + 1;
                if (nlh && !row->par()->getLabelWidthString().empty()) {
@@ -2164,7 +2152,7 @@ void LyXText::prepareToPrint(BufferView * bview,
                // set x how you need it
                int align;
                if (row->par()->params().align() == LYX_ALIGN_LAYOUT) {
-                       align = layout.align;
+                       align = layout->align;
                } else {
                        align = row->par()->params().align();
                }
@@ -2219,7 +2207,7 @@ void LyXText::prepareToPrint(BufferView * bview,
                if (main_body > 0 &&
                    (main_body - 1 > last ||
                     !row->par()->isLineSeparator(main_body - 1))) {
-                       x += font_metrics::width(layout.labelsep,
+                       x += font_metrics::width(layout->labelsep,
                                            getLabelFont(bview->buffer(), row->par()));
                        if (main_body - 1 <= last)
                                x += fill_label_hfill;
@@ -2228,12 +2216,12 @@ void LyXText::prepareToPrint(BufferView * bview,
 }
 
 
-// important for the screen 
+// important for the screen
 
 
 // the cursor set functions have a special mechanism. When they
 // realize, that you left an empty paragraph, they will delete it.
-// They also delete the corresponding row 
+// They also delete the corresponding row
 
 void LyXText::cursorRightOneWord(BufferView * bview) const
 {
@@ -2286,7 +2274,7 @@ void LyXText::cursorTab(BufferView * bview) const
 
 
 // Skip initial whitespace at end of word and move cursor to *start*
-// of prior word, not to end of next prior word. 
+// of prior word, not to end of next prior word.
 void LyXText::cursorLeftOneWord(BufferView * bview)  const
 {
        LyXCursor tmpcursor = cursor;
@@ -2295,7 +2283,7 @@ void LyXText::cursorLeftOneWord(BufferView * bview)  const
 }
 
 
-void LyXText::cursorLeftOneWord(LyXCursor  & cur)  const
+void LyXText::cursorLeftOneWord(LyXCursor & cur) const
 {
        // treat HFills, floats and Insets as words
        cur = cursor;
@@ -2317,14 +2305,14 @@ void LyXText::cursorLeftOneWord(LyXCursor  & cur)  const
                }
        } else {                // Here, cur != 0
                while (cur.pos() > 0 &&
-                      cur.par()->isWord(cur.pos()-1))
+                      cur.par()->isWord(cur.pos() - 1))
                        cur.pos(cur.pos() - 1);
        }
 }
 
 
 // Select current word. This depends on behaviour of
-// CursorLeftOneWord(), so it is patched as well. 
+// CursorLeftOneWord(), so it is patched as well.
 void LyXText::getWord(LyXCursor & from, LyXCursor & to,
                      word_location const loc) const
 {
@@ -2335,8 +2323,8 @@ void LyXText::getWord(LyXCursor & from, LyXCursor & to,
                if (cursor.pos() == 0 || cursor.pos() == cursor.par()->size()
                    || cursor.par()->isSeparator(cursor.pos())
                    || cursor.par()->isKomma(cursor.pos())
-                   || cursor.par()->isSeparator(cursor.pos() -1)
-                   || cursor.par()->isKomma(cursor.pos() -1)) {
+                   || cursor.par()->isSeparator(cursor.pos() - 1)
+                   || cursor.par()->isKomma(cursor.pos() - 1)) {
                        to = from;
                        return;
                }
@@ -2362,7 +2350,8 @@ void LyXText::getWord(LyXCursor & from, LyXCursor & to,
        while (to.pos() < to.par()->size()
               && !to.par()->isSeparator(to.pos())
               && !to.par()->isKomma(to.pos())
-              && !to.par()->isHfill(to.pos()))
+              && !to.par()->isHfill(to.pos())
+              && !to.par()->isInset(to.pos()))
        {
                to.pos(to.pos() + 1);
        }
@@ -2385,7 +2374,7 @@ void LyXText::selectWord(BufferView * bview, word_location const loc)
 
 
 // Select the word currently under the cursor when no
-// selection is currently set 
+// selection is currently set
 bool LyXText::selectWordWhenUnderCursor(BufferView * bview,
                                        word_location const loc)
 {
@@ -2399,19 +2388,20 @@ bool LyXText::selectWordWhenUnderCursor(BufferView * bview,
 
 // This function is only used by the spellchecker for NextWord().
 // It doesn't handle LYX_ACCENTs and probably never will.
-string const LyXText::selectNextWordToSpellcheck(BufferView * bview,
-                                                float & value) const
+WordLangTuple const
+LyXText::selectNextWordToSpellcheck(BufferView * bview, float & value) const
 {
        if (the_locking_inset) {
-               string str = the_locking_inset->selectNextWordToSpellcheck(bview, value);
-               if (!str.empty()) {
-                       value += float(cursor.y())/float(height);
-                       return str;
+               WordLangTuple word = the_locking_inset->selectNextWordToSpellcheck(bview, value);
+               if (!word.word().empty()) {
+                       value += float(cursor.y());
+                       value /= float(height);
+                       return word;
                }
-               // we have to go on checking so move cusor to the next char
+               // we have to go on checking so move cursor to the next char
                if (cursor.pos() == cursor.par()->size()) {
                        if (!cursor.par()->next())
-                               return str;
+                               return word;
                        cursor.par(cursor.par()->next());
                        cursor.pos(0);
                } else
@@ -2463,6 +2453,9 @@ string const LyXText::selectNextWordToSpellcheck(BufferView * bview,
        // Start the selection from here
        selection.cursor = cursor;
 
+       string lang_code(
+               getFont(bview->buffer(), cursor.par(), cursor.pos())
+                       .language()->code());
        // and find the end of the word (insets like optional hyphens
        // and ligature break are part of a word)
        while (cursor.pos() < cursor.par()->size()
@@ -2478,7 +2471,7 @@ string const LyXText::selectNextWordToSpellcheck(BufferView * bview,
                                str += cursor.par()->getChar(i);
                }
        }
-       return str;
+       return WordLangTuple(str, lang_code);
 }
 
 
@@ -2510,7 +2503,7 @@ void LyXText::selectSelectedWord(BufferView * bview)
 // Delete from cursor up to the end of the current or next word.
 void LyXText::deleteWordForward(BufferView * bview)
 {
-       if (!cursor.par()->size())
+       if (cursor.par()->empty())
                cursorRight(bview);
        else {
                LyXCursor tmpcursor = cursor;
@@ -2531,7 +2524,7 @@ void LyXText::deleteWordForward(BufferView * bview)
 // Delete from cursor to start of current or prior word.
 void LyXText::deleteWordBackward(BufferView * bview)
 {
-       if (!cursor.par()->size())
+       if (cursor.par()->empty())
                cursorLeft(bview);
        else {
                LyXCursor tmpcursor = cursor;
@@ -2547,10 +2540,10 @@ void LyXText::deleteWordBackward(BufferView * bview)
 }
 
 
-// Kill to end of line. 
+// Kill to end of line.
 void LyXText::deleteLineForward(BufferView * bview)
 {
-       if (!cursor.par()->size())
+       if (cursor.par()->empty())
                // Paragraph is empty, so we just go to the right
                cursorRight(bview);
        else {
@@ -2611,6 +2604,11 @@ void LyXText::changeRegionCase(BufferView * bview,
        Paragraph * par = from.par();
 
        while (par && (pos != to.pos() || par != to.par())) {
+               if (pos == par->size()) {
+                       par = par->next();
+                       pos = 0;
+                       continue;
+               }
                unsigned char c = par->getChar(pos);
                if (!IsInsetChar(c) && !IsHfillChar(c)) {
                        switch (action) {
@@ -2630,10 +2628,6 @@ void LyXText::changeRegionCase(BufferView * bview,
                checkParagraph(bview, par, pos);
 
                ++pos;
-               if (pos == par->size()) {
-                       par = par->next();
-                       pos = 0;
-               }
        }
        if (to.row() != from.row()) {
                refresh_y = from.y() - from.row()->baseline();
@@ -2785,16 +2779,17 @@ void LyXText::backspace(BufferView * bview)
                // because the user would be confused if the footnote behaves
                // different wether it is open or closed.
 
-               //      Correction: Pasting is always allowed with standard-layout
-               LyXTextClass const & tclass = textclasslist[bview->buffer()->params.textclass];
+               //      Correction: Pasting is always allowed with standard-layout
+               LyXTextClass const & tclass =
+                       bview->buffer()->params.getLyXTextClass();
 
                if (cursor.par() != tmppar
                    && (cursor.par()->layout() == tmppar->layout()
-                       || tmppar->layout() == tclass.defaultLayoutName())
+                       || tmppar->layout() == tclass.defaultLayout())
                    && cursor.par()->getAlign() == tmppar->getAlign()) {
                        removeParagraph(tmprow);
                        removeRow(tmprow);
-                       cursor.par()->pasteParagraph(bview->buffer()->params);
+                       mergeParagraph(bview->buffer()->params, cursor.par());
 
                        if (!cursor.pos() || !cursor.par()->isSeparator(cursor.pos() - 1))
                                ; //cursor.par()->insertChar(cursor.pos(), ' ');
@@ -2819,14 +2814,14 @@ void LyXText::backspace(BufferView * bview)
 
                        // This rebuilds the rows.
                        appendParagraph(bview, cursor.row());
-                       updateCounters(bview, cursor.row());
+                       updateCounters(bview);
 
                        // the row may have changed, block, hfills etc.
                        setCursor(bview, cursor.par(), cursor.pos(), false);
                }
        } else {
                // this is the code for a normal backspace, not pasting
-               // any paragraphs 
+               // any paragraphs
                setUndo(bview, Undo::DELETE,
                        cursor.par(), cursor.par()->next());
                // We used to do cursorLeftIntern() here, but it is
@@ -2854,7 +2849,7 @@ void LyXText::backspace(BufferView * bview)
                int y = cursor.y() - row->baseline();
                pos_type z;
                // remember that a space at the end of a row doesnt count
-               // when calculating the fill 
+               // when calculating the fill
                if (cursor.pos() < rowLast(row) ||
                    !cursor.par()->isLineSeparator(cursor.pos())) {
                        row->fill(row->fill() + singleWidth(bview,
@@ -2863,7 +2858,7 @@ void LyXText::backspace(BufferView * bview)
                }
 
                // some special code when deleting a newline. This is similar
-               // to the behavior when pasting paragraphs 
+               // to the behavior when pasting paragraphs
                if (cursor.pos() && cursor.par()->isNewline(cursor.pos())) {
                        cursor.par()->erase(cursor.pos());
                        // refresh the positions
@@ -2899,7 +2894,7 @@ void LyXText::backspace(BufferView * bview)
                        }
 
                        // delete newlines at the beginning of paragraphs
-                       while (cursor.par()->size() &&
+                       while (!cursor.par()->empty() &&
                               cursor.par()->isNewline(cursor.pos()) &&
                               cursor.pos() == beginningOfMainBody(bview->buffer(),
                                                                   cursor.par())) {
@@ -2966,7 +2961,7 @@ void LyXText::backspace(BufferView * bview)
                        // it can happen that a paragraph loses one row
                        // without a real breakup. This is when a word
                        // is to long to be broken. Well, I don t care this
-                       // hack ;-) 
+                       // hack ;-)
                        if (rowLast(row) == row->par()->size() - 1)
                                removeRow(row->next());
 
@@ -3021,9 +3016,8 @@ void LyXText::backspace(BufferView * bview)
                redoHeightOfParagraph(bview, cursor);
        } else {
                // now the special right address boxes
-               if (textclasslist
-                   [bview->buffer()->params.textclass]
-                   [cursor.par()->layout()].margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+               if (cursor.par()->layout()->margintype
+                   == MARGIN_RIGHT_ADDRESS_BOX) {
                        redoDrawingOfParagraph(bview, cursor);
                }
        }
@@ -3038,7 +3032,7 @@ bool LyXText::paintRowBackground(DrawRowParams & p)
 
        pos_type const last = rowLastPrintable(p.row);
 
-       if (!p.bv->screen()->forceClear() && last == p.row->pos()
+       if (!p.bv->screen().forceClear() && last == p.row->pos()
                && p.row->par()->isInset(p.row->pos())) {
                inset = p.row->par()->getInset(p.row->pos());
                if (inset) {
@@ -3131,38 +3125,31 @@ void LyXText::paintRowSelection(DrawRowParams & p)
                }
                return;
        } else if (startrow != row && endrow != row) {
-               int w = p.width;
-               int h = row->height();
                if (p.y > starty && p.y < endy) {
+                       int w = p.width;
+                       int h = row->height();
                        p.pain->fillRectangle(p.xo, p.yo, w, h, LColor::selection);
                }
                return;
        }
 
-       if (!((startrow != row && !is_rtl) || (endrow != row && is_rtl))) {
-               return;
-       }
-
-       float tmpx = p.x;
-
-       p.pain->fillRectangle(p.xo, p.yo, int(p.x), row->height(), LColor::selection);
+       if ((startrow != row && !is_rtl) || (endrow != row && is_rtl))
+               p.pain->fillRectangle(p.xo, p.yo, int(p.x), row->height(), LColor::selection);
 
        Buffer const * buffer = p.bv->buffer();
        Paragraph * par = row->par();
        pos_type main_body = beginningOfMainBody(buffer, par);
        pos_type const last = rowLastPrintable(row);
+       float tmpx = p.x;
 
        for (pos_type vpos = row->pos(); vpos <= last; ++vpos)  {
                pos_type pos = vis2log(vpos);
                float const old_tmpx = tmpx;
                if (main_body > 0 && pos == main_body - 1) {
-                       LyXLayout const & layout =
-                               textclasslist
-                               [buffer->params.textclass]
-                               [par->layout()];
+                       LyXLayout_ptr const & layout = par->layout();
                        LyXFont const lfont = getLabelFont(buffer, par);
 
-                       tmpx += p.label_hfill + font_metrics::width(layout.labelsep, lfont);
+                       tmpx += p.label_hfill + font_metrics::width(layout->labelsep, lfont);
 
                        if (par->isLineSeparator(main_body - 1))
                                tmpx -= singleWidth(p.bv, par, main_body - 1);
@@ -3191,12 +3178,12 @@ void LyXText::paintRowSelection(DrawRowParams & p)
                                int(tmpx - old_tmpx + 1),
                                row->height(), LColor::selection);
                }
+       }
 
-               if ((startrow != row && is_rtl) || (endrow != row && !is_rtl)) {
-                       p.pain->fillRectangle(p.xo + int(tmpx),
-                               p.yo, int(p.bv->workWidth() - tmpx),
-                               row->height(), LColor::selection);
-               }
+       if ((startrow != row && is_rtl) || (endrow != row && !is_rtl)) {
+               p.pain->fillRectangle(p.xo + int(tmpx),
+                                     p.yo, int(p.bv->workWidth() - tmpx),
+                                     row->height(), LColor::selection);
        }
 }
 
@@ -3284,7 +3271,7 @@ int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
        switch (vsp.kind()) {
        case VSpace::LENGTH:
        {
-               str = prefix + " (" + vsp.asLyXCommand() + ")";
+               str = prefix + " (" + vsp.asLyXCommand() + ')';
                // adding or removing space
                bool const added = !(vsp.length().len().value() < 0.0);
                ty1 = added ? (start + arrow_size) : start;
@@ -3293,8 +3280,8 @@ int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
                by2 = added ? end : (end - arrow_size);
                break;
        }
-       case VSpace:: VFILL:
-               str = prefix + " (vertical fill)";
+       case VSpace::VFILL:
+               str = prefix + _(" (vertical fill)");
                ty1 = ty2 = start;
                by1 = by2 = end;
                break;
@@ -3318,9 +3305,7 @@ int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
 
        p.pain->rectText(leftx + 2 * arrow_size + 5,
                         start + ((end - start) / 2) + d,
-                        str, font,
-                        backgroundColor(),
-                        backgroundColor());
+                        str, font);
 
        // top arrow
        p.pain->line(leftx, ty1, midx, ty2, LColor::added_space);
@@ -3337,6 +3322,30 @@ int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
 }
 
 
+int LyXText::paintPageBreak(string const & label, int y, DrawRowParams & p)
+{
+       LyXFont pb_font;
+       pb_font.setColor(LColor::pagebreak).decSize();
+
+       int w = 0;
+       int a = 0;
+       int d = 0;
+       font_metrics::rectText(label, pb_font, w, a, d);
+
+       int const text_start = p.xo + ((p.width - w) / 2);
+       int const text_end = text_start + w;
+
+       p.pain->rectText(text_start, y + d, label, pb_font);
+
+       p.pain->line(p.xo, y, text_start, y,
+               LColor::pagebreak, Painter::line_onoffdash);
+       p.pain->line(text_end, y, p.xo + p.width, y,
+               LColor::pagebreak, Painter::line_onoffdash);
+
+       return 3 * defaultHeight();
+}
+
+
 void LyXText::paintFirstRow(DrawRowParams & p)
 {
        Paragraph * par = p.row->par();
@@ -3355,22 +3364,8 @@ void LyXText::paintFirstRow(DrawRowParams & p)
 
        // draw a top pagebreak
        if (parparams.pagebreakTop()) {
-               int const y = p.yo + y_top + 2*defaultHeight();
-               p.pain->line(p.xo, y, p.xo + p.width, y,
-                       LColor::pagebreak, Painter::line_onoffdash);
-
-               int w = 0;
-               int a = 0;
-               int d = 0;
-
-               LyXFont pb_font;
-               pb_font.setColor(LColor::pagebreak).decSize();
-               font_metrics::rectText(_("Page Break (top)"), pb_font, w, a, d);
-               p.pain->rectText((p.width - w)/2, y + d,
-                             _("Page Break (top)"), pb_font,
-                             backgroundColor(),
-                             backgroundColor());
-               y_top += 3 * defaultHeight();
+               y_top += paintPageBreak(_("Page Break (top)"),
+                       p.yo + y_top + 2 * defaultHeight(), p);
        }
 
        // draw the additional space if needed:
@@ -3379,20 +3374,19 @@ void LyXText::paintFirstRow(DrawRowParams & p)
 
        Buffer const * buffer = p.bv->buffer();
 
-       LyXTextClass const & tclass = textclasslist[buffer->params.textclass];
-       LyXLayout const & layout = tclass[par->layout()];
+       LyXLayout_ptr const & layout = par->layout();
 
        // think about the parskip
        // some parskips VERY EASY IMPLEMENTATION
        if (buffer->params.paragraph_separation == BufferParams::PARSEP_SKIP) {
                if (par->previous()) {
-                       if (layout.latextype == LATEX_PARAGRAPH
+                       if (layout->latextype == LATEX_PARAGRAPH
                                && !par->getDepth()) {
                                y_top += buffer->params.getDefSkip().inPixels(p.bv);
                        } else {
-                               LyXLayout const & playout =
-                                       tclass[par->previous()->layout()];
-                               if (playout.latextype == LATEX_PARAGRAPH
+                               LyXLayout_ptr const & playout =
+                                       par->previous()->layout();
+                               if (playout->latextype == LATEX_PARAGRAPH
                                        && !par->previous()->getDepth()) {
                                        // is it right to use defskip here, too? (AS)
                                        y_top += buffer->params.getDefSkip().inPixels(p.bv);
@@ -3422,9 +3416,9 @@ void LyXText::paintFirstRow(DrawRowParams & p)
        bool const is_rtl = p.row->par()->isRightToLeftPar(p.bv->buffer()->params);
 
        // should we print a label?
-       if (layout.labeltype >= LABEL_STATIC
-           && (layout.labeltype != LABEL_STATIC
-               || layout.latextype != LATEX_ENVIRONMENT
+       if (layout->labeltype >= LABEL_STATIC
+           && (layout->labeltype != LABEL_STATIC
+               || layout->latextype != LATEX_ENVIRONMENT
                || par->isFirstInSequence())) {
 
                LyXFont font = getLabelFont(buffer, par);
@@ -3435,7 +3429,7 @@ void LyXText::paintFirstRow(DrawRowParams & p)
                        // this is special code for the chapter layout. This is
                        // printed in an extra row and has a pagebreak at
                        // the top.
-                       if (layout.labeltype == LABEL_COUNTER_CHAPTER) {
+                       if (layout->labeltype == LABEL_COUNTER_CHAPTER) {
                                if (buffer->params.secnumdepth >= 0) {
                                        float spacing_val = 1.0;
                                        if (!parparams.spacing().isDefault()) {
@@ -3445,8 +3439,8 @@ void LyXText::paintFirstRow(DrawRowParams & p)
                                        }
 
                                        int const maxdesc =
-                                               int(font_metrics::maxDescent(font) * layout.spacing.getValue() * spacing_val)
-                                               + int(layout.parsep) * defaultHeight();
+                                               int(font_metrics::maxDescent(font) * layout->spacing.getValue() * spacing_val)
+                                               + int(layout->parsep) * defaultHeight();
 
                                        if (is_rtl) {
                                                x = ww - leftMargin(p.bv, p.row) -
@@ -3461,9 +3455,9 @@ void LyXText::paintFirstRow(DrawRowParams & p)
                        } else {
                                if (is_rtl) {
                                        x = ww - leftMargin(p.bv, p.row)
-                                               + font_metrics::width(layout.labelsep, font);
+                                               + font_metrics::width(layout->labelsep, font);
                                } else {
-                                       x = p.x - font_metrics::width(layout.labelsep, font)
+                                       x = p.x - font_metrics::width(layout->labelsep, font)
                                                - font_metrics::width(str, font);
                                }
 
@@ -3473,9 +3467,9 @@ void LyXText::paintFirstRow(DrawRowParams & p)
        // the labels at the top of an environment.
        // More or less for bibliography
        } else if (par->isFirstInSequence() &&
-               (layout.labeltype == LABEL_TOP_ENVIRONMENT ||
-               layout.labeltype == LABEL_BIBLIO ||
-               layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT)) {
+               (layout->labeltype == LABEL_TOP_ENVIRONMENT ||
+               layout->labeltype == LABEL_BIBLIO ||
+               layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT)) {
                LyXFont font = getLabelFont(buffer, par);
                if (!par->getLabelstring().empty()) {
                        string const str = par->getLabelstring();
@@ -3487,11 +3481,11 @@ void LyXText::paintFirstRow(DrawRowParams & p)
                        }
 
                        int maxdesc =
-                               int(font_metrics::maxDescent(font) * layout.spacing.getValue() * spacing_val
-                               + (layout.labelbottomsep * defaultHeight()));
+                               int(font_metrics::maxDescent(font) * layout->spacing.getValue() * spacing_val
+                               + (layout->labelbottomsep * defaultHeight()));
 
                        float x = p.x;
-                       if (layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) {
+                       if (layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) {
                                x = ((is_rtl ? leftMargin(p.bv, p.row) : p.x)
                                         + ww - rightMargin(buffer, p.row)) / 2;
                                x -= font_metrics::width(str, font) / 2;
@@ -3505,14 +3499,14 @@ void LyXText::paintFirstRow(DrawRowParams & p)
                }
        }
 
-       if (layout.labeltype == LABEL_BIBLIO && par->bibkey) {
+       if (layout->labeltype == LABEL_BIBLIO && par->bibkey) {
                LyXFont font = getLayoutFont(buffer, par);
                float x;
                if (is_rtl) {
                        x = ww - leftMargin(p.bv, p.row)
-                               + font_metrics::width(layout.labelsep, font);
+                               + font_metrics::width(layout->labelsep, font);
                } else {
-                       x = p.x - font_metrics::width(layout.labelsep, font)
+                       x = p.x - font_metrics::width(layout->labelsep, font)
                                - par->bibkey->width(p.bv, font);
                }
                par->bibkey->draw(p.bv, font, p.yo + p.row->baseline(), x, p.cleared);
@@ -3534,22 +3528,8 @@ void LyXText::paintLastRow(DrawRowParams & p)
 
        // draw a bottom pagebreak
        if (parparams.pagebreakBottom()) {
-               LyXFont pb_font;
-               pb_font.setColor(LColor::pagebreak).decSize();
-               int const y = p.yo + y_bottom - 2 * defaultHeight();
-
-               p.pain->line(p.xo, y, p.xo + p.width, y, LColor::pagebreak,
-                            Painter::line_onoffdash);
-
-               int w = 0;
-               int a = 0;
-               int d = 0;
-               font_metrics::rectText(_("Page Break (bottom)"), pb_font, w, a, d);
-               p.pain->rectText((ww - w) / 2, y + d,
-                       _("Page Break (bottom)"),
-                       pb_font, backgroundColor(), backgroundColor());
-
-               y_bottom -= 3 * defaultHeight();
+               y_bottom -= paintPageBreak(_("Page Break (bottom)"),
+                       p.yo + y_bottom - 2 * defaultHeight(), p);
        }
 
        // draw the additional space if needed:
@@ -3580,7 +3560,7 @@ void LyXText::paintLastRow(DrawRowParams & p)
        }
 
        bool const is_rtl = p.row->par()->isRightToLeftPar(p.bv->buffer()->params);
-       int const endlabel = par->getEndLabel(buffer->params);
+       int const endlabel = par->getEndLabel();
 
        // draw an endlabel
        switch (endlabel) {
@@ -3605,10 +3585,13 @@ void LyXText::paintLastRow(DrawRowParams & p)
        }
        case END_LABEL_STATIC:
        {
+#if 0
                LyXFont font(LyXFont::ALL_SANE);
-               string const & layout = par->layout();
-               string const str = textclasslist[buffer->params.textclass][layout].endlabelstring();
                font = getLabelFont(buffer, par);
+#else
+               LyXFont font = getLabelFont(buffer, par);
+#endif
+               string const & str = par->layout()->endlabelstring();
                int const x = is_rtl ?
                        int(p.x) - font_metrics::width(str, font)
                        : ww - rightMargin(buffer, p.row) - p.row->fill();
@@ -3620,6 +3603,7 @@ void LyXText::paintLastRow(DrawRowParams & p)
        }
 }
 
+
 void LyXText::paintRowText(DrawRowParams & p)
 {
        Paragraph * par = p.row->par();
@@ -3634,8 +3618,7 @@ void LyXText::paintRowText(DrawRowParams & p)
                main_body = 0;
        }
 
-       LyXLayout const & layout =
-               textclasslist[buffer->params.textclass][par->layout()];
+       LyXLayout_ptr const & layout = par->layout();
 
        pos_type vpos = p.row->pos();
        while (vpos <= last) {
@@ -3648,7 +3631,7 @@ void LyXText::paintRowText(DrawRowParams & p)
                        continue;
                }
                if (main_body > 0 && pos == main_body - 1) {
-                       int const lwidth = font_metrics::width(layout.labelsep,
+                       int const lwidth = font_metrics::width(layout->labelsep,
                                getLabelFont(buffer, par));
 
                        p.x += p.label_hfill + lwidth
@@ -3759,12 +3742,12 @@ int LyXText::defaultHeight() const
 {
        LyXFont font(LyXFont::ALL_SANE);
        return int(font_metrics::maxAscent(font)
-                + font_metrics::maxDescent(font) * 1.5);
+                + font_metrics::maxDescent(font) * 1.5);
 }
 
 
 // returns the column near the specified x-coordinate of the row
-// x is set to the real beginning of this column 
+// x is set to the real beginning of this column
 pos_type
 LyXText::getColumnNearX(BufferView * bview, Row * row, int & x,
                        bool & boundary) const
@@ -3780,9 +3763,9 @@ LyXText::getColumnNearX(BufferView * bview, Row * row, int & x,
        pos_type vc = row->pos();
        pos_type last = rowLastPrintable(row);
        pos_type c = 0;
-       LyXLayout const & layout =
-               textclasslist[bview->buffer()->params.textclass][
-                                   row->par()->layout()];
+
+       LyXLayout_ptr const & layout = row->par()->layout();
+
        bool left_side = false;
 
        pos_type main_body = beginningOfMainBody(bview->buffer(), row->par());
@@ -3798,14 +3781,14 @@ LyXText::getColumnNearX(BufferView * bview, Row * row, int & x,
                last_tmpx = tmpx;
                if (main_body > 0 && c == main_body-1) {
                        tmpx += fill_label_hfill +
-                               font_metrics::width(layout.labelsep,
+                               font_metrics::width(layout->labelsep,
                                               getLabelFont(bview->buffer(), row->par()));
                        if (row->par()->isLineSeparator(main_body - 1))
                                tmpx -= singleWidth(bview, row->par(), main_body-1);
                }
 
                if (hfillExpansion(bview->buffer(), row, c)) {
-                       x += singleWidth(bview, row->par(), c);
+                       tmpx += singleWidth(bview, row->par(), c);
                        if (c >= main_body)
                                tmpx += fill_hfill;
                        else
@@ -3930,17 +3913,10 @@ Row * LyXText::getRowNearY(int & y) const
 
        if (y < tmpy) {
                lyxerr << "up" << endl;
-#if 0
-               while (tmprow && tmpy - tmprow->height() >= y) {
-                       tmpy -= tmprow->height();
-                       tmprow = tmprow->previous();
-               }
-#else
                do {
                        tmpy -= tmprow->height();
                        tmprow = tmprow->previous();
                } while (tmprow && tmpy - tmprow->height() >= y);
-#endif
        } else if (y > tmpy) {
                lyxerr << "down" << endl;