]> git.lyx.org Git - lyx.git/blobdiff - src/text.C
Lars says _(_(b)) is a bug ... fix
[lyx.git] / src / text.C
index b8078303abdd54b349bcc788de58448375cc5807..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 "LyXView.h"
-#include "Painter.h"
-#include "tracer.h"
-#include "font.h"
 #include "encoding.h"
-#include "lyxscreen.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 "font.h"
+#include "WordLangTuple.h"
+#include "paragraph_funcs.h"
 
 #include "insets/insetbib.h"
 #include "insets/insettext.h"
@@ -80,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;
@@ -92,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)
@@ -150,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);
@@ -214,11 +216,11 @@ int LyXText::singleWidth(BufferView * bview, Paragraph * par,
                                 Encodings::IsComposeChar_hebrew(c))
                                return 0;
                }
-               return lyxfont::width(c, font);
+               return font_metrics::width(c, font);
 
        } else if (IsHfillChar(c)) {
-               return 3;       /* 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);
                if (tmpinset) {
@@ -236,7 +238,7 @@ int LyXText::singleWidth(BufferView * bview, Paragraph * par,
                c = ' ';
        else if (IsNewlineChar(c))
                c = 'n';
-       return lyxfont::width(c, font);
+       return font_metrics::width(c, font);
 }
 
 
@@ -283,6 +285,13 @@ void LyXText::computeBidiTables(Buffer const * buf, Row * row) const
                return;
        }
 
+       Inset * inset = row->par()->inInset();
+       if (inset && inset->owner() &&
+           inset->owner()->lyxCode() == Inset::ERT_CODE) {
+               bidi_start = -1;
+               return;
+       }
+
        bidi_start = row->pos();
        bidi_end = rowLastPrintable(row);
 
@@ -306,14 +315,13 @@ void LyXText::computeBidiTables(Buffer const * buf, Row * row) const
 
        pos_type stack[2];
        bool const rtl_par =
-               row->par()->getParLanguage(buf->params)->RightToLeft();
+               row->par()->isRightToLeftPar(buf->params);
        int level = 0;
        bool rtl = false;
        bool rtl0 = false;
        pos_type const main_body = beginningOfMainBody(buf, row->par());
 
-       for (pos_type lpos = bidi_start;
-            lpos <= bidi_end; ++lpos) {
+       for (pos_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
                bool is_space = row->par()->isLineSeparator(lpos);
                pos_type const pos =
                        (is_space && lpos + 1 <= bidi_end &&
@@ -429,12 +437,13 @@ bool LyXText::isBoundary(Buffer const * buf, Paragraph * par,
        return rtl != rtl2;
 }
 
+
 void LyXText::drawNewline(DrawRowParams & p, pos_type const pos)
 {
        // Draw end-of-line marker
        LyXFont const font = getFont(p.bv->buffer(), p.row->par(), pos);
-       int const wid = lyxfont::width('n', font);
-       int const asc = lyxfont::maxAscent(font);
+       int const wid = font_metrics::width('n', font);
+       int const asc = font_metrics::maxAscent(font);
        int const y = p.yo + p.row->baseline();
        int xp[3];
        int yp[3];
@@ -541,7 +550,7 @@ void LyXText::drawHebrewComposeChar(DrawRowParams & p, pos_type & vpos)
        ++vpos;
 
        LyXFont const & font = getFont(p.bv->buffer(), p.row->par(), pos);
-       int const width = lyxfont::width(c, font);
+       int const width = font_metrics::width(c, font);
        int dx = 0;
 
        for (pos_type i = pos-1; i >= 0; --i) {
@@ -576,7 +585,7 @@ void LyXText::drawArabicComposeChar(DrawRowParams & p, pos_type & vpos)
        ++vpos;
 
        LyXFont const & font = getFont(p.bv->buffer(), p.row->par(), pos);
-       int const width = lyxfont::width(c, font);
+       int const width = font_metrics::width(c, font);
        int dx = 0;
 
        for (pos_type i = pos-1; i >= 0; --i) {
@@ -626,13 +635,15 @@ 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;
        }
 
        // Draw text and set the new x position
        p.pain->text(int(p.x), p.yo + p.row->baseline(), str, orig_font);
-       p.x += lyxfont::width(str, orig_font);
+       p.x += font_metrics::width(str, orig_font);
 }
 
 
@@ -672,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) {
@@ -681,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;
@@ -705,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 += lyxfont::signedWidth(tclass.leftmargin(), tclass.defaultfont());
+       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());
@@ -750,68 +749,70 @@ 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 += lyxfont::signedWidth(layout.leftmargin,
+               if (!layout->leftmargin.empty()) {
+                       x += font_metrics::signedWidth(layout->leftmargin,
                                                  tclass.defaultfont());
                }
                if (!row->par()->getLabelstring().empty()) {
-                       x += lyxfont::signedWidth(layout.labelindent,
+                       x += font_metrics::signedWidth(layout->labelindent,
                                                  labelfont);
-                       x += lyxfont::width(row->par()->getLabelstring(),
+                       x += font_metrics::width(row->par()->getLabelstring(),
                                            labelfont);
-                       x += lyxfont::width(layout.labelsep, labelfont);
+                       x += font_metrics::width(layout->labelsep, labelfont);
                }
                break;
        case MARGIN_MANUAL:
-               x += lyxfont::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 += lyxfont::width(row->par()->getLabelWidthString(),
+                               x += font_metrics::width(row->par()->getLabelWidthString(),
                                               labelfont);
-                               x += lyxfont::width(layout.labelsep, labelfont);
+                               x += font_metrics::width(layout->labelsep, labelfont);
                        }
                }
                break;
        case MARGIN_STATIC:
-               x += lyxfont::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 += lyxfont::signedWidth(layout.leftmargin,
+                               x += font_metrics::signedWidth(layout->leftmargin,
                                                          labelfont);
                        } else {
-                               x += lyxfont::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 += lyxfont::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 += lyxfont::signedWidth(layout.labelindent,
+                       x += font_metrics::signedWidth(layout->labelindent,
                                                  labelfont);
-                       x += lyxfont::width(layout.labelsep, labelfont);
-                       x += lyxfont::width(row->par()->getLabelstring(),
+                       x += font_metrics::width(layout->labelsep, labelfont);
+                       x += font_metrics::width(row->par()->getLabelstring(),
                                            labelfont);
                }
                break;
@@ -835,27 +836,36 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                                minfill = tmprow->fill();
                }
 
-               x += lyxfont::signedWidth(layout.leftmargin,
-                                         tclass.defaultfont());
+               x += font_metrics::signedWidth(layout->leftmargin,
+                       tclass.defaultfont());
                x += minfill;
        }
        break;
        }
 
+       if ((workWidth(bview) > 0) &&
+               !row->par()->params().leftIndent().zero())
+       {
+               LyXLength const len = row->par()->params().leftIndent();
+               int const tw = inset_owner ?
+                       inset_owner->latexTextWidth(bview) : workWidth(bview);
+               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()
@@ -863,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 += lyxfont::signedWidth(parindent,
+                       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());
                }
@@ -886,11 +896,11 @@ 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
-               + lyxfont::signedWidth(tclass.rightmargin(),
+               + font_metrics::signedWidth(tclass.rightmargin(),
                                       tclass.defaultfont());
 
        // this is the way, LyX handles the LaTeX-Environments.
@@ -909,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);
@@ -924,7 +934,8 @@ int LyXText::rightMargin(Buffer const * buf, Row const * row) const
        }
 
        //lyxerr << "rightmargin: " << layout->rightmargin << endl;
-       x += lyxfont::signedWidth(layout.rightmargin, tclass.defaultfont())
+       x += font_metrics::signedWidth(layout->rightmargin,
+                                      tclass.defaultfont())
                * 4 / (row->par()->getDepth() + 4);
        return x;
 }
@@ -932,17 +943,17 @@ 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());
-               return leftMargin(bview, &tmprow);  /* just the beginning
-                                               of the main body */
-       } else
-               return 0;  /* LabelEnd is only needed, if the
-                             layout fills a flushleft
-                             label. */
+               // 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;
+       }
 }
 
 
@@ -964,12 +975,12 @@ 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) {
-               /* special code for right address boxes, only newlines count */
+       if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+               // special code for right address boxes, only newlines count
                while (i < par->size()) {
                        if (par->isNewline(i)) {
                                last_separator = i;
@@ -983,8 +994,7 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
                }
        } else {
                // Last position is an invariant
-               pos_type const last =
-                       par->size();
+               pos_type const last = par->size();
                // this is the usual handling
                int x = leftMargin(bview, row);
                bool doitonetime = true;
@@ -1002,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
@@ -1041,7 +1051,7 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
                        }
                        ++i;
                        if (i == main_body) {
-                               x += lyxfont::width(layout.labelsep,
+                               x += font_metrics::width(layout->labelsep,
                                                    getLabelFont(bview->buffer(), par));
                                if (par->isLineSeparator(i - 1))
                                        x-= singleWidth(bview, par, i - 1);
@@ -1084,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);
@@ -1094,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 += lyxfont::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);
@@ -1112,7 +1121,7 @@ int LyXText::fill(BufferView * bview, Row * row, int paper_width) const
                ++i;
        }
        if (main_body > 0 && main_body > last) {
-               w += lyxfont::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);
@@ -1139,8 +1148,8 @@ int LyXText::labelFill(BufferView * bview, Row const * row) const
        // environment with a manual label. (Asger)
        if (last < 0) last = 0;
 
-       if (row->par()->isLineSeparator(last)) /* a sepearator at this end
-                                               does not count */
+       // a separator at this end does not count
+       if (row->par()->isLineSeparator(last))
                --last;
 
        int w = 0;
@@ -1152,7 +1161,7 @@ int LyXText::labelFill(BufferView * bview, Row const * row) const
 
        int fill = 0;
        if (!row->par()->params().labelWidthString().empty()) {
-               fill = max(lyxfont::width(row->par()->params().labelWidthString(),
+               fill = max(font_metrics::width(row->par()->params().labelWidthString(),
                                          getLabelFont(bview->buffer(), row->par())) - w,
                           0);
        }
@@ -1186,8 +1195,8 @@ int LyXText::numberOfHfills(Buffer const * buf, Row const * row) const
        pos_type const last = rowLast(row);
        pos_type first = row->pos();
 
-       if (first) { /* hfill *DO* count at the beginning
-                     * of paragraphs! */
+       if (first) {
+               // hfill *DO* count at the beginning of paragraphs!
                while (first <= last && row->par()->isHfill(first)) {
                        ++first;
                }
@@ -1211,8 +1220,8 @@ int LyXText::numberOfLabelHfills(Buffer const * buf, Row const * row) const
 {
        pos_type last = rowLast(row);
        pos_type first = row->pos();
-       if (first) { /* hfill *DO* count at the beginning
-                     * of paragraphs! */
+       if (first) {
+               // hfill *DO* count at the beginning of paragraphs!
                while (first < last && row->par()->isHfill(first))
                        ++first;
        }
@@ -1256,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;
 
@@ -1283,7 +1291,7 @@ LColor::color LyXText::backgroundColor()
 
 void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
 {
-       /* get the maximum ascent and the maximum descent */
+       // get the maximum ascent and the maximum descent
        int asc = 0;
        int desc = 0;
        float layoutasc = 0;
@@ -1292,17 +1300,17 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
        LyXFont tmpfont;
        Inset * tmpinset = 0;
 
-       /* 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 */
+       // 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
 
-       /* Correction: only the fontsize count. The other properties
-          are taken from the layoutfont. Nicer on the screen :) */
+       // Correction: only the fontsize count. The other properties
+       //  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
@@ -1323,12 +1331,13 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
        }
        //lyxerr << "spacing_val = " << spacing_val << endl;
 
-       int maxasc = int(lyxfont::maxAscent(font) *
-                        layout.spacing.getValue() *
+       int maxasc = int(font_metrics::maxAscent(font) *
+                        layout->spacing.getValue() *
                         spacing_val);
-       int maxdesc = int(lyxfont::maxDescent(font) *
-                         layout.spacing.getValue() *
+       int maxdesc = int(font_metrics::maxDescent(font) *
+                         layout->spacing.getValue() *
                          spacing_val);
+
        pos_type const pos_end = rowLast(row_ptr);
        int labeladdon = 0;
        int maxwidth = 0;
@@ -1361,8 +1370,8 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
        if (maxsize > font.size()) {
                font.setSize(maxsize);
 
-               asc = lyxfont::maxAscent(font);
-               desc = lyxfont::maxDescent(font);
+               asc = font_metrics::maxAscent(font);
+               desc = font_metrics::maxDescent(font);
                if (asc > maxasc)
                        maxasc = asc;
                if (desc > maxdesc)
@@ -1382,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)
@@ -1406,16 +1415,16 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                // do not forget the DTP-lines!
                // there height depends on the font of the nearest character
                if (firstpar->params().lineTop())
-                       maxasc += 2 * lyxfont::ascent('x', getFont(bview->buffer(),
-                                                                  firstpar, 0));
 
+                       maxasc += 2 * font_metrics::ascent('x', getFont(bview->buffer(),
+                                       firstpar, 0));
                // and now the pagebreaks
                if (firstpar->params().pagebreakTop())
                        maxasc += 3 * defaultHeight();
 
                // 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;
@@ -1425,18 +1434,18 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                                spacing_val = bview->buffer()->params.spacing.getValue();
                        }
 
-                       labeladdon = int(lyxfont::maxDescent(labelfont) *
-                                        layout.spacing.getValue() *
+                       labeladdon = int(font_metrics::maxDescent(labelfont) *
+                                        layout->spacing.getValue() *
                                         spacing_val)
-                               + int(lyxfont::maxAscent(labelfont) *
-                                     layout.spacing.getValue() *
+                               + int(font_metrics::maxAscent(labelfont) *
+                                     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())
                {
@@ -1448,14 +1457,14 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                        }
 
                        labeladdon = int(
-                               (lyxfont::maxAscent(labelfont) *
-                                layout.spacing.getValue() *
+                               (font_metrics::maxAscent(labelfont) *
+                                layout->spacing.getValue() *
                                 spacing_val)
-                               +(lyxfont::maxDescent(labelfont) *
-                                 layout.spacing.getValue() *
+                               +(font_metrics::maxDescent(labelfont) *
+                                 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,
@@ -1469,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());
@@ -1487,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 &&
@@ -1496,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());
                                }
                        }
                }
@@ -1516,7 +1525,7 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                // do not forget the DTP-lines!
                // there height depends on the font of the nearest character
                if (firstpar->params().lineBottom())
-                       maxdesc += 2 * lyxfont::ascent('x',
+                       maxdesc += 2 * font_metrics::ascent('x',
                                                       getFont(bview->buffer(),
                                                               par,
                                                               max(pos_type(0), par->size() - 1)));
@@ -1536,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;
@@ -1553,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());
                        }
                }
        }
@@ -1570,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);
@@ -1589,8 +1598,8 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
 }
 
 
-/* Appends the implicit specified paragraph behind the specified row,
- * start at the implicit given position */
+// Appends the implicit specified paragraph behind the specified row,
+// start at the implicit given position
 void LyXText::appendParagraph(BufferView * bview, Row * row) const
 {
        bool not_ready = true;
@@ -1650,8 +1659,8 @@ void LyXText::breakAgain(BufferView * bview, Row * row) const
                                }
                        }
                } else {
-                       /* if there are some rows too much, delete them */
-                       /* only if you broke the whole paragraph! */
+                       // if there are some rows too much, delete them
+                       // only if you broke the whole paragraph!
                        Row * tmprow2 = row;
                        while (tmprow2->next() && tmprow2->next()->par() == row->par()) {
                                tmprow2 = tmprow2->next();
@@ -1663,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);
@@ -1680,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();
@@ -1714,92 +1723,99 @@ 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()];
-
-   // 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)
-          return;
-
-   setUndo(bview, Undo::FINISH, cursor.par(), cursor.par()->next());
-
-   // Always break behind a space
-   //
-   // It is better to erase the space (Dekel)
-   if (cursor.pos() < cursor.par()->size()
-       && cursor.par()->isLineSeparator(cursor.pos()))
+               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()->empty()
+          && layout->labeltype != LABEL_SENSITIVE
+          && !layout->keepempty)
+               return;
+
+       setUndo(bview, Undo::FINISH, cursor.par(), cursor.par()->next());
+
+       // Always break behind a space
+       //
+       // It is better to erase the space (Dekel)
+       if (cursor.pos() < cursor.par()->size()
+            && cursor.par()->isLineSeparator(cursor.pos()))
           cursor.par()->erase(cursor.pos());
-          // cursor.pos(cursor.pos() + 1);
-
-   // break the paragraph
-   if (keep_layout)
-     keep_layout = 2;
-   else
-     keep_layout = layout.isEnvironment();
-   cursor.par()->breakParagraph(bview->buffer()->params, cursor.pos(),
-                               keep_layout);
-
-   // well this is the caption hack since one caption is really enough
-   if (layout.labeltype == LABEL_SENSITIVE) {
-     if (!cursor.pos())
-            // set to standard-layout
-            cursor.par()->applyLayout(tclass.defaultLayoutName());
-     else
-            // set to standard-layout
-            cursor.par()->next()->applyLayout(tclass.defaultLayoutName());
-   }
-
-   /* 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 */
-   if (cursor.pos() && !cursor.row()->par()->isNewline(cursor.row()->pos() - 1)
-       && cursor.row()->pos() == cursor.pos())
-   {
-          cursorLeft(bview);
-   }
-
-   status(bview, LyXText::NEED_MORE_REFRESH);
-   refresh_row = cursor.row();
-   refresh_y = cursor.y() - cursor.row()->baseline();
-
-   // Do not forget the special right address boxes
-   if (layout.margintype == MARGIN_RIGHT_ADDRESS_BOX) {
-      while (refresh_row->previous() &&
-            refresh_row->previous()->par() == refresh_row->par()) {
-             refresh_row = refresh_row->previous();
-             refresh_y -= refresh_row->height();
-      }
-   }
-   removeParagraph(cursor.row());
-
-   // set the dimensions of the cursor row
-   cursor.row()->fill(fill(bview, cursor.row(), workWidth(bview)));
-
-   setHeightOfRow(bview, cursor.row());
-
-   while (cursor.par()->next()->size()
+       // cursor.pos(cursor.pos() + 1);
+
+       // break the paragraph
+       if (keep_layout)
+               keep_layout = 2;
+       else
+               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()->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 (!cursor.pos())
+                       // set to standard-layout
+                       cursor.par()->applyLayout(tclass.defaultLayout());
+               else
+                       // set to standard-layout
+                       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
+       if (cursor.pos() && !cursor.row()->par()->isNewline(cursor.row()->pos() - 1)
+                        && cursor.row()->pos() == cursor.pos())
+       {
+               cursorLeft(bview);
+       }
+
+       status(bview, LyXText::NEED_MORE_REFRESH);
+       refresh_row = cursor.row();
+       refresh_y = cursor.y() - cursor.row()->baseline();
+
+       // Do not forget the special right address boxes
+       if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+               while (refresh_row->previous() &&
+                      refresh_row->previous()->par() == refresh_row->par())
+               {
+                       refresh_row = refresh_row->previous();
+                       refresh_y -= refresh_row->height();
+               }
+       }
+       removeParagraph(cursor.row());
+
+       // set the dimensions of the cursor row
+       cursor.row()->fill(fill(bview, cursor.row(), workWidth(bview)));
+
+       setHeightOfRow(bview, cursor.row());
+
+       while (!cursor.par()->next()->empty()
          && cursor.par()->next()->isNewline(0))
           cursor.par()->next()->erase(0);
 
-   insertParagraph(bview, cursor.par()->next(), cursor.row());
+       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! */
-   if (cursor.pos() || layout.keepempty)
-          setCursor(bview, cursor.par()->next(), 0);
-   else
-          setCursor(bview, cursor.par(), 0);
+       // This check is necessary. Otherwise the new empty paragraph will
+       // be deleted automatically. And it is more friendly for the user!
+       if (cursor.pos() || isempty)
+               setCursor(bview, cursor.par()->next(), 0);
+       else
+               setCursor(bview, cursor.par(), 0);
 
-   if (cursor.row()->next())
-          breakAgain(bview, cursor.row()->next());
+       if (cursor.row()->next())
+               breakAgain(bview, cursor.row()->next());
 
-   need_break_row = 0;
+       need_break_row = 0;
 }
 
 
@@ -1812,8 +1828,8 @@ 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 */
+// insert a character, moves all the following breaks in the
+// 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());
@@ -1821,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) {
@@ -1873,11 +1888,11 @@ void LyXText::insertChar(BufferView * bview, char c)
        }
 
 
-       /* First check, if there will be two blanks together or a blank at
-         the beginning of a paragraph.
-         I decided to handle blanks like normal characters, the main
-         difference are the special checks when calculating the row.fill
-         (blank does not count at the end of a row) and the check here */
+       // First check, if there will be two blanks together or a blank at
+       // the beginning of a paragraph.
+       // I decided to handle blanks like normal characters, the main
+       // difference are the special checks when calculating the row.fill
+       // (blank does not count at the end of a row) and the check here
 
        // The bug is triggered when we type in a description environment:
        // The current_font is not changed when we go from label to main text
@@ -1885,11 +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;  /* store the current font.
-                                    * This is because of the use
-                                    * of cursor movements. The moving
-                                    * cursor would refresh the
-                                    * 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
 
        // Get the font that is used to calculate the baselineskip
        pos_type const lastpos = cursor.par()->size();
@@ -1923,9 +1936,8 @@ void LyXText::insertChar(BufferView * bview, char c)
                        charInserted();
                        return;
                }
-               /* No newline at first position
-                * of a paragraph or behind labels.
-                * TeX does not allow that */
+               // No newline at first position of a paragraph or behind labels.
+               // TeX does not allow that
 
                if (cursor.pos() < cursor.par()->size() &&
                    cursor.par()->isLineSeparator(cursor.pos()))
@@ -1946,9 +1958,10 @@ void LyXText::insertChar(BufferView * bview, char c)
        // get the cursor row fist
        Row * row = cursor.row();
        int y = cursor.y() - row->baseline();
-       if (c != Paragraph::META_INSET) /* Here case LyXText::InsertInset
-                                        * already insertet the character */
+       if (c != Paragraph::META_INSET) {
+               // Here case LyXText::InsertInset  already insertet the character
                cursor.par()->insertChar(cursor.pos(), c);
+       }
        setCharFont(bview->buffer(), cursor.par(), cursor.pos(), rawtmpfont);
 
        if (!jumped_over_space) {
@@ -2010,15 +2023,15 @@ void LyXText::insertChar(BufferView * bview, char c)
        }
 
        // recalculate the fill of the row
-       if (row->fill() >= 0)  /* needed because a newline
-                               * will set fill to -1. Otherwise
-                               * we would not get a rebreak! */
+       if (row->fill() >= 0) {
+               // needed because a newline will set fill to -1. Otherwise
+               // 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?
@@ -2043,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);
@@ -2066,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);
                }
@@ -2116,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()) {
@@ -2142,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();
                }
@@ -2197,7 +2207,7 @@ void LyXText::prepareToPrint(BufferView * bview,
                if (main_body > 0 &&
                    (main_body - 1 > last ||
                     !row->par()->isLineSeparator(main_body - 1))) {
-                       x += lyxfont::width(layout.labelsep,
+                       x += font_metrics::width(layout->labelsep,
                                            getLabelFont(bview->buffer(), row->par()));
                        if (main_body - 1 <= last)
                                x += fill_label_hfill;
@@ -2205,12 +2215,13 @@ 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 */
+
+// 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
 
 void LyXText::cursorRightOneWord(BufferView * bview) const
 {
@@ -2246,25 +2257,24 @@ void LyXText::cursorRightOneWord(BufferView * bview) const
 
 void LyXText::cursorTab(BufferView * bview) const
 {
-    LyXCursor tmpcursor = cursor;
-    while (tmpcursor.pos() < tmpcursor.par()->size()
+       LyXCursor tmpcursor = cursor;
+       while (tmpcursor.pos() < tmpcursor.par()->size()
           && !tmpcursor.par()->isNewline(tmpcursor.pos()))
        tmpcursor.pos(tmpcursor.pos() + 1);
 
-    if (tmpcursor.pos() == tmpcursor.par()->size()) {
-       if (tmpcursor.par()->next()) {
-           tmpcursor.par(tmpcursor.par()->next());
-           tmpcursor.pos(0);
-       }
-    } else
-       tmpcursor.pos(tmpcursor.pos() + 1);
-    setCursor(bview, tmpcursor.par(), tmpcursor.pos());
+       if (tmpcursor.pos() == tmpcursor.par()->size()) {
+               if (tmpcursor.par()->next()) {
+                       tmpcursor.par(tmpcursor.par()->next());
+                       tmpcursor.pos(0);
+               }
+       } else
+               tmpcursor.pos(tmpcursor.pos() + 1);
+       setCursor(bview, tmpcursor.par(), tmpcursor.pos());
 }
 
 
-/* -------> Skip initial whitespace at end of word and move cursor to *start*
-           of prior word, not to end of next prior word. */
-
+// Skip initial whitespace at end of word and move cursor to *start*
+// of prior word, not to end of next prior word.
 void LyXText::cursorLeftOneWord(BufferView * bview)  const
 {
        LyXCursor tmpcursor = cursor;
@@ -2272,7 +2282,8 @@ void LyXText::cursorLeftOneWord(BufferView * bview)  const
        setCursor(bview, tmpcursor.par(), tmpcursor.pos());
 }
 
-void LyXText::cursorLeftOneWord(LyXCursor  & cur)  const
+
+void LyXText::cursorLeftOneWord(LyXCursor & cur) const
 {
        // treat HFills, floats and Insets as words
        cur = cursor;
@@ -2294,13 +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. */
+
+// Select current word. This depends on behaviour of
+// CursorLeftOneWord(), so it is patched as well.
 void LyXText::getWord(LyXCursor & from, LyXCursor & to,
                      word_location const loc) const
 {
@@ -2311,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;
                }
@@ -2338,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);
        }
@@ -2360,8 +2373,8 @@ void LyXText::selectWord(BufferView * bview, word_location const loc)
 }
 
 
-/* -------> Select the word currently under the cursor when no
-       selection is currently set */
+// Select the word currently under the cursor when no
+// selection is currently set
 bool LyXText::selectWordWhenUnderCursor(BufferView * bview,
                                        word_location const loc)
 {
@@ -2375,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
@@ -2439,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()
@@ -2454,7 +2471,7 @@ string const LyXText::selectNextWordToSpellcheck(BufferView * bview,
                                str += cursor.par()->getChar(i);
                }
        }
-       return str;
+       return WordLangTuple(str, lang_code);
 }
 
 
@@ -2483,10 +2500,10 @@ void LyXText::selectSelectedWord(BufferView * bview)
 }
 
 
-/* -------> Delete from cursor up to the end of the current or next word. */
+// 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;
@@ -2498,35 +2515,35 @@ void LyXText::deleteWordForward(BufferView * bview)
                cursor = tmpcursor;
                setSelection(bview);
 
-               /* -----> Great, CutSelection() gets rid of multiple spaces. */
+               // Great, CutSelection() gets rid of multiple spaces.
                cutSelection(bview, true, false);
        }
 }
 
 
-/* -------> Delete from cursor to start of current or prior word. */
+// Delete from cursor to start of current or prior word.
 void LyXText::deleteWordBackward(BufferView * bview)
 {
-       if (!cursor.par()->size())
-              cursorLeft(bview);
-       else {
-              LyXCursor tmpcursor = cursor;
-              tmpcursor.row(0); // ??
-              selection.set(true); // to avoid deletion
-              cursorLeftOneWord(bview);
-              setCursor(bview, tmpcursor, tmpcursor.par(), tmpcursor.pos());
-              selection.cursor = cursor;
-              cursor = tmpcursor;
-              setSelection(bview);
-              cutSelection(bview, true, false);
-       }
+       if (cursor.par()->empty())
+               cursorLeft(bview);
+       else {
+               LyXCursor tmpcursor = cursor;
+               tmpcursor.row(0); // ??
+               selection.set(true); // to avoid deletion
+               cursorLeftOneWord(bview);
+               setCursor(bview, tmpcursor, tmpcursor.par(), tmpcursor.pos());
+               selection.cursor = cursor;
+               cursor = tmpcursor;
+               setSelection(bview);
+               cutSelection(bview, true, false);
+       }
 }
 
 
-/* -------> 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 {
@@ -2587,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) {
@@ -2606,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();
@@ -2753,25 +2771,25 @@ void LyXText::backspace(BufferView * bview)
                                        false);
                }
 
-               /* Pasting is not allowed, if the paragraphs have different
-                  layout. I think it is a real bug of all other
-                  word processors to allow it. It confuses the user.
-                  Even so with a footnote paragraph and a non-footnote
-                  paragraph. I will not allow pasting in this case,
-                  because the user would be confused if the footnote behaves
-                  different wether it is open or closed.
+               // Pasting is not allowed, if the paragraphs have different
+               // layout. I think it is a real bug of all other
+               // word processors to allow it. It confuses the user.
+               // Even so with a footnote paragraph and a non-footnote
+               // paragraph. I will not allow pasting in this case,
+               // 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(), ' ');
@@ -2796,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 */
+               // this is the code for a normal backspace, not pasting
+               // any paragraphs
                setUndo(bview, Undo::DELETE,
                        cursor.par(), cursor.par()->next());
                // We used to do cursorLeftIntern() here, but it is
@@ -2830,8 +2848,8 @@ void LyXText::backspace(BufferView * bview)
                Row * row = cursor.row();
                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 */
+               // remember that a space at the end of a row doesnt count
+               // when calculating the fill
                if (cursor.pos() < rowLast(row) ||
                    !cursor.par()->isLineSeparator(cursor.pos())) {
                        row->fill(row->fill() + singleWidth(bview,
@@ -2839,8 +2857,8 @@ void LyXText::backspace(BufferView * bview)
                                                            cursor.pos()));
                }
 
-               /* some special code when deleting a newline. This is similar
-                * to the behavior when pasting paragraphs */
+               // some special code when deleting a newline. This is similar
+               // to the behavior when pasting paragraphs
                if (cursor.pos() && cursor.par()->isNewline(cursor.pos())) {
                        cursor.par()->erase(cursor.pos());
                        // refresh the positions
@@ -2876,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())) {
@@ -2940,10 +2958,10 @@ void LyXText::backspace(BufferView * bview)
                    (rowLast(row) == row->par()->size() - 1 ||
                     nextBreakPoint(bview, row, workWidth(bview)) != rowLast(row))) {
 
-                       /* 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 ;-) */
+                       // 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 ;-)
                        if (rowLast(row) == row->par()->size() - 1)
                                removeRow(row->next());
 
@@ -2998,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);
                }
        }
@@ -3015,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) {
@@ -3108,39 +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 + lyxfont::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);
@@ -3169,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);
        }
 }
 
@@ -3236,8 +3245,8 @@ int LyXText::getLengthMarkerHeight(BufferView * bv, VSpace const & vsp) const
        LyXFont font;
        font.decSize();
        int const min_size = max(3 * arrow_size,
-                                     lyxfont::maxAscent(font)
-                                     + lyxfont::maxDescent(font));
+                                     font_metrics::maxAscent(font)
+                                     + font_metrics::maxDescent(font));
 
        if (vsp.length().len().value() < 0.0)
                return min_size;
@@ -3262,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;
@@ -3271,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;
@@ -3292,13 +3301,11 @@ int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
 
        LyXFont font;
        font.setColor(LColor::added_space).decSize();
-       lyxfont::rectText(str, font, w, a, d);
+       font_metrics::rectText(str, font, w, a, d);
 
        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);
@@ -3315,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();
@@ -3333,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();
-               lyxfont::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:
@@ -3357,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);
@@ -3384,7 +3400,7 @@ void LyXText::paintFirstRow(DrawRowParams & p)
        // draw a top line
        if (parparams.lineTop()) {
                LyXFont font(LyXFont::ALL_SANE);
-               int const asc = lyxfont::ascent('x', getFont(buffer, par, 0));
+               int const asc = font_metrics::ascent('x', getFont(buffer, par, 0));
 
                y_top += asc;
 
@@ -3400,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);
@@ -3413,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()) {
@@ -3423,12 +3439,12 @@ void LyXText::paintFirstRow(DrawRowParams & p)
                                        }
 
                                        int const maxdesc =
-                                               int(lyxfont::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) -
-                                                       lyxfont::width(str, font);
+                                                       font_metrics::width(str, font);
                                        }
 
                                        p.pain->text(int(x),
@@ -3439,10 +3455,10 @@ void LyXText::paintFirstRow(DrawRowParams & p)
                        } else {
                                if (is_rtl) {
                                        x = ww - leftMargin(p.bv, p.row)
-                                               + lyxfont::width(layout.labelsep, font);
+                                               + font_metrics::width(layout->labelsep, font);
                                } else {
-                                       x = p.x - lyxfont::width(layout.labelsep, font)
-                                               - lyxfont::width(str, font);
+                                       x = p.x - font_metrics::width(layout->labelsep, font)
+                                               - font_metrics::width(str, font);
                                }
 
                                p.pain->text(int(x), p.yo + p.row->baseline(), str, font);
@@ -3451,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();
@@ -3465,17 +3481,17 @@ void LyXText::paintFirstRow(DrawRowParams & p)
                        }
 
                        int maxdesc =
-                               int(lyxfont::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 -= lyxfont::width(str, font) / 2;
+                               x -= font_metrics::width(str, font) / 2;
                        } else if (is_rtl) {
                                x = ww - leftMargin(p.bv, p.row) -
-                                       lyxfont::width(str, font);
+                                       font_metrics::width(str, font);
                        }
                        p.pain->text(int(x), p.yo + p.row->baseline()
                                  - p.row->ascent_of_text() - maxdesc,
@@ -3483,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)
-                               + lyxfont::width(layout.labelsep, font);
+                               + font_metrics::width(layout->labelsep, font);
                } else {
-                       x = p.x - lyxfont::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);
@@ -3512,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;
-               lyxfont::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:
@@ -3542,7 +3544,7 @@ void LyXText::paintLastRow(DrawRowParams & p)
        // draw a bottom line
        if (parparams.lineBottom()) {
                LyXFont font(LyXFont::ALL_SANE);
-               int const asc = lyxfont::ascent('x',
+               int const asc = font_metrics::ascent('x',
                        getFont(buffer, par,
                        max(pos_type(0), par->size() - 1)));
 
@@ -3558,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) {
@@ -3566,7 +3568,7 @@ void LyXText::paintLastRow(DrawRowParams & p)
        case END_LABEL_FILLED_BOX:
        {
                LyXFont const font = getLabelFont(buffer, par);
-               int const size = int(0.75 * lyxfont::maxAscent(font));
+               int const size = int(0.75 * font_metrics::maxAscent(font));
                int const y = (p.yo + p.row->baseline()) - size;
                int x = is_rtl ? LYX_PAPER_MARGIN : ww - LYX_PAPER_MARGIN - size;
 
@@ -3583,12 +3585,15 @@ 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) - lyxfont::width(str, font)
+                       int(p.x) - font_metrics::width(str, font)
                        : ww - rightMargin(buffer, p.row) - p.row->fill();
                p.pain->text(x, p.yo + p.row->baseline(), str, font);
                break;
@@ -3598,6 +3603,7 @@ void LyXText::paintLastRow(DrawRowParams & p)
        }
 }
 
+
 void LyXText::paintRowText(DrawRowParams & p)
 {
        Paragraph * par = p.row->par();
@@ -3612,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) {
@@ -3626,7 +3631,7 @@ void LyXText::paintRowText(DrawRowParams & p)
                        continue;
                }
                if (main_body > 0 && pos == main_body - 1) {
-                       int const lwidth = lyxfont::width(layout.labelsep,
+                       int const lwidth = font_metrics::width(layout->labelsep,
                                getLabelFont(buffer, par));
 
                        p.x += p.label_hfill + lwidth
@@ -3736,12 +3741,13 @@ void LyXText::getVisibleRow(BufferView * bv, int y_offset, int x_offset,
 int LyXText::defaultHeight() const
 {
        LyXFont font(LyXFont::ALL_SANE);
-       return int(lyxfont::maxAscent(font) + lyxfont::maxDescent(font) * 1.5);
+       return int(font_metrics::maxAscent(font)
+                + 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  */
+// returns the column near the specified x-coordinate of the row
+// x is set to the real beginning of this column
 pos_type
 LyXText::getColumnNearX(BufferView * bview, Row * row, int & x,
                        bool & boundary) const
@@ -3757,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());
@@ -3775,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 +
-                               lyxfont::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
@@ -3907,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;