]> git.lyx.org Git - lyx.git/blobdiff - src/text.C
Added html export for LinuxDoc and DocBook. LinuxDoc import now available in file...
[lyx.git] / src / text.C
index 6d8b9ca4d25bbeb97304813f6ec3094ea1f58e74..c81fae1f9b3af9e3315795c7f73349b769992667 100644 (file)
@@ -1,12 +1,12 @@
 /* This file is part of
-* ======================================================
-* 
-*           LyX, The Document Processor
-*       
-*          Copyright (C) 1995 Matthias Ettrich
-*           Copyright (C) 1995-1998 The LyX Team.
-*
-*======================================================*/
+ * ====================================================== 
+ 
+ *           LyX, The Document Processor
+ *      
+ *           Copyright 1995 Matthias Ettrich
+ *           Copyright 1995-2000 The LyX Team.
+ *
+ * ====================================================== */
 
 #include <config.h>
 #include <cstdlib>
 #include "lyxparagraph.h"
 #include "lyxtext.h"
 #include "support/textutils.h"
+#include "insets/insetbib.h"
 #include "lyx_gui_misc.h"
-#include "lyxdraw.h"
 #include "gettext.h"
 #include "bufferparams.h"
 #include "buffer.h"
-#include "lyxscreen.h"
 #include "minibuffer.h"
+#include "debug.h"
+#include "lyxrc.h"
+#include "LyXView.h"
+#include "lyxrow.h"
+#include "Painter.h"
+#include "tracer.h"
+
+using std::max;
+using std::min;
 
 static const int LYX_PAPER_MARGIN = 20;
 
-extern int mono_video;
-extern int reverse_video;
-extern int fast_selection;
-extern BufferView *current_view;
-extern int UnlockInset(UpdatableInset* inset);
 
 // ale070405
-extern int bibitemMaxWidth(const class LyXFont &);
+extern int bibitemMaxWidth(Painter &, LyXFont const &);
+
+#define FIX_DOUBLE_SPACE 1
+
+static int iso885968x[] = {
+       0xbc,   // 0xa8 = fathatan
+       0xbd,   // 0xa9 = dammatan
+       0xbe,   // 0xaa = kasratan
+       0xdb,   // 0xab = fatha
+       0xdc,   // 0xac = damma
+       0xdd,   // 0xad = kasra
+       0xde,   // 0xae = shadda
+       0xdf,   // 0xaf = sukun
+
+       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xb0-0xbf
+
+       0,      // 0xc0 
+       0xc1,   // 0xc1 = hamza
+       0xc2,   // 0xc2 = ligature madda
+       0xc3,   // 0xc3 = ligature hamza on alef
+       0xc4,   // 0xc4 = ligature hamza on waw
+       0xc5,   // 0xc5 = ligature hamza under alef
+       0xc0,   // 0xc6 = ligature hamza on ya 
+       0xc7,   // 0xc7 = alef
+       0xeb,   // 0xc8 = baa 
+       0xc9,   // 0xc9 = taa marbuta
+       0xec,   // 0xca = taa
+       0xed,   // 0xcb = thaa
+       0xee,   // 0xcc = jeem
+       0xef,   // 0xcd = haa
+       0xf0,   // 0xce = khaa
+       0xcf,   // 0xcf = dal
+
+       0xd0,   // 0xd0 = thal
+       0xd1,   // 0xd1 = ra
+       0xd2,   // 0xd2 = zain
+       0xf1,   // 0xd3 = seen
+       0xf2,   // 0xd4 = sheen
+       0xf3,   // 0xd5 = sad
+       0xf4,   // 0xd6 = dad
+       0xd7,   // 0xd7 = tah
+       0xd8,   // 0xd8 = zah
+       0xf5,   // 0xd9 = ain
+       0xf6,   // 0xda = ghain
+       0,0,0,0,0, // 0xdb- 0xdf
+
+       0,      // 0xe0
+       0xf7,   // 0xe1 = fa
+       0xf8,   // 0xe2 = qaf
+       0xf9,   // 0xe3 = kaf
+       0xfa,   // 0xe4 = lam
+       0xfb,   // 0xe5 = meem
+       0xfc,   // 0xe6 = noon
+       0xfd,   // 0xe7 = ha
+       0xe8,   // 0xe8 = waw
+       0xe9,   // 0xe9 = alef maksura
+       0xfe    // 0xea = ya
+};
+
+bool is_arabic(unsigned char c)
+{
+       return 0xa8 <= c && c <= 0xea && iso885968x[c-0xa8];
+}
+
+unsigned char LyXText::TransformChar(unsigned char c, Letter_Form form) const
+{
+       if (is_arabic(c) && 
+           (form == FORM_INITIAL || form == FORM_MEDIAL) )
+               return iso885968x[c-0xa8];
+       else
+               return c;
+}
 
-// dnaber 1999-02-02
-extern MiniBuffer *minibuffer;
+unsigned char LyXText::TransformChar(unsigned char c, LyXParagraph * par,
+                       LyXParagraph::size_type pos) const
+{
+       if (!is_arabic(c))
+               return c;
+
+       bool not_first = (pos > 0 && is_arabic(par->GetChar(pos-1)));
+       if (pos < par->Last()-1 && is_arabic(par->GetChar(pos+1)))
+               if (not_first)
+                       return TransformChar(c,FORM_MEDIAL);
+               else
+                       return TransformChar(c,FORM_INITIAL);
+       else
+               if (not_first)
+                       return TransformChar(c,FORM_FINAL);
+               else
+                       return TransformChar(c,FORM_ISOLATED);
+}
 
-int LyXText::SingleWidth(LyXParagraph *par, int pos)
+// This is the comments that some of the warnings below refers to.
+// There are some issues in this file and I don't think they are
+// really related to the FIX_DOUBLE_SPACE patch. I'd rather think that
+// this is a problem that has been here almost from day one and that a
+// larger userbase with differenct access patters triggers the bad
+// behaviour. (segfaults.) What I think happen is: In several places
+// we store the paragraph in the current cursor and then moves the
+// cursor. This movement of the cursor will delete paragraph at the
+// old position if it is now empty. This will make the temporary
+// pointer to the old cursor paragraph invalid and dangerous to use.
+// And is some cases this will trigger a segfault. I have marked some
+// of the cases where this happens with a warning, but I am sure there
+// are others in this file and in text2.C. There is also a note in
+// Delete() that you should read. In Delete I store the paragraph->id
+// instead of a pointer to the paragraph. I am pretty sure this faulty
+// use of temporary pointers to paragraphs that might have gotten
+// invalidated (through a cursor movement) before they are used, are
+// the cause of the strange crashes we get reported often.
+//
+// It is very tiresom to change this code, especially when it is as
+// hard to read as it is. Help to fix all the cases where this is done
+// would be greately appreciated.
+//
+// Lgb
+
+int LyXText::SingleWidth(LyXParagraph * par,
+                        LyXParagraph::size_type pos) const
 {
        char c = par->GetChar(pos);
        return SingleWidth(par, pos, c);
 }
 
 
-int LyXText::SingleWidth(LyXParagraph *par, int pos, char c)
+int LyXText::SingleWidth(LyXParagraph * par,
+                        LyXParagraph::size_type pos, char c) const
 {
        LyXFont font = GetFont(par, pos);
 
        // The most common case is handled first (Asger)
        if (IsPrintable(c)) {
+               if (lyxrc.rtl_support && lyxrc.font_norm == "iso8859-6.8x")
+                       c = TransformChar(c, par, pos);
                return font.width(c);
 
        } else if (IsHfillChar(c)) {
-               return 3;       /* because of the representation
+               return 3;       /* Because of the representation
                                 * as vertical lines */
-
-       } else if (c == LYX_META_FOOTNOTE ||
-                  c == LYX_META_MARGIN ||
-                  c == LYX_META_FIG ||
-                  c == LYX_META_TAB ||
-                  c == LYX_META_WIDE_FIG ||
-                  c == LYX_META_WIDE_TAB ||
-                  c == LYX_META_ALGORITHM) 
-       {
+       } else if (c == LyXParagraph::META_FOOTNOTE ||
+                  c == LyXParagraph::META_MARGIN ||
+                  c == LyXParagraph::META_FIG ||
+                  c == LyXParagraph::META_TAB ||
+                  c == LyXParagraph::META_WIDE_FIG ||
+                  c == LyXParagraph::META_WIDE_TAB ||
+                  c == LyXParagraph::META_ALGORITHM) {
                string fs;
                switch (c) {
-               case LYX_META_MARGIN:
+               case LyXParagraph::META_MARGIN:
                        fs = "margin";
                        break;
-               case LYX_META_FIG:
+               case LyXParagraph::META_FIG:
                        fs = "fig";
                        break;
-               case LYX_META_TAB:
+               case LyXParagraph::META_TAB:
                        fs = "tab";
                        break;
-               case LYX_META_ALGORITHM:
+               case LyXParagraph::META_ALGORITHM:
                        fs = "alg";
                        break;
-               case LYX_META_WIDE_FIG:
+               case LyXParagraph::META_WIDE_FIG:
                        fs = "wide-fig";
                        break;
-               case LYX_META_WIDE_TAB:
+               case LyXParagraph::META_WIDE_TAB:
                        fs = "wide-tab";
                        break;
-               case LYX_META_FOOTNOTE:
+               case LyXParagraph::META_FOOTNOTE:
                        fs = "foot";
                        break;
                }
                font.decSize();
                font.decSize();
                return font.stringWidth(fs);
-       } 
-   
-       else if (c == LYX_META_INSET) {
-               Inset *tmpinset=par->GetInset(pos);
+       } else if (c == LyXParagraph::META_INSET) {
+               Inset * tmpinset= par->GetInset(pos);
                if (tmpinset)
-                       return par->GetInset(pos)->Width(font);
+                       return par->GetInset(pos)->width(owner_->painter(),
+                                                        font);
                else
                        return 0;
 
@@ -113,105 +229,266 @@ int LyXText::SingleWidth(LyXParagraph *par, int pos, char c)
 }
 
 
-/* returns the paragraph position of the last character in the 
- * specified row */
-int LyXText::RowLast(Row *row)
+// Returns the paragraph position of the last character in the specified row
+LyXParagraph::size_type LyXText::RowLast(Row const * row) const
 {
        if (row->next == 0)
-               return row->par->Last()-1;
+               return row->par->Last() - 1;
        else if (row->next->par != row->par) 
-               return row->par->Last()-1;
+               return row->par->Last() - 1;
        else 
                return row->next->pos - 1;
 }
 
 
-void LyXText::Draw(Row *row, int &pos, LyXScreen &scr, int offset, float &x)
+
+
+
+void LyXText::ComputeBidiTables(Row * row) const
 {
+
+       if (!lyxrc.rtl_support) {
+               bidi_start = -1;
+               return;
+       }
+       LyXParagraph::size_type last = RowLast(row);
+       bidi_start = row->pos;
+
+       if (bidi_start > last) {
+               bidi_start = -1;
+               return;
+       }
+
+       if (last + 2 - bidi_start >
+           static_cast<LyXParagraph::size_type>(log2vis_list.size())) {
+               LyXParagraph::size_type new_size = 
+                       (last + 2 - bidi_start < 500) ?
+                       500 : 2 * (last + 2 - bidi_start);
+               log2vis_list.resize(new_size);
+               vis2log_list.resize(new_size);
+       }
+
+       vis2log_list[last + 1 - bidi_start] = -1;
+       log2vis_list[last + 1 - bidi_start] = -1;
+
+       LyXParagraph::size_type main_body = BeginningOfMainBody(row->par);
+       if (main_body > 0 && row->pos < main_body - 1 && main_body - 1 <= last
+           && row->par->IsLineSeparator(main_body - 1)) {
+               // This is needed in case there is a direction change in
+               // the label which is continued into the main body
+               if (row->par->getParDirection() == LYX_DIR_LEFT_TO_RIGHT) {
+                       ComputeBidiTablesFromTo(row, bidi_start,
+                                               main_body - 2, 0);
+                       log2vis_list[main_body - 1 - bidi_start] =
+                               main_body - 1;
+                       vis2log_list[main_body - 1 - bidi_start] =
+                               main_body - 1;
+                       if (main_body <= last)
+                               ComputeBidiTablesFromTo(row,
+                                                       main_body,last, 0);
+               } else {
+                       ComputeBidiTablesFromTo(row, bidi_start,
+                                               main_body - 2,
+                                               last - main_body + 2);
+                       log2vis_list[main_body - 1 - bidi_start] =
+                               last - main_body + 1 + bidi_start;
+                       vis2log_list[last - main_body + 1 - bidi_start] =
+                               main_body - 1;
+                       if (main_body <= last)
+                               ComputeBidiTablesFromTo(row, main_body,
+                                                       last, -main_body);
+               }
+       } else
+               ComputeBidiTablesFromTo(row, bidi_start, last, 0);
+}
+
+
+void LyXText::ComputeBidiTablesFromTo(Row * row,
+                                     LyXParagraph::size_type from,
+                                     LyXParagraph::size_type to,
+                                     LyXParagraph::size_type offset) const
+{
+       LyXParagraph::size_type vpos, old_lpos, stack[2];
+       LyXDirection par_direction = row->par->getParDirection();
+       LyXDirection direction = par_direction;
+       LyXParagraph::size_type lpos = from;
+       int level = 0;
+
+       while (lpos <= to) {
+               if (row->par->getLetterDirection(lpos) == direction) {
+                       log2vis_list[lpos - bidi_start] = direction;
+                       ++lpos;
+               } else {
+                       if (level == 0 ||
+                           (level == 1 && direction == LYX_DIR_RIGHT_TO_LEFT
+                            && row->par->getFont(lpos).isRightToLeft()
+                            && row->par->getFont(lpos).latex() == LyXFont::ON
+                            ) ) {
+                               // The last check is needed when the
+                               // char is a space
+                               stack[level++] = lpos;
+                       } else {
+                               old_lpos = stack[--level];
+                               log2vis_list[old_lpos - bidi_start] = 
+                                       log2vis_list[lpos - bidi_start] =
+                                       (old_lpos - lpos) * direction;
+                               ++lpos;
+                       }
+                       direction = static_cast<LyXDirection>(-direction);
+               }
+       }
+
+       while (level > 0) {
+               old_lpos = stack[--level];
+               log2vis_list[old_lpos - bidi_start] =
+                       (old_lpos - (to + 1)) * direction; 
+               direction = static_cast<LyXDirection>(-direction);
+       }
+
+       vpos = (par_direction == LYX_DIR_LEFT_TO_RIGHT)
+               ? from - 1 : to + 1;
+       vpos += offset;
+       for (lpos = from; lpos <= to; ++lpos) {
+               vpos += log2vis_list[lpos - bidi_start];
+               vis2log_list[vpos - bidi_start] = lpos;
+               log2vis_list[lpos - bidi_start] = vpos;
+       }
+}
+
+
+void LyXText::draw(Row const * row,
+                  LyXParagraph::size_type & vpos,
+                  int offset, float & x)
+{
+       Painter & pain = owner_->painter();
+       
+       LyXParagraph::size_type pos = vis2log(vpos);
        char c = row->par->GetChar(pos);
 
        if (IsNewlineChar(c)) {
-               pos++;
+               ++vpos;
                // Draw end-of-line marker
-
                LyXFont font = GetFont(row->par, pos);
-               int asc = font.maxAscent();
                int wid = font.width('n');
-               int y = (offset + row->baseline);
-               XPoint p[3];
-               p[0].x = int(x + wid*0.375); p[0].y = int(y - 0.875*asc*0.75);
-               p[1].x = int(x);             p[1].y = int(y - 0.500*asc*0.75);
-               p[2].x = int(x + wid*0.375); p[2].y = int(y - 0.125*asc*0.75);
-               scr.drawLines(::getGC(gc_new_line),p, 3);
+               int asc = font.maxAscent();
+               int y = offset + row->baseline;
+               int xp[3], yp[3];
                
-               p[0].x = int(x);             p[0].y = int(y - 0.500*asc*0.75);
-               p[1].x = int(x + wid);       p[1].y = int(y - 0.500*asc*0.75);
-               p[2].x = int(x + wid);       p[2].y = int(y - asc*0.75);
-               scr.drawLines(::getGC(gc_new_line),p, 3);
+               if (row->par->getLetterDirection(pos) == LYX_DIR_LEFT_TO_RIGHT) {
+                       xp[0] = int(x + wid * 0.375);
+                       yp[0] = int(y - 0.875 * asc * 0.75);
+                       
+                       xp[1] = int(x);
+                       yp[1] = int(y - 0.500 * asc * 0.75);
+                       
+                       xp[2] = int(x + wid * 0.375);
+                       yp[2] = int(y - 0.125 * asc * 0.75);
+                       
+                       pain.lines(xp, yp, 3, LColor::eolmarker);
+                       
+                       xp[0] = int(x);
+                       yp[0] = int(y - 0.500 * asc * 0.75);
+                       
+                       xp[1] = int(x + wid);
+                       yp[1] = int(y - 0.500 * asc * 0.75);
+                       
+                       xp[2] = int(x + wid);
+                       yp[2] = int(y - asc * 0.75);
+                       
+                       pain.lines(xp, yp, 3, LColor::eolmarker);
+               } else {
+                       xp[0] = int(x + wid * 0.625);
+                       yp[0] = int(y - 0.875 * asc * 0.75);
+                       
+                       xp[1] = int(x + wid);
+                       yp[1] = int(y - 0.500 * asc * 0.75);
+                       
+                       xp[2] = int(x + wid * 0.625);
+                       yp[2] = int(y - 0.125 * asc * 0.75);
+                       
+                       pain.lines(xp, yp, 3, LColor::eolmarker);
+                       
+                       xp[0] = int(x + wid);
+                       yp[0] = int(y - 0.500 * asc * 0.75);
+                       
+                       xp[1] = int(x);
+                       yp[1] = int(y - 0.500 * asc * 0.75);
+                       
+                       xp[2] = int(x);
+                       yp[2] = int(y - asc * 0.75);
+                       
+                       pain.lines(xp, yp, 3, LColor::eolmarker);
+               }
+               x += wid;
                return;
        }
 
        LyXFont font = GetFont(row->par, pos);
        LyXFont font2 = font;
 
-       if (c == LYX_META_FOOTNOTE ||
-           c == LYX_META_MARGIN ||
-           c == LYX_META_FIG ||
-           c == LYX_META_TAB ||
-           c == LYX_META_WIDE_FIG ||
-           c == LYX_META_WIDE_TAB ||
-           c == LYX_META_ALGORITHM) {
+       if (c == LyXParagraph::META_FOOTNOTE
+           || c == LyXParagraph::META_MARGIN
+           || c == LyXParagraph::META_FIG
+           || c == LyXParagraph::META_TAB
+           || c == LyXParagraph::META_WIDE_FIG
+           || c == LyXParagraph::META_WIDE_TAB
+           || c == LyXParagraph::META_ALGORITHM) {
                string fs;
                switch (c) {
-               case LYX_META_MARGIN:
+               case LyXParagraph::META_MARGIN:
                        fs = "margin";
-                       /* draw a sign at the left margin! */ 
-                       scr.drawText(font, "!", 1, offset + row->baseline,
-                                    (LYX_PAPER_MARGIN - font.width('!'))/2);
+                       // Draw a sign at the left margin!
+                       owner_->painter()
+                               .text((LYX_PAPER_MARGIN - font.width('!'))/2,
+                                     offset + row->baseline, "!", 1, font);
                        break;
-               case LYX_META_FIG:
+               case LyXParagraph::META_FIG:
                        fs = "fig";
                        break;
-               case LYX_META_TAB:
+               case LyXParagraph::META_TAB:
                        fs = "tab";
                        break;
-               case LYX_META_ALGORITHM:
+               case LyXParagraph::META_ALGORITHM:
                        fs = "alg";
                        break;
-               case LYX_META_WIDE_FIG:
+               case LyXParagraph::META_WIDE_FIG:
                        fs = "wide-fig";
                        break;
-               case LYX_META_WIDE_TAB:
+               case LyXParagraph::META_WIDE_TAB:
                        fs = "wide-tab";
                        break;
-               case LYX_META_FOOTNOTE:
+               case LyXParagraph::META_FOOTNOTE:
                        fs = "foot";
                        break;
                }
                font.decSize();
                font.decSize();
          
-               /* calculate the position of the footnotemark */
+               // calculate the position of the footnotemark
                int y = (row->baseline - font2.maxAscent() 
                         + font.maxAscent());
          
-               font.setColor(LyXFont::INSET);
+               font.setColor(LColor::footnote);
 
                float tmpx = x;
 
-               /* draw it and set new x position */
-               x += scr.drawString(font, fs, offset + y, int(x));
+               // draw it and set new x position
+               
+               pain.text(int(x), offset + y, fs, font);
+               x += pain.width(fs, font);
+               pain.line(int(tmpx), offset + row->baseline,
+                         int(x), offset + row->baseline,
+                         LColor::footnote);
 
-               scr.drawLine(gc_foot, offset + row->baseline,
-                            int(tmpx), int(x - tmpx));
-         
-               pos++;
+               ++vpos;
                return;
-       } else if (c == LYX_META_INSET) {
-               Inset *tmpinset = row->par->GetInset(pos);
-               if (tmpinset) 
-                       tmpinset->Draw(font, scr, offset + row->baseline, x);
-               pos++;
+       } else if (c == LyXParagraph::META_INSET) {
+               Inset * tmpinset = row->par->GetInset(pos);
+               if (tmpinset) {
+                       tmpinset->draw(owner_->painter(), font,
+                                      offset + row->baseline, x);
+               }
+               ++vpos;
                return;
        }
 
@@ -222,42 +499,41 @@ void LyXText::Draw(Row *row, int &pos, LyXScreen &scr, int offset, float &x)
        // This is dirty, but fast. Notice that it will never be too small.
        // For the record, I'll note that Microsoft Word has a limit
        // of 768 here. We have none :-) (Asger)
-       static char textstring[1024];
-
-       int last = RowLast(row);
-       // Prevent crash in the extremely unlikely event
-       // that our array is too small
-       if (last > pos+1020) last = pos + 1020;
-
-       textstring[0] = c;
-       pos++;
-
-       int i = 1;
-
-       while (pos <= last &&
-              (unsigned char) (c = row->par->GetChar(pos)) > ' ' &&
-              font2 == GetFont(row->par, pos)) {
-               textstring[i++] = c;
-               pos++;
+       // Ok. I am the first to admit that the use of std::string will be
+       // a tiny bit slower than using a POD char array. However, I claim
+       // that this slowdown is so small that it is close to inperceptive.
+       // So IMHO we should go with the easier and clearer implementation.
+       // And even if 1024 is a large number here it might overflow, string
+       // will only overflow if the machine is out of memory...
+       bool do_transform = (lyxrc.rtl_support && lyxrc.font_norm == "iso8859-6.8x");
+       if (do_transform)
+               c = TransformChar(c, row->par, pos);
+       static string textstring;
+       textstring = c;
+       ++vpos;
+
+       LyXParagraph::size_type last = RowLast(row);
+       
+       while (vpos <= last &&
+              (pos = vis2log(vpos)) >= 0
+              && static_cast<unsigned char>(c = row->par->GetChar(pos)) > ' '
+              && font2 == GetFont(row->par, pos)) {
+               if (do_transform)
+                       c = TransformChar(c, row->par, pos);
+               textstring += c;
+               ++vpos;
        }
-       textstring[i] = 0; 
-
        float tmpx = x;
 
-       // If monochrome and LaTeX mode, provide reverse background
-       if (mono_video && font.latex() == LyXFont::ON) {
-               int a=font.maxAscent(), d=font.maxDescent();
-               scr.fillRectangle(gc_copy, int(tmpx), offset + row->baseline-a,
-                                 font.textWidth(textstring, i), a+d);
-       }
-
-       /* Draw text and set the new x position */ 
-       x += scr.drawText(font, textstring, i, offset + row->baseline, 
-                         int(x));
-       /* what about underbars? */
+       // Draw text and set the new x position
+       pain.text(int(x), offset + row->baseline, textstring, font);
+       x += pain.width(textstring, font);
+       
+       // what about underbars?
        if (font.underbar() == LyXFont::ON && font.latex() != LyXFont::ON) {
-               scr.drawLine(gc_copy, offset + row->baseline + 2,
-                            int(tmpx), int(x - tmpx));
+               pain.line(tmpx, offset + row->baseline + 2,
+                         x, offset + row->baseline + 2);
+               
        }
 
        // If we want ulem.sty support, drawing
@@ -266,319 +542,342 @@ void LyXText::Draw(Row *row, int &pos, LyXScreen &scr, int offset, float &x)
 }
 
 
-/* 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(Row* row)
+// 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(Row const * row) const
 {
-   int x;
-   LyXLayout *layout;
-   LyXFont labelfont;
-   LyXParagraph *newpar;
-   Row dummyrow;
-   layout = lyxstyle.Style(parameters->textclass, row->par->GetLayout());
-   
-   string parindent = layout->parindent; 
-
-   /* table stuff -- begin*/ 
-   if (row->par->table)
-      parindent.erase();
-   /* table stuff -- end*/       
-
-   x = LYX_PAPER_MARGIN;
-
-   x += lyxstyle.TextClass(parameters->textclass)->
-     defaultfont.signedStringWidth(lyxstyle.TextClass(parameters->textclass)->leftmargin);
-
-   if (row->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)  {
-       LyXFont font(LyXFont::ALL_SANE);
-       font.setSize(LyXFont::SIZE_SMALL);
-       x += font.textWidth("Mwide-figM", 10) + LYX_PAPER_MARGIN/2;
-   }
-
-   /* 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->GetLayout()) {
-        /* find the previous same level paragraph */
-        if (row->par->FirstPhysicalPar()->Previous()) {
-           newpar = row->par->DepthHook(row->par->GetDepth());
-           if (newpar && lyxstyle.Style(parameters->textclass, newpar->GetLayout())->nextnoindent)
-              parindent.erase();
-        }
-      }
-   }
-   else {
-      /* find the next level paragraph */ 
-      
-      newpar = row->par->DepthHook(row->par->GetDepth()-1);
-
-      /* make a corresponding row. Needed to call LeftMargin() */
-      
-      /* check wether it is a sufficent paragraph */ 
-      if (newpar && newpar->footnoteflag == row->par->footnoteflag
-         && lyxstyle.Style(parameters->textclass, 
-                           newpar->GetLayout())->isEnvironment()) {
-            dummyrow.par = newpar;
-            dummyrow.pos = newpar->Last();
-            x = LeftMargin(&dummyrow);
-      }
-      else {
-        /* this is no longer an error, because this function is used
-         * to clear impossible depths after changing a layout. Since there
-         * is always a redo, LeftMargin() is always called */ 
-        
-        /* printf("LYX_ERROR (text, LeftMargin()) impossible depth \n");*/ 
-        row->par->FirstPhysicalPar()->depth = 0;
-      }
-      
-      if (newpar && !row->par->GetLayout()) {
-        if (newpar->FirstPhysicalPar()->noindent)
-           parindent.erase();
-        else
-           parindent = lyxstyle.Style(parameters->textclass, 
-                                      newpar->GetLayout())->parindent;
-      }
-      
-   }
-   
-   labelfont = GetFont(row->par, -2);
-   switch (layout->margintype) {
-    case MARGIN_DYNAMIC:
-      if (!layout->leftmargin.empty()) {
-       x += lyxstyle.TextClass(parameters->textclass)->defaultfont.signedStringWidth(layout->leftmargin);
-      }
-      if (!row->par->GetLabestring().empty()) {
-           x += labelfont.signedStringWidth(layout->labelindent);
-           x += labelfont.stringWidth(row->par->GetLabestring());
-           x += labelfont.stringWidth(layout->labelsep);
-      }
-      break;
-    case MARGIN_MANUAL:
-      x += labelfont.signedStringWidth(layout->labelindent);
-      if (row->pos >= BeginningOfMainBody(row->par)) {
-        if (!row->par->GetLabelWidthString().empty()) {
-           x += labelfont.stringWidth(row->par->GetLabelWidthString());
-           x += labelfont.stringWidth(layout->labelsep);
-        }
-      }
-      break;
-    case MARGIN_STATIC:
-      x += ( lyxstyle.TextClass(parameters->textclass)->defaultfont.signedStringWidth(layout->leftmargin) * 4
-            / (row->par->GetDepth() + 4));
-      break;
-    case MARGIN_FIRST_DYNAMIC:
-      if (layout->labeltype == LABEL_MANUAL) {
-        if (row->pos >= BeginningOfMainBody(row->par)) {
-           x += labelfont.signedStringWidth(layout->leftmargin);
-        } else {
-           x += labelfont.signedStringWidth(layout->labelindent);
-        }
-      } else {
-        if (row->pos
-            // Special case to fix problems with theorems (JMarc)
-            || (layout->labeltype == LABEL_STATIC
-                && layout->latextype == LATEX_ENVIRONMENT
-                && ! row->par->IsFirstInSequence())) {
-                x += labelfont.signedStringWidth(layout->leftmargin);
-        } else if (layout->labeltype != LABEL_TOP_ENVIRONMENT
-                 && layout->labeltype != LABEL_BIBLIO
-                 && layout->labeltype != LABEL_CENTERED_TOP_ENVIRONMENT) {
-                x += labelfont.signedStringWidth(layout->labelindent);
-                x += labelfont.stringWidth(layout->labelsep);
-                x += labelfont.stringWidth(row->par->GetLabestring());
-        } 
-      }
-      break;
-      
-    case MARGIN_RIGHT_ADDRESS_BOX:
-    {
-      /* ok, a terrible hack. The left margin depends on the widest row
-       * in this paragraph. Do not care about footnotes, they are *NOT*
-       * allowed in the LaTeX realisation of this layout. */ 
-      
-      /* find the first row of this paragraph */ 
-      Row *tmprow = row;
-      while (tmprow->previous && tmprow->previous->par == row->par)
-       tmprow = tmprow->previous;
-      
-      int minfill = tmprow->fill;
-      while (tmprow-> next && tmprow->next->par == row->par) {
-        tmprow = tmprow->next;
-        if (tmprow->fill < minfill)
-          minfill = tmprow->fill;
-      }
-      
-      x += lyxstyle.TextClass(parameters->textclass)->defaultfont.signedStringWidth(layout->leftmargin);
-      x += minfill;
-    }
-      break;
-   }
-   if (row->par->pextra_type == PEXTRA_INDENT) {
-       if (!row->par->pextra_widthp.empty()) {
-           x += paperwidth * atoi(row->par->pextra_widthp.c_str()) / 100;
-       } else if (!row->par->pextra_width.empty()) {
-           int xx = VSpace(row->par->pextra_width).inPixels();
-
-           if (xx > paperwidth)
-               xx = paperwidth * 80 / 100;
-           x += xx;
-       } else { // should not happen
-           LyXFont font(LyXFont::ALL_SANE);
-           x += font.stringWidth("XXXXXX");
-       }
-   }
-   
-   int align;
-   if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT)
-     align = layout->align;
-   else
-     align = row->par->FirstPhysicalPar()->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
-               && ! row->par->IsFirstInSequence()))
-          && row->par == row->par->FirstPhysicalPar()
-          && align == LYX_ALIGN_BLOCK
-          && !row->par->noindent
-          && (row->par->layout ||
-              parameters->paragraph_separation == LYX_PARSEP_INDENT))
-        x += lyxstyle.TextClass(parameters->textclass)->defaultfont.stringWidth(parindent);
-       else 
-        if (layout->labeltype==LABEL_BIBLIO) { // ale970405 Right width for bibitems
-            x += bibitemMaxWidth(lyxstyle.TextClass(parameters->textclass)->defaultfont);
-        }
-   }
-
-   return x;
+       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+                                                      row->par->GetLayout());
+       
+       string parindent = layout.parindent; 
+       
+       /* table stuff -- begin */ 
+       if (row->par->table)
+               parindent.clear();
+       /* table stuff -- end */
+       
+       int x = LYX_PAPER_MARGIN;
+       
+       x += textclasslist.TextClass(parameters->textclass)
+               .defaultfont()
+               .signedStringWidth(textclasslist
+                                  .TextClass(parameters->textclass)
+                                  .leftmargin());
+       
+       if (row->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)  {
+               LyXFont font(LyXFont::ALL_SANE);
+               font.setSize(LyXFont::SIZE_SMALL);
+               x += font.textWidth("Mwide-figM", 10) + LYX_PAPER_MARGIN/2;
+       }
+       
+       // 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->GetLayout()) {
+                       // find the previous same level paragraph
+                       if (row->par->FirstPhysicalPar()->Previous()) {
+                               LyXParagraph * newpar = row->par
+                                       ->DepthHook(row->par->GetDepth());
+                               if (newpar &&
+                                   textclasslist.Style(parameters->textclass,
+                                                       newpar->GetLayout())
+                                   .nextnoindent)
+                                       parindent.clear();
+                       }
+               }
+       } else {
+               // find the next level paragraph
+               
+               LyXParagraph * newpar = row->par->DepthHook(row->par->GetDepth()-1);
+               
+               // make a corresponding row. Needed to call LeftMargin()
+               
+               // check wether it is a sufficent paragraph 
+               if (newpar && newpar->footnoteflag == row->par->footnoteflag
+                   && textclasslist
+                       .Style(parameters->textclass, 
+                              newpar->GetLayout()).isEnvironment()) {
+                       Row dummyrow;
+                       dummyrow.par = newpar;
+                       dummyrow.pos = newpar->Last();
+                       x = LeftMargin(&dummyrow);
+               } else {
+                       // this is no longer an error, because this function
+                       // is used to clear impossible depths after changing
+                       // a layout. Since there is always a redo,
+                       // LeftMargin() is always called
+                       row->par->FirstPhysicalPar()->depth = 0;
+               }
+               
+               if (newpar && !row->par->GetLayout()) {
+                       if (newpar->FirstPhysicalPar()->noindent)
+                               parindent.clear();
+                       else
+                               parindent = textclasslist
+                                       .Style(parameters->textclass, 
+                                              newpar->GetLayout()).parindent;
+               }
+               
+       }
+       
+       LyXFont labelfont = GetFont(row->par, -2);
+       switch (layout.margintype) {
+       case MARGIN_DYNAMIC:
+               if (!layout.leftmargin.empty()) {
+                       x += textclasslist
+                               .TextClass(parameters->textclass)
+                               .defaultfont()
+                               .signedStringWidth(layout.leftmargin);
+               }
+               if (!row->par->GetLabestring().empty()) {
+                       x += labelfont.signedStringWidth(layout.labelindent);
+                       x += labelfont.stringWidth(row->par->GetLabestring());
+                       x += labelfont.stringWidth(layout.labelsep);
+               }
+               break;
+       case MARGIN_MANUAL:
+               x += labelfont.signedStringWidth(layout.labelindent);
+               if (row->pos >= BeginningOfMainBody(row->par)) {
+                       if (!row->par->GetLabelWidthString().empty()) {
+                               x += labelfont
+                                       .stringWidth(row->par
+                                                    ->GetLabelWidthString());
+                               x += labelfont.stringWidth(layout.labelsep);
+                       }
+               }
+               break;
+       case MARGIN_STATIC:
+               x += textclasslist.TextClass(parameters->textclass)
+                       .defaultfont().signedStringWidth(layout.leftmargin) * 4
+                       / (row->par->GetDepth() + 4);
+               break;
+       case MARGIN_FIRST_DYNAMIC:
+               if (layout.labeltype == LABEL_MANUAL) {
+                       if (row->pos >= BeginningOfMainBody(row->par)) {
+                               x += labelfont
+                                       .signedStringWidth(layout.leftmargin);
+                       } else {
+                               x += labelfont
+                                       .signedStringWidth(layout.labelindent);
+                       }
+               } else if (row->pos
+                          // Special case to fix problems with
+                          // theorems (JMarc)
+                          || (layout.labeltype == LABEL_STATIC
+                              && layout.latextype == LATEX_ENVIRONMENT
+                              && ! row->par->IsFirstInSequence())) {
+                       x += labelfont.signedStringWidth(layout.leftmargin);
+               } else if (layout.labeltype != LABEL_TOP_ENVIRONMENT
+                          && layout.labeltype != LABEL_BIBLIO
+                          && layout.labeltype !=
+                          LABEL_CENTERED_TOP_ENVIRONMENT) {
+                       x += labelfont.signedStringWidth(layout.labelindent);
+                       x += labelfont.stringWidth(layout.labelsep);
+                       x += labelfont.stringWidth(row->par->GetLabestring());
+               } 
+               break;
+               
+       case MARGIN_RIGHT_ADDRESS_BOX:
+       {
+               // ok, a terrible hack. The left margin depends on the widest
+               // row in this paragraph. Do not care about footnotes, they
+               // are *NOT* allowed in the LaTeX realisation of this layout.
+               
+               // find the first row of this paragraph
+               Row const * tmprow = row;
+               while (tmprow->previous && tmprow->previous->par == row->par)
+                       tmprow = tmprow->previous;
+               
+               int minfill = tmprow->fill;
+               while (tmprow->next && tmprow->next->par == row->par) {
+                       tmprow = tmprow->next;
+                       if (tmprow->fill < minfill)
+                               minfill = tmprow->fill;
+               }
+               
+               x += textclasslist.TextClass(parameters->textclass)
+                       .defaultfont().signedStringWidth(layout.leftmargin);
+               x += minfill;
+       }
+       break;
+       }
+       if (row->par->pextra_type == LyXParagraph::PEXTRA_INDENT) {
+               if (!row->par->pextra_widthp.empty()) {
+                       x += paperwidth *
+                               atoi(row->par->pextra_widthp.c_str()) / 100;
+               } else if (!row->par->pextra_width.empty()) {
+                       int xx = VSpace(row->par->pextra_width).inPixels(owner_);
+                       
+                       if (xx > paperwidth)
+                               xx = paperwidth * 80 / 100;
+                       x += xx;
+               } else { // should not happen
+                       LyXFont font(LyXFont::ALL_SANE);
+                       x += font.stringWidth("XXXXXX");
+               }
+       }
+       
+       int align; // wrong type
+       if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT)
+               align = layout.align;
+       else
+               align = row->par->FirstPhysicalPar()->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
+                        && ! row->par->IsFirstInSequence()))
+                   && row->par == row->par->FirstPhysicalPar()
+                   && align == LYX_ALIGN_BLOCK
+                   && !row->par->noindent
+                   && (row->par->layout ||
+                       parameters->paragraph_separation ==
+                       BufferParams::PARSEP_INDENT))
+                       x += textclasslist.TextClass(parameters->textclass)
+                               .defaultfont().signedStringWidth(parindent);
+               else if (layout.labeltype == LABEL_BIBLIO) {
+                       // ale970405 Right width for bibitems
+                       x += bibitemMaxWidth(owner_->painter(),
+                                            textclasslist
+                                            .TextClass(parameters
+                                                       ->textclass)
+                                            .defaultfont());
+               }
+       }
+       return x;
 }
     
    
-int LyXText::RightMargin(Row *row)
+int LyXText::RightMargin(Row const * row) const
 {
-   int  x;
-   LyXLayout* layout;
-   
-   LyXParagraph *newpar;
-   Row dummyrow;
-   layout = lyxstyle.Style(parameters->textclass, row->par->GetLayout());
-
-   x = LYX_PAPER_MARGIN;
-
-   x += lyxstyle.TextClass(parameters->textclass)->
-     defaultfont.signedStringWidth(lyxstyle.TextClass(parameters->textclass)->rightmargin);
-   if (row->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)  {
-     x += LYX_PAPER_MARGIN/2;
-   }
-
-    /* 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()) {
-      /* find the next level paragraph */ 
-      
-      newpar = row->par;
-      
-      do {
-               newpar = newpar->FirstPhysicalPar()->Previous();
-               if (newpar) 
-                       newpar = newpar->FirstPhysicalPar();
-      } while (newpar && newpar->GetDepth() >= row->par->GetDepth()
-              && newpar->footnoteflag == row->par->footnoteflag);
-      
-      /* make a corresponding row. Needed to call LeftMargin() */
-
-      /* check wether it is a sufficent paragraph */ 
-      if (newpar && newpar->footnoteflag == row->par->footnoteflag
-         && lyxstyle.Style(parameters->textclass,
-                           newpar->GetLayout())->isEnvironment()) {
-            dummyrow.par = newpar;
-            dummyrow.pos = 0;
-            x = RightMargin(&dummyrow);
-         }
-      else {
-        /* this is no longer an error, because this function is used
-         * to clear impossible depths after changing a layout. Since there
-         * is always a redo, LeftMargin() is always called */ 
-        
-        /* printf("LYX_ERROR (text, LeftMargin()) impossible depth \n");*/ 
-        row->par->FirstPhysicalPar()->depth = 0;
-      }
-   }
-
-   //fprintf(stderr,"rightmargin: %s\n", layout->rightmargin.c_str());
-   //fflush(stderr);
-   x += (lyxstyle.TextClass(parameters->textclass)->defaultfont.signedStringWidth(layout->rightmargin) * 4
-        / (row->par->GetDepth() + 4));
-   return x;
-   
+       LyXLayout const & layout =
+               textclasslist.Style(parameters->textclass,
+                                   row->par->GetLayout());
+       
+       int x = LYX_PAPER_MARGIN
+               + textclasslist
+               .TextClass(parameters->textclass)
+               .defaultfont()
+               .signedStringWidth(textclasslist
+                                  .TextClass(parameters->textclass)
+                                  .rightmargin());
+       
+       if (row->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)  {
+               x += LYX_PAPER_MARGIN / 2;
+       }
+       
+       // 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()) {
+               // find the next level paragraph
+               
+               LyXParagraph * newpar = row->par;
+               
+               do {
+                       newpar = newpar->FirstPhysicalPar()->Previous();
+                       if (newpar) 
+                               newpar = newpar->FirstPhysicalPar();
+               } while (newpar && newpar->GetDepth() >= row->par->GetDepth()
+                        && newpar->footnoteflag == row->par->footnoteflag);
+               
+               // make a corresponding row. Needed to call LeftMargin()
+               
+               // check wether it is a sufficent paragraph
+               if (newpar && newpar->footnoteflag == row->par->footnoteflag
+                   && textclasslist.Style(parameters->textclass,
+                                          newpar->GetLayout())
+                      .isEnvironment()) {
+                       Row dummyrow;
+                       dummyrow.par = newpar;
+                       dummyrow.pos = 0;
+                       x = RightMargin(&dummyrow);
+               } else {
+                       // this is no longer an error, because this function
+                       // is used to clear impossible depths after changing
+                       // a layout. Since there is always a redo,
+                       // LeftMargin() is always called
+                       row->par->FirstPhysicalPar()->depth = 0;
+               }
+       }
+       
+       //lyxerr << "rightmargin: " << layout->rightmargin << endl;
+       x += textclasslist.TextClass(parameters->textclass)
+               .defaultfont()
+               .signedStringWidth(layout.rightmargin) * 4
+             / (row->par->GetDepth() + 4);
+       return x;
 }
 
 
-int LyXText::LabelEnd (Row *row)
+int LyXText::LabelEnd (Row const * row) const
 {
-   if (lyxstyle.Style(parameters->textclass, row->par->GetLayout())->margintype == MARGIN_MANUAL) {
-      Row tmprow;
-      tmprow = *row;
-      tmprow.pos = row->par->Last();
-      return LeftMargin(&tmprow);      /* just the beginning 
-                                       * of the main body */
-   }
-   else
-     return 0;                        /* LabelEnd is only needed, if the  
-                                       * layout fills a flushleft
-                                       * label. */
+       if (textclasslist.Style(parameters->textclass,
+                               row->par->GetLayout()).margintype
+           == MARGIN_MANUAL) {
+               Row tmprow;
+               tmprow = *row;
+               tmprow.pos = row->par->Last();
+               return LeftMargin(&tmprow);  /* just the beginning 
+                                               of the main body */
+       } else
+               return 0;  /* LabelEnd is only needed, if the  
+                             layout fills a flushleft
+                             label. */
 }
 
 
-/* table stuff -- begin*/ 
-int LyXText::NumberOfCell(LyXParagraph *par, int pos)
+/* table stuff -- begin*/
+int LyXText::NumberOfCell(LyXParagraph * par,
+                         LyXParagraph::size_type pos) const
 {
    int cell = 0;
-   int tmp_pos = 0;
+   LyXParagraph::size_type tmp_pos = 0;
    while (tmp_pos < pos) {
       if (par->IsNewline(tmp_pos))
-        cell++;
-      tmp_pos++;
+        ++cell;
+      ++tmp_pos;
    }
    return cell;
 }
 
 
-int LyXText::WidthOfCell(LyXParagraph *par, int &pos)
+int LyXText::WidthOfCell(LyXParagraph * par,
+                        LyXParagraph::size_type & pos) const
 {
    int w = 0;
    while (pos < par->Last() && !par->IsNewline(pos)) {
       w += SingleWidth(par, pos);
-      pos++;
+      ++pos;
    }
    if (par->IsNewline(pos))
-      pos++;
+      ++pos;
    return w;
 }
 
 
-char LyXText::HitInTable(Row* row, int x)
+bool LyXText::HitInTable(Row * row, int x) const
 {
-  float tmpx;
-  float fill_separator, fill_hfill, fill_label_hfill;
-  if (!row->par->table)
-    return 0;
-  PrepareToPrint(row, tmpx, fill_separator, fill_hfill, fill_label_hfill);
-  return (x > tmpx && x < tmpx + row->par->table->WidthOfTable());
+       float tmpx;
+       float fill_separator, fill_hfill, fill_label_hfill;
+       if (!row->par->table)
+               return false;
+       PrepareToPrint(row, tmpx, fill_separator,
+                      fill_hfill, fill_label_hfill, false);
+       return (x > tmpx && x < tmpx + row->par->table->WidthOfTable());
 }
 
 
-bool LyXText::MouseHitInTable(int x, long y)
+bool LyXText::MouseHitInTable(int x, long y) const
 {
-       Row *row = GetRowNearY(y);
+       Row * row = GetRowNearY(y);
         return HitInTable(row, x);
 }
 
@@ -586,112 +885,113 @@ bool LyXText::MouseHitInTable(int x, long y)
 /* table stuff -- end*/
 
 
-/* get the next breakpoint in a given paragraph */
-int LyXText::NextBreakPoint(Row* row, int width)
+// get the next breakpoint in a given paragraph
+LyXParagraph::size_type
+LyXText::NextBreakPoint(Row const * row, int width) const
 {
-       int x = 0;
-       int last_separator = -1; /* position of the last possible breakpoint 
-                                 * -1 isn't a suitable value, but a flag */
-       int i = 0;
-       int left_margin;
-       
-       LyXParagraph *par = row->par;
-       int pos = row->pos;
+       LyXParagraph * par = row->par;
+       LyXParagraph::size_type pos = row->pos;
        
        /* table stuff -- begin*/ 
        if (par->table) {
-               while (pos<par->last 
+               while (pos < par->size()
                       && (!par->IsNewline(pos) 
                           || !par->table->IsFirstCell(NumberOfCell(par, pos+1)))) {
-                       if (par->GetChar(pos) == LYX_META_INSET &&
-                           par->GetInset(pos) && par->GetInset(pos)->Display()){
-                               par->GetInset(pos)->SetDisplay(false);
+                       if (par->GetChar(pos) == LyXParagraph::META_INSET &&
+                           par->GetInset(pos) && par->GetInset(pos)->display()){
+                               par->GetInset(pos)->display(false);
                        }
-                       pos++;
+                       ++pos;
                }
                return pos;
        }
        /* table stuff -- end*/ 
        
-       left_margin = LabelEnd(row);
+       // position of the last possible breakpoint 
+       // -1 isn't a suitable value, but a flag
+       LyXParagraph::size_type last_separator = -1;
        width -= RightMargin(row);
-       int main_body = BeginningOfMainBody(par);
-       LyXLayout* layout = lyxstyle.Style(parameters->textclass, par->GetLayout());
-       i = pos;
-       char c;
        
-       if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+       LyXParagraph::size_type main_body = BeginningOfMainBody(par);
+       LyXLayout const & layout =
+               textclasslist.Style(parameters->textclass, par->GetLayout());
+       LyXParagraph::size_type i = pos;
+
+       if (layout.margintype == MARGIN_RIGHT_ADDRESS_BOX) {
                /* special code for right address boxes, only newlines count */
                while (i < par->Last()) {
                        if (par->IsNewline(i)) {
                                last_separator = i;
-                               i = par->Last() - 1;/* this means break  */
-                               x = width;
-                       } else if (par->GetChar(i) == LYX_META_INSET &&
-                                  par->GetInset(i) && par->GetInset(i)->Display()){
-                               par->GetInset(i)->SetDisplay(false);
+                               i = par->Last() - 1; // this means break
+                               //x = width;
+                       } else if (par->GetChar(i) == LyXParagraph::META_INSET &&
+                                  par->GetInset(i) && par->GetInset(i)->display()){
+                               par->GetInset(i)->display(false);
                        }
-                       i++;
+                       ++i;
                }
        } else {
                // Last position is an invariant
-               int const last = par->Last();
-               /* this is the usual handling */ 
-               x = LeftMargin(row);
+               LyXParagraph::size_type const last = 
+                       par->Last();
+               // this is the usual handling
+               int x = LeftMargin(row);
                while (x < width && i < last) {
-                       c = par->GetChar(i);
+                       char c = par->GetChar(i);
                        if (IsNewlineChar(c)) {
                                last_separator = i;
-                               x = width;                     /* this means break  */
-                       } else if (c == LYX_META_INSET &&
-                                  par->GetInset(i) && par->GetInset(i)->Display()){
-                               /* check wether a Display() inset is valid here .
-                                  if not, change it to non-display*/ 
-                               if (layout->isCommand()
-                                   || (layout->labeltype == LABEL_MANUAL
+                               x = width; // this means break
+                       } else if (c == LyXParagraph::META_INSET &&
+                                  par->GetInset(i) && par->GetInset(i)->display()){
+                               // check wether a Display() inset is
+                               // valid here. if not, change it to
+                               // non-display
+                               if (layout.isCommand()
+                                   || (layout.labeltype == LABEL_MANUAL
                                        && i < BeginningOfMainBody(par))){
-                                       /* display istn't allowd */ 
-                                       par->GetInset(i)->SetDisplay(false);
+                                       // display istn't allowd
+                                       par->GetInset(i)->display(false);
                                        x += SingleWidth(par, i, c);
                                } else {
-                                       /* inset is display. So break the line here */ 
-                                       if (i==pos){
+                                       // inset is display. So break the line here
+                                       if (i == pos){
                                                if (pos < last-1) {
                                                        last_separator = i;
                                                        if (IsLineSeparatorChar(par->GetChar(i+1)))
-                                                               last_separator++;
+                                                               ++last_separator;
                                                } else
                                                        last_separator = last; // to avoid extra rows
                                        } else
                                                last_separator = i - 1;
-                                       x = width;                     /* this means break  */
+                                       x = width;  // this means break
                                }
                        } else  {
                                if (IsLineSeparatorChar(c))
                                        last_separator = i;
                                x += SingleWidth(par, i, c);
                        }
-                       i++;
+                       ++i;
                        if (i == main_body) {
-                               x += GetFont(par, -2).stringWidth(layout->labelsep);
+                               x += GetFont(par, -2).stringWidth(layout.labelsep);
                                if (par->IsLineSeparator(i - 1))
                                        x-= SingleWidth(par, i - 1);
+                               int left_margin = LabelEnd(row);
                                if (x < left_margin)
                                        x = left_margin;
                        }
                }
-               /* end of paragraph is always a suitable separator */
+               // end of paragraph is always a suitable separator
                if (i == last && x < width)
                        last_separator = i;
        }
        
-       /* well, if last_separator is still 0, the line isn't breakable. 
-        * don't care and cut simply at the end */
+       // well, if last_separator is still 0, the line isn't breakable. 
+       // don't care and cut simply at the end
        if (last_separator < 0) {
                last_separator = i;
        }
        
-       /* manual labels cannot be broken in LaTeX, do not care  */
+       // manual labels cannot be broken in LaTeX, do not care
        if (main_body && last_separator < main_body)
                last_separator = main_body - 1;
        
@@ -699,239 +999,236 @@ int LyXText::NextBreakPoint(Row* row, int width)
 }
 
 
-/* returns the minimum space a row needs on the screen in pixel */
-int LyXText::Fill(Row *row, int paperwidth)
+// returns the minimum space a row needs on the screen in pixel
+int LyXText::Fill(Row const * row, int paper_width) const
 {
-   int w,i, last, fill, left_margin;
-   /* get the pure distance */
-   last = RowLast(row);
-   
-   /* table stuff -- begin*/
-   if (row->par->table) {
-      /* for tables FILL does calculate the widthes of each cell in 
-       * the row */ 
-      int pos = row->pos;
-      int cell = NumberOfCell(row->par, pos);
-      w = 0;
-      do {
-        row->par->table->SetWidthOfCell(cell, WidthOfCell(row->par, pos));
-        cell++;
-      } while (pos <= last && !row->par->table->IsFirstCell(cell));
-      /* don't forget the very last table cell without characters */
-      if (cell == row->par->table->GetNumberOfCells()-1)
-          row->par->table->SetWidthOfCell(cell, WidthOfCell(row->par, pos));
-      
-      return 0; /* width of table cannot be returned since
-                * we cannot guarantee its correct value at
-                * this point. */ 
-   }
-   /* table stuff -- end*/ 
-
-   left_margin = LabelEnd(row);
-
-     /* if the row ends with newline, this newline will not be relevant */ 
-     if (last >= 0 && row->par->IsNewline(last))
-       last--;
-     
-     /* if the row ends with a space, this space will not be relevant */ 
-     if (last >= 0 && row->par->IsLineSeparator(last))
-       last--;
-
-   /* special handling of the right address boxes */ 
-   if (lyxstyle.Style(parameters->textclass, row->par->GetLayout())->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
-      int tmpfill = row->fill;
-      row->fill = 0;                  /* the minfill in MarginLeft()  */
-      w = LeftMargin(row);
-      row->fill = tmpfill;
-      
-      /* the old way, impossible when using environments: */ 
-      /*  w = LyXStringWidth(lyxstyle.Style(parameters->textclass, row->par->GetLayout())->font, */ 
-      /*                        lyxstyle.Style(parameters->textclass, row->par->GetLayout())->leftmargin); */
-   }
-   else
-     w = LeftMargin(row);
-   
-   int main_body = BeginningOfMainBody(row->par);
-   LyXLayout *layout = lyxstyle.Style(parameters->textclass,
-                                     row->par->GetLayout());
-   i = row->pos;
-   while (i<= last) {
-      w += SingleWidth(row->par, i);
-      i++;
-      if (i == main_body) {
-        w += GetFont(row->par, -2).stringWidth(layout->labelsep);
-        if (row->par->IsLineSeparator(i - 1))
-          w-= SingleWidth(row->par, i - 1);
-        if (w < left_margin)
-          w = left_margin;
-      }
-   }
-   
-   fill = paperwidth - w - RightMargin(row);
-   return fill;
+       int w, fill;
+       // get the pure distance
+       LyXParagraph::size_type last = RowLast(row);
+       /* table stuff -- begin */
+       if (row->par->table) {
+               // for tables FILL does calculate the widthes of each cell in 
+               // the row
+               LyXParagraph::size_type pos = row->pos;
+               int cell = NumberOfCell(row->par, pos);
+               w = 0;
+               do {
+                       row->par->table->SetWidthOfCell(cell,
+                                                       WidthOfCell(row->par,
+                                                                   pos));
+                       ++cell;
+               } while (pos <= last && !row->par->table->IsFirstCell(cell));
+               // don't forget the very last table cell without characters
+               if (cell == row->par->table->GetNumberOfCells() - 1)
+                       row->par->table->SetWidthOfCell(cell,
+                                                       WidthOfCell(row->par,
+                                                                   pos));
+               
+               return 0; /* width of table cannot be returned since
+                          * we cannot guarantee its correct value at
+                          * this point. */ 
+       }
+       /* table stuff -- end*/ 
+               
+       // if the row ends with newline, this newline will not be relevant
+       //if (last >= 0 && row->par->IsNewline(last))
+       //      --last;
+       
+       // if the row ends with a space, this space will not be relevant
+       if (last >= 0 && row->par->IsLineSeparator(last))
+               --last;
+       
+       // special handling of the right address boxes
+       if (textclasslist.Style(parameters->textclass,
+                               row->par->GetLayout()).margintype
+           == MARGIN_RIGHT_ADDRESS_BOX) {
+               int tmpfill = row->fill;
+               row->fill = 0; // the minfill in MarginLeft()
+               w = LeftMargin(row);
+               row->fill = tmpfill;
+       } else
+               w = LeftMargin(row);
+       
+       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+                                                      row->par->GetLayout());
+       LyXParagraph::size_type main_body = 
+               BeginningOfMainBody(row->par);
+       LyXParagraph::size_type i = row->pos;
+
+       while (i <= last) {
+               if (main_body > 0 && i == main_body) {
+                       w += GetFont(row->par, -2).
+                               stringWidth(layout.labelsep);
+                       if (row->par->IsLineSeparator(i - 1))
+                               w -= SingleWidth(row->par, i - 1);
+                       int left_margin = LabelEnd(row);
+                       if (w < left_margin)
+                               w = left_margin;
+               }
+               w += SingleWidth(row->par, i);
+               ++i;
+       }
+       if (main_body > 0 && main_body > last) {
+               w += GetFont(row->par, -2).stringWidth(layout.labelsep);
+               if (last >= 0 && row->par->IsLineSeparator(last))
+                       w -= SingleWidth(row->par, last);
+               int left_margin = LabelEnd(row);
+               if (w < left_margin)
+                       w = left_margin;
+       }
+       
+       fill = paper_width - w - RightMargin(row);
+       return fill;
 }
 
 
-/* returns the minimum space a manual label needs on the screen in pixel */ 
-int LyXText::LabelFill(Row *row)
+// returns the minimum space a manual label needs on the screen in pixel
+int LyXText::LabelFill(Row const * row) const
 {
-   int w,i, last;
-   int fill=0;
-   
-   last = BeginningOfMainBody(row->par) - 1;
-   /* -1 because a label ends either with a space that is in the label, 
-    * or with the beginning of a footnote that is outside the label. */ 
-
-   // I don't understand this code in depth, but sometimes "last" is less than
-   // 0 and this causes a crash. This fix seems to work correctly, but I
-   // bet the real error is elsewhere.  The bug is triggered when you have an 
-   // open footnote in a paragraph environment with a manual label. (Asger)
-   if (last<0) last = 0;
-
-   if (row->par->IsLineSeparator(last))    /* a sepearator at this end 
-                                       * does not count */
-     last--;
-   
-   w = 0;
-   i = row->pos;
-   while (i<= last) {
-      w += SingleWidth(row->par, i);
-      i++;
-   }
-   
-   if (!row->par->labelwidthstring.empty()) {
-      fill = GetFont(row->par, -2).stringWidth(row->par->labelwidthstring) - w;
-   }
-   
-   if (fill < 0)
-     fill = 0;
-   
-   return fill;
+       LyXParagraph::size_type last = BeginningOfMainBody(row->par) - 1;
+       // -1 because a label ends either with a space that is in the label, 
+       // or with the beginning of a footnote that is outside the label.
+
+       // I don't understand this code in depth, but sometimes "last" is
+       // less than 0 and this causes a crash. This fix seems to work
+       // correctly, but I bet the real error is elsewhere.  The bug is
+       // triggered when you have an open footnote in a paragraph
+       // environment with a manual label. (Asger)
+       if (last < 0) last = 0;
+       
+       if (row->par->IsLineSeparator(last)) /* a sepearator at this end 
+                                               does not count */
+               --last;
+       
+       int w = 0;
+       int i = row->pos;
+       while (i <= last) {
+               w += SingleWidth(row->par, i);
+               ++i;
+       }
+       
+       int fill = 0;
+       if (!row->par->labelwidthstring.empty()) {
+               fill = GetFont(row->par, -2)
+                       .stringWidth(row->par->labelwidthstring) - w;
+       }
+       
+       if (fill < 0)
+               fill = 0;
+       
+       return fill;
 }
 
 
-/* returns the number of separators in the specified row. The separator 
-* on the very last column doesnt count */ 
-int LyXText::NumberOfSeparators(Row *row)
+// returns the number of separators in the specified row. The separator 
+// on the very last column doesnt count
+int LyXText::NumberOfSeparators(Row const * row) const
 {
-   int n,p,last;
-   
-   last = RowLast(row);
-   n = 0;
-   p = row->pos;
-   int main_body = BeginningOfMainBody(row->par);
-   if (p < main_body)
-     p = main_body;
-   for (; p < last; p++) {
-      if (row->par->IsSeparator(p)) {
-        n++;
-      }
-   }
-   return n;
+       int last = RowLast(row);
+       int p = max(row->pos, BeginningOfMainBody(row->par));
+       int n = 0;
+       for (; p < last; ++p) {
+               if (row->par->IsSeparator(p)) {
+                       ++n;
+               }
+       }
+       return n;
 }
 
 
-/* returns the number of hfills in the specified row. The LyX-Hfill is
-* a LaTeX \hfill so that the hfills at the beginning and at the end were 
-* ignored. This is *MUCH* more usefull than not to ignore!  */
-int LyXText::NumberOfHfills(Row *row)
+// returns the number of hfills in the specified row. The LyX-Hfill is
+// a LaTeX \hfill so that the hfills at the beginning and at the end were 
+// ignored. This is *MUCH* more usefull than not to ignore!
+int LyXText::NumberOfHfills(Row const * row) const
 {
-   int n,p,last, first;
-   
-   last = RowLast(row);
-   first = row->pos;
-   if (first) {                               /* hfill *DO* count at the beginning 
-                                       * of paragraphs! */
-     while(first <= last && row->par->IsHfill(first))
-       first++;
-   }
+       int last = RowLast(row);
+       int first = row->pos;
+       if (first) { /* hfill *DO* count at the beginning 
+                     * of paragraphs! */
+               while(first <= last && row->par->IsHfill(first))
+                       ++first;
+       }
 
-   n = 0;
-   int main_body = BeginningOfMainBody(row->par);
-   if (first < main_body)
-     first = main_body;
-   for (p = first; p <= last; p++) {    /* last, because the end is ignored!  */
-      if (row->par->IsHfill(p)) {
-        n++;
-      }
-   }
-   return n;
+       first = max(first, BeginningOfMainBody(row->par));
+       int n = 0;
+       for (int p = first; p <= last; ++p) { // last, because the end is ignored!
+               if (row->par->IsHfill(p)) {
+                       ++n;
+               }
+       }
+       return n;
 }
 
 
-/* like NumberOfHfills, but only those in the manual label! */ 
-int LyXText::NumberOfLabelHfills(Row *row)
+// like NumberOfHfills, but only those in the manual label!
+int LyXText::NumberOfLabelHfills(Row const * row) const
 {
-   int n,p,last, first;
-   
-   last = RowLast(row);
-   first = row->pos;
-   if (first) {                               /* hfill *DO* count at the beginning 
-                                       * of paragraphs! */
-      while(first < last && row->par->IsHfill(first))
-       first++;
-   }
+       LyXParagraph::size_type last = RowLast(row);
+       LyXParagraph::size_type first = row->pos;
+       if (first) { /* hfill *DO* count at the beginning 
+                     * of paragraphs! */
+               while(first < last && row->par->IsHfill(first))
+                       ++first;
+       }
 
-   n = 0;
-   int main_body = BeginningOfMainBody(row->par);
-   
-   if (last > main_body)
-     last = main_body;
-   
-   for (p = first; p < last; p++) {    /* last, because the end is ignored!  */
-      if (row->par->IsHfill(p)) {
-        n++;
-      }
-   }
-   return n;
+       last = min(last, BeginningOfMainBody(row->par));
+       int n = 0;
+       for (LyXParagraph::size_type p = first;
+            p < last; ++p) {  // last, because the end is ignored!
+               if (row->par->IsHfill(p)) {
+                       ++n;
+               }
+       }
+       return n;
 }
 
 
-/* returns true, if a expansion is needed.
- * Rules are given by LaTeX */ 
-bool LyXText::HfillExpansion(Row *row_ptr, int pos)
+// returns true, if a expansion is needed.
+// Rules are given by LaTeX
+bool LyXText::HfillExpansion(Row const * row_ptr,
+                            LyXParagraph::size_type pos) const
 {
-   /* by the way, is it a hfill? */ 
-   if (!row_ptr->par->IsHfill(pos))
-     return false;
-   
-   /* at the end of a row it does not count */ 
-   if (pos >= RowLast(row_ptr))
-     return false;
-   
-   /* at the beginning of a row it does not count, if it is not 
-    * the first row of a paragaph */ 
-   if (!row_ptr->pos)
-     return true;
-   
-   /* in some labels  it does not count */ 
-   if ( lyxstyle.Style(parameters->textclass, row_ptr->par->GetLayout())->margintype != MARGIN_MANUAL &&
-       pos < BeginningOfMainBody(row_ptr->par))
-     return false; 
-   
-   /* if there is anything between the first char of the row and
-    * the sepcified position that is not a newline and not a hfill,
-    * the hfill will count, otherwise not */ 
-   
-   int i = row_ptr->pos;
-   while (i < pos && (row_ptr->par->IsNewline(i)
-                     || row_ptr->par->IsHfill(i)))
-     i++;
-   
-   return (i != pos);
+       // by the way, is it a hfill?
+       if (!row_ptr->par->IsHfill(pos))
+               return false;
+       
+       // at the end of a row it does not count
+       if (pos >= RowLast(row_ptr))
+               return false;
+       
+       // at the beginning of a row it does not count, if it is not 
+       // the first row of a paragaph
+       if (!row_ptr->pos)
+               return true;
+       
+       // in some labels  it does not count
+       if (textclasslist.Style(parameters->textclass,
+                               row_ptr->par->GetLayout()).margintype
+           != MARGIN_MANUAL
+           && pos < BeginningOfMainBody(row_ptr->par))
+               return false; 
+       
+       // if there is anything between the first char of the row and
+       // the sepcified position that is not a newline and not a hfill,
+       // the hfill will count, otherwise not
+       LyXParagraph::size_type i = row_ptr->pos;
+       while (i < pos && (row_ptr->par->IsNewline(i)
+                          || row_ptr->par->IsHfill(i)))
+               ++i;
+       
+       return i != pos;
 }
 
 
-void LyXText::SetHeightOfRow(Row *row_ptr)
+void LyXText::SetHeightOfRow(Row * row_ptr) const
 {
     /* get the maximum ascent and the maximum descent */
-   int asc, maxasc, desc, maxdesc, pos_end, pos, labeladdon;
+   int asc, desc, pos;
    float layoutasc = 0;
    float layoutdesc = 0;
    float tmptop = 0;
-   LyXParagraph *par, *firstpar;
    LyXFont tmpfont;
-   Inset *tmpinset;
+   Inset * tmpinset;
 
    /* this must not happen before the currentrow for clear reasons.
       so the trick is just to set the current row onto this row */
@@ -946,10 +1243,11 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
    /* Correction: only the fontsize count. The other properties
       are taken from the layoutfont. Nicer on the screen :) */
    
-   par = row_ptr->par->LastPhysicalPar();
-   firstpar = row_ptr->par->FirstPhysicalPar();
+   LyXParagraph * par = row_ptr->par->LastPhysicalPar();
+   LyXParagraph * firstpar = row_ptr->par->FirstPhysicalPar();
    
-   LyXLayout *layout = lyxstyle.Style(parameters->textclass, firstpar->GetLayout());
+   LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+                                                 firstpar->GetLayout());
    
    LyXFont font = GetFont(par, par->Last()-1);
    LyXFont::FONT_SIZE size = font.size();
@@ -958,25 +1256,25 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
 
    LyXFont labelfont = GetFont(par, -2);
 
-   maxasc = int(font.maxAscent() *
-                  layout->spacing.getValue() *
+   int maxasc = int(font.maxAscent() *
+                  layout.spacing.getValue() *
                   parameters->spacing.getValue());
-   maxdesc = int(font.maxDescent() *
-                   layout->spacing.getValue() *
+   int maxdesc = int(font.maxDescent() *
+                   layout.spacing.getValue() *
                    parameters->spacing.getValue());
 
-   pos_end = RowLast(row_ptr);
+   int pos_end = RowLast(row_ptr);
    
-   labeladdon = 0;
+   int labeladdon = 0;
 
    // Check if any insets are larger
-   for (pos = row_ptr->pos; pos <= pos_end; pos++) {
-      if (row_ptr->par->GetChar(pos) == LYX_META_INSET) {
+   for (pos = row_ptr->pos; pos <= pos_end; ++pos) {
+      if (row_ptr->par->GetChar(pos) == LyXParagraph::META_INSET) {
         tmpfont = GetFont(row_ptr->par, pos);
          tmpinset = row_ptr->par->GetInset(pos);
          if (tmpinset) {
-            asc = tmpinset->Ascent(tmpfont);
-            desc = tmpinset->Descent(tmpfont);
+            asc = tmpinset->ascent(owner_->painter(), tmpfont);
+            desc = tmpinset->descent(owner_->painter(), tmpfont);
            if (asc > maxasc) 
              maxasc = asc;
            if (desc > maxdesc)
@@ -988,7 +1286,8 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
    // Check if any custom fonts are larger (Asger)
    // This is not completely correct, but we can live with the small,
    // cosmetic error for now.
-   LyXFont::FONT_SIZE maxsize = row_ptr->par->HighestFontInRange(row_ptr->pos, pos_end);
+   LyXFont::FONT_SIZE maxsize = row_ptr->par->HighestFontInRange(row_ptr->pos,
+                                                                pos_end);
    if (maxsize > font.size()) {
        font.setSize(maxsize);
 
@@ -1004,13 +1303,13 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
    if (row_ptr->par->table){
      // stretch the rows a bit
       maxasc += 1;
-      maxdesc +=1;
+      maxdesc += 1;
    }
    /* table stuff -- end*/
 
    // This is nicer with box insets:
-   maxasc++;
-   maxdesc++;
+   ++maxasc;
+   ++maxdesc;
 
    row_ptr->ascent_of_text = maxasc;
    
@@ -1019,17 +1318,17 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
        && row_ptr->par == firstpar) {
       
       /* some parksips VERY EASY IMPLEMENTATION */ 
-      if (parameters->paragraph_separation == LYX_PARSEP_SKIP) {
-        if (layout->isParagraph()
+      if (parameters->paragraph_separation == BufferParams::PARSEP_SKIP) {
+        if (layout.isParagraph()
             && firstpar->GetDepth() == 0
             && firstpar->Previous())
-           maxasc += parameters->getDefSkip().inPixels();
+           maxasc += parameters->getDefSkip().inPixels(owner_);
         else if (firstpar->Previous()
-                 && lyxstyle.Style(parameters->textclass,
-                          firstpar->Previous()->GetLayout())->isParagraph()
+                 && textclasslist.Style(parameters->textclass,
+                          firstpar->Previous()->GetLayout()).isParagraph()
                  && firstpar->Previous()->GetDepth() == 0)
           // is it right to use defskip here too? (AS)
-          maxasc += parameters->getDefSkip().inPixels();
+          maxasc += parameters->getDefSkip().inPixels(owner_);
       }
       
       /* the paper margins */ 
@@ -1038,7 +1337,7 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
       
       /* add the vertical spaces, that the user added */
       if (firstpar->added_space_top.kind() != VSpace::NONE)
-        maxasc += int(firstpar->added_space_top.inPixels());
+        maxasc += int(firstpar->added_space_top.inPixels(owner_));
       
       /* do not forget the DTP-lines! 
        * there height depends on the font of the nearest character */
@@ -1051,57 +1350,57 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
       
       /*  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
-         && parameters->secnumdepth>=0) {
+      if (layout.labeltype == LABEL_COUNTER_CHAPTER
+         && parameters->secnumdepth>= 0) {
              labeladdon = int(labelfont.maxDescent() *
-                                 layout->spacing.getValue() *
+                                 layout.spacing.getValue() *
                                  parameters->spacing.getValue())
                      + int(labelfont.maxAscent() *
-                              layout->spacing.getValue() *
+                              layout.spacing.getValue() *
                               parameters->spacing.getValue());
       }
       
       /* 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->GetLabestring().empty()) {
         labeladdon = int(
                 (labelfont.maxAscent() *
-                 layout->spacing.getValue() *
+                 layout.spacing.getValue() *
                  parameters->spacing.getValue())
                 +(labelfont.maxDescent() *
-                  layout->spacing.getValue() *
+                  layout.spacing.getValue() *
                   parameters->spacing.getValue())
-                + layout->topsep * DefaultHeight()
-                + layout->labelbottomsep *  DefaultHeight());
+                + layout.topsep * DefaultHeight()
+                + layout.labelbottomsep *  DefaultHeight());
       }
    
       /* and now the layout spaces, for example before and after a section, 
        * or between the items of a itemize or enumerate environment */ 
       
       if (!firstpar->pagebreak_top) {
-        LyXParagraph *prev = row_ptr->par->Previous();
+        LyXParagraph * prev = row_ptr->par->Previous();
         if (prev)
            prev = row_ptr->par->DepthHook(row_ptr->par->GetDepth());
         if (prev && prev->GetLayout() == firstpar->GetLayout()
             && 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-=lyxstyle.Style(parameters->textclass, row_ptr->previous->par->GetLayout())->bottomsep;
+              tmptop-= textclasslist.Style(parameters->textclass, row_ptr->previous->par->GetLayout()).bottomsep;
            
            if (tmptop > 0)
               layoutasc = (tmptop * DefaultHeight());
         }
         else if (row_ptr->par->line_top){
-           tmptop = layout->topsep;
+           tmptop = layout.topsep;
            
            if (tmptop > 0)
               layoutasc = (tmptop * DefaultHeight());
@@ -1109,8 +1408,8 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
         
         prev = row_ptr->par->DepthHook(row_ptr->par->GetDepth()-1);
         if (prev)  {
-           maxasc += int(lyxstyle.Style(parameters->textclass,
-                                        prev->GetLayout())->parsep * DefaultHeight());
+           maxasc += int(textclasslist.Style(parameters->textclass,
+                                        prev->GetLayout()).parsep * DefaultHeight());
         }
         else {
                if (firstpar->Previous()
@@ -1119,7 +1418,7 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
                   /* avoid parsep */ 
                }
            else if (firstpar->Previous()){
-              maxasc += int(layout->parsep * DefaultHeight());
+              maxasc += int(layout.parsep * DefaultHeight());
            }
         }
       }
@@ -1135,7 +1434,7 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
        
          /* add the vertical spaces, that the user added */
          if (firstpar->added_space_bottom.kind() != VSpace::NONE)
-           maxdesc += int(firstpar->added_space_bottom.inPixels());
+           maxdesc += int(firstpar->added_space_bottom.inPixels(owner_));
          
          /* do not forget the DTP-lines! 
           * there height depends on the font of the nearest character */
@@ -1149,18 +1448,18 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
          /* and now the layout spaces, for example before and after a section, 
           * or between the items of a itemize or enumerate environment */
          if (!firstpar->pagebreak_bottom && row_ptr->par->Next()) {
-            LyXParagraph *nextpar = row_ptr->par->Next();
-            LyXParagraph *comparepar = row_ptr->par;
+            LyXParagraph * nextpar = row_ptr->par->Next();
+            LyXParagraph * comparepar = row_ptr->par;
             float usual = 0;
             float  unusual = 0;
             
             if (comparepar->GetDepth() > nextpar->GetDepth()) {
-               usual = (lyxstyle.Style(parameters->textclass, comparepar->GetLayout())->bottomsep * DefaultHeight());
+               usual = (textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
                comparepar = comparepar->DepthHook(nextpar->GetDepth());
-               if (comparepar->GetLayout()!=nextpar->GetLayout()
+               if (comparepar->GetLayout()!= nextpar->GetLayout()
                    || nextpar->GetLabelWidthString() != 
                        comparepar->GetLabelWidthString())
-                 unusual = (lyxstyle.Style(parameters->textclass, comparepar->GetLayout())->bottomsep * DefaultHeight());
+                 unusual = (textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
                
                if (unusual > usual)
                  layoutdesc = unusual;
@@ -1170,9 +1469,9 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
             else if (comparepar->GetDepth() ==  nextpar->GetDepth()) {
                
                if (comparepar->GetLayout()!= nextpar->GetLayout()
-                   || nextpar->GetLabelWidthString() !=
+                   || nextpar->GetLabelWidthString() != 
                        comparepar->GetLabelWidthString())
-                 layoutdesc = int(lyxstyle.Style(parameters->textclass, comparepar->GetLayout())->bottomsep * DefaultHeight());
+                 layoutdesc = int(textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
             }
          }
        }
@@ -1191,8 +1490,8 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
    /* calculate the new height of the text */ 
    height -= row_ptr->height;
    
-   row_ptr->height=maxasc+maxdesc+labeladdon;
-   row_ptr->baseline=maxasc+labeladdon;
+   row_ptr->height = maxasc + maxdesc + labeladdon;
+   row_ptr->baseline = maxasc + labeladdon;
    
    height += row_ptr->height;
 }
@@ -1200,28 +1499,23 @@ void LyXText::SetHeightOfRow(Row *row_ptr)
 
 /* Appends the implicit specified paragraph behind the specified row,
  * start at the implicit given position */
-void LyXText::AppendParagraph(Row *row)
+void LyXText::AppendParagraph(Row * row) const
 {
-   int z;
-   Row *tmprow;
    bool not_ready = true;
    
-   // Get the width of the row
-   z = row->pos;
-
    // The last character position of a paragraph is an invariant so we can 
    // safely get it here. (Asger)
    int lastposition = row->par->Last();
 
    do {
       // Get the next breakpoint
-      z = NextBreakPoint(row, paperwidth);
+      int z = NextBreakPoint(row, paperwidth);
       
-      tmprow = row;
+      Row * tmprow = row;
 
       // Insert the new row
       if (z < lastposition) {
-        z++;
+        ++z;
         InsertRow(row, row->par, z);
         row = row->next;
 
@@ -1237,43 +1531,36 @@ void LyXText::AppendParagraph(Row *row)
 }
 
 
-void LyXText::BreakAgain(Row *row)
+void LyXText::BreakAgain(Row * row) const
 {
-   int z;
-   char not_ready;
-   z = row->pos;
-   Row *tmprow, *tmprow2;
-   
-   not_ready = 1;
+   bool not_ready = true;
    
    do  {
       /* get the next breakpoint */
-      z = NextBreakPoint(row, paperwidth);
-      
-      tmprow = row;
+       LyXParagraph::size_type z = 
+               NextBreakPoint(row, paperwidth);
+      Row * tmprow = row;
       
       if (z < row->par->Last() ) {
         if (!row->next || (row->next && row->next->par != row->par)) {
-           /* insert a new row */ 
-           z++;
+                // insert a new row
+           ++z;
            InsertRow(row, row->par, z);
            row = row->next;
            row->height = 0;
-        }
-        else  {
-           row=row->next;
-           z++;
+        } else  {
+           row = row->next;
+           ++z;
            if (row->pos == z)
-             not_ready = 0;           /* the rest will not change  */
+                   not_ready = false;     // the rest will not change
            else {
               row->pos = z;
            }
         }
-      }
-      else {
+      } else {
         /* if there are some rows too much, delete them */
         /* only if you broke the whole paragraph! */ 
-        tmprow2 = row;
+        Row * tmprow2 = row;
         while (tmprow2->next && tmprow2->next->par == row->par) {
            tmprow2 = tmprow2->next;
         }
@@ -1281,7 +1568,7 @@ void LyXText::BreakAgain(Row *row)
            tmprow2 = tmprow2->previous;
            RemoveRow(tmprow2->next);
         }
-        not_ready = 0;
+        not_ready = false;
       }
        
       /* set the dimensions of the row */ 
@@ -1292,42 +1579,31 @@ void LyXText::BreakAgain(Row *row)
 
 
 /* this is just a little changed version of break again */ 
-void LyXText::BreakAgainOneRow(Row *row)
+void LyXText::BreakAgainOneRow(Row * row)
 {
-   int z;
-   char not_ready;
-   z = row->pos;
-   Row *tmprow, *tmprow2;
-   
-   not_ready = 1;
-   
    /* get the next breakpoint */
-   z = NextBreakPoint(row, paperwidth);
-   
-   tmprow = row;
+   LyXParagraph::size_type z = NextBreakPoint(row, paperwidth);
+   Row * tmprow = row;
    
    if (z < row->par->Last() ) {
       if (!row->next || (row->next && row->next->par != row->par)) {
         /* insert a new row */ 
-        z++;
+        ++z;
         InsertRow(row, row->par, z);
         row = row->next;
         row->height = 0;
       }
       else  {
-        row=row->next;
-        z++;
-        if (row->pos == z)
-          not_ready = 0;              /* the rest will not change  */
-        else {
+        row= row->next;
+        ++z;
+        if (row->pos != z)
            row->pos = z;
-        }
       }
    }
    else {
       /* if there are some rows too much, delete them */
       /* only if you broke the whole paragraph! */ 
-      tmprow2 = row;
+      Row * tmprow2 = row;
       while (tmprow2->next && tmprow2->next->par == row->par) {
         tmprow2 = tmprow2->next;
       }
@@ -1335,7 +1611,6 @@ void LyXText::BreakAgainOneRow(Row *row)
         tmprow2 = tmprow2->previous;
         RemoveRow(tmprow2->next);
       }
-      not_ready = 0;
    }
    
    /* set the dimensions of the row */ 
@@ -1346,48 +1621,49 @@ void LyXText::BreakAgainOneRow(Row *row)
 
 void LyXText::BreakParagraph(char keep_layout)
 {
-   LyXLayout *layout = lyxstyle.Style(parameters->textclass,
+   LyXLayout const & layout = textclasslist.Style(parameters->textclass,
                                      cursor.par->GetLayout());
    
-   /* table stuff -- begin*/
+   /* table stuff -- begin */
    if (cursor.par->table) {
        // breaking of tables is only allowed at the beginning or the end */
-       if (cursor.pos && cursor.pos < cursor.par->last &&
+       if (cursor.pos && cursor.pos < cursor.par->size() &&
            !cursor.par->table->ShouldBeVeryLastCell(NumberOfCell(cursor.par, cursor.pos)))
-           return; /* no breaking of tables allowed */ 
+              return; // no breaking of tables allowed
    }
-   /* table stuff -- end*/
+   /* table stuff -- end */
 
-   /* this is only allowed, if the current paragraph is not empty or caption*/ 
+   // this is only allowed, if the current paragraph is not empty or caption
    if ((cursor.par->Last() <= 0 && !cursor.par->IsDummy())
        && 
-       layout->labeltype!=LABEL_SENSITIVE)
+       layout.labeltype!= LABEL_SENSITIVE)
      return;
 
    SetUndo(Undo::INSERT, 
           cursor.par->ParFromPos(cursor.pos)->previous, 
           cursor.par->ParFromPos(cursor.pos)->next); 
 
-   /* table stuff -- begin*/
+   /* table stuff -- begin */
    if (cursor.par->table) {
        int cell = NumberOfCell(cursor.par, cursor.pos);
        if (cursor.par->table->ShouldBeVeryLastCell(cell))
-           SetCursor(cursor.par,cursor.par->last);
+           SetCursor(cursor.par, cursor.par->size());
    }
-   /* table stuff -- end*/
-   /* please break alway behind a space */ 
+   /* table stuff -- end */
+   
+   // please break always behind a space
    if (cursor.pos < cursor.par->Last()
        && cursor.par->IsLineSeparator(cursor.pos))
      cursor.pos++;
    
-   /* break the paragraph */
+   // break the paragraph
    if (keep_layout)
      keep_layout = 2;
    else        
-     keep_layout = layout->isEnvironment();
+     keep_layout = layout.isEnvironment();
    cursor.par->BreakParagraph(cursor.pos, keep_layout);
 
-   /* table stuff -- begin*/
+   /* table stuff -- begin */
    if (cursor.par->table){
      // the table should stay with the contents
      if (!cursor.pos){
@@ -1395,19 +1671,18 @@ void LyXText::BreakParagraph(char keep_layout)
        cursor.par->table = 0;
      }
    }
-   /* table stuff -- end*/
+   /* table stuff -- end */
 
-   /* well this is the caption hack since one caption is really enough */
-   if (layout->labeltype == LABEL_SENSITIVE){
+   // well this is the caption hack since one caption is really enough
+   if (layout.labeltype == LABEL_SENSITIVE){
      if (!cursor.pos)
-       cursor.par->SetLayout(0); /* set the new paragraph to standard-layout */
+            cursor.par->SetLayout(0); // set to standard-layout
      else
-       cursor.par->Next()->SetLayout(0); /* set the new paragraph to standard-layout */
-        
+            cursor.par->Next()->SetLayout(0); // set to standard-layout
    }
    
    /* if the cursor is at the beginning of a row without prior newline, 
-    *  move one row up! 
+    * 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) &&
@@ -1419,8 +1694,8 @@ void LyXText::BreakParagraph(char keep_layout)
    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) {
+   // 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;
@@ -1429,7 +1704,7 @@ void LyXText::BreakParagraph(char keep_layout)
    }
    RemoveParagraph(cursor.row);
    
-   /* set the dimensions of the cursor row */
+   // set the dimensions of the cursor row
    cursor.row->fill = Fill(cursor.row, paperwidth);
 
    SetHeightOfRow(cursor.row);
@@ -1442,7 +1717,7 @@ void LyXText::BreakParagraph(char keep_layout)
 
    UpdateCounters(cursor.row->previous);
    
-   /* this check is necessary. Otherwise the new empty paragraph will
+   /* This check is necessary. Otherwise the new empty paragraph will
     * be deleted automatically. And it is more friendly for the user! */ 
    if (cursor.pos)
      SetCursor(cursor.par->Next(), 0);
@@ -1458,10 +1733,10 @@ void LyXText::BreakParagraph(char keep_layout)
 
 void LyXText::OpenFootnote()
 {
-   LyXParagraph *par, *endpar,*tmppar;
-   Row *row;
+   LyXParagraph * endpar,* tmppar;
+   Row * row;
    
-   par = cursor.par->ParFromPos(cursor.pos);
+   LyXParagraph * par = cursor.par->ParFromPos(cursor.pos);
    
    /* if there is no footnote in this paragraph, just return. */ 
    if (!par->next
@@ -1471,9 +1746,11 @@ void LyXText::OpenFootnote()
    /* ok, move the cursor right before the footnote */ 
    
    /* just a little faster than using CursorRight() */
-   for (cursor.pos=0; cursor.par->ParFromPos(cursor.pos)!=par; cursor.pos++);
+   for (cursor.pos = 0;
+       cursor.par->ParFromPos(cursor.pos) != par; cursor.pos++);
    /* now the cursor is at the beginning of the physical par */
-   SetCursor(cursor.par, cursor.pos + cursor.par->ParFromPos(cursor.pos)->last);
+   SetCursor(cursor.par,
+            cursor.pos + cursor.par->ParFromPos(cursor.pos)->size());
    
    /* the cursor must be exactly before the footnote */ 
    par = cursor.par->ParFromPos(cursor.pos);
@@ -1491,6 +1768,7 @@ void LyXText::OpenFootnote()
    /* set the dimensions of the cursor row */
    row->fill = Fill(row, paperwidth);
    SetHeightOfRow(row);
+#warning See comment on top of text.C
    tmppar = tmppar->Next();
    
    while (tmppar != endpar) {
@@ -1508,69 +1786,64 @@ void LyXText::OpenFootnote()
 
 /* table stuff -- begin*/
 
-void LyXText::TableFeatures(int feature, string val)
+void LyXText::TableFeatures(int feature, string const & val) const
 {
-    int
-        actCell;
-    
-    if (!cursor.par->table)
-        return; /* this should never happen */
+       if (!cursor.par->table)
+               return; /* this should never happen */
   
-    actCell = NumberOfCell(cursor.par, cursor.pos);
-    SetUndo(Undo::FINISH, 
-            cursor.par->ParFromPos(cursor.pos)->previous, 
-            cursor.par->ParFromPos(cursor.pos)->next); 
-
-    switch (feature){
-      case LyXTable::SET_PWIDTH:
-          cursor.par->table->SetPWidth(actCell,val);
-          break;
-      case LyXTable::SET_SPECIAL_COLUMN:
-      case LyXTable::SET_SPECIAL_MULTI:
-          cursor.par->table->SetAlignSpecial(actCell,val,feature);
-          break;
-      default:
-          break;
-    }
-    RedoParagraph();
+       int actCell = NumberOfCell(cursor.par, cursor.pos);
+       SetUndo(Undo::FINISH, 
+               cursor.par->ParFromPos(cursor.pos)->previous, 
+               cursor.par->ParFromPos(cursor.pos)->next); 
+       
+       switch (feature){
+       case LyXTable::SET_PWIDTH:
+               cursor.par->table->SetPWidth(actCell, val);
+               break;
+       case LyXTable::SET_SPECIAL_COLUMN:
+       case LyXTable::SET_SPECIAL_MULTI:
+               cursor.par->table->SetAlignSpecial(actCell, val, feature);
+               break;
+       default:
+               break;
+       }
+       RedoParagraph();
 }
 
 
-void LyXText::TableFeatures(int feature)
+void LyXText::TableFeatures(int feature) const
 {
-    int
-        setLines = 0,
-        setAlign = LYX_ALIGN_LEFT,
-        lineSet,
-        actCell;
-    bool
-        what;
+       int setLines = 0;
+       int setAlign = LYX_ALIGN_LEFT;
+       int lineSet;
+       bool what;
     
     if (!cursor.par->table)
         return; /* this should never happen */
   
-    actCell = NumberOfCell(cursor.par, cursor.pos);
+    int actCell = NumberOfCell(cursor.par, cursor.pos);
     SetUndo(Undo::FINISH, 
             cursor.par->ParFromPos(cursor.pos)->previous, 
             cursor.par->ParFromPos(cursor.pos)->next); 
 
     switch (feature){
       case LyXTable::ALIGN_LEFT:
-          setAlign=LYX_ALIGN_LEFT;
+          setAlign= LYX_ALIGN_LEFT;
           break;
       case LyXTable::ALIGN_RIGHT:
-          setAlign=LYX_ALIGN_RIGHT;
+          setAlign= LYX_ALIGN_RIGHT;
           break;
       case LyXTable::ALIGN_CENTER:
-          setAlign=LYX_ALIGN_CENTER;
+          setAlign= LYX_ALIGN_CENTER;
           break;
       default:
           break;
     }
     switch (feature){
       case LyXTable::APPEND_ROW: {
-         int pos = cursor.pos;
-          /* move to the next row */
+             LyXParagraph::size_type pos = cursor.pos;
+
+             /* move to the next row */
           int cell_org = actCell;
           int cell = cell_org;
 
@@ -1582,38 +1855,41 @@ void LyXText::TableFeatures(int feature)
                     !cursor.par->table->IsContRow(cell)) {
                   while (pos < cursor.par->Last() &&
                          !cursor.par->IsNewline(pos))
-                      pos++;
+                      ++pos;
                   if (pos < cursor.par->Last())
-                      pos++;
-                  cell++;
+                      ++pos;
+                  ++cell;
               }
               while((pos < cursor.par->Last()) &&
                     cursor.par->table->IsContRow(cell)) {
                   while (pos < cursor.par->Last() &&
                          !cursor.par->IsNewline(pos))
-                      pos++;
+                      ++pos;
                   if (pos < cursor.par->Last())
-                      pos++;
-                  cell++;
+                      ++pos;
+                  ++cell;
               }
               cell_org = --cell;
               if (pos < cursor.par->Last())
-                  pos--;
+                  --pos;
           }
           while (pos < cursor.par->Last() && 
                  (cell == cell_org || !cursor.par->table->IsFirstCell(cell))){
               while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos))
-                  pos++;
+                  ++pos;
               if (pos < cursor.par->Last())
-                  pos++;
-              cell++;
+                  ++pos;
+              ++cell;
           }
                
           /* insert the new cells */ 
           int number = cursor.par->table->NumberOfCellsInRow(cell_org);
-          int i;
-          for (i=0; i<number; i++)
-              cursor.par->InsertChar(pos, LYX_META_NEWLINE);
+         Language const * lang = cursor.par->getParLanguage();
+         LyXFont font(LyXFont::ALL_INHERIT,lang);
+          for (int i = 0; i < number; ++i) {
+              cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE);
+             cursor.par->SetFont(pos, font);
+         }
                
           /* append the row into the table */
           cursor.par->table->AppendRow(cell_org);
@@ -1621,7 +1897,7 @@ void LyXText::TableFeatures(int feature)
           return;
       }
       case LyXTable::APPEND_CONT_ROW: {
-          int pos = cursor.pos;
+             LyXParagraph::size_type pos = cursor.pos;
           /* move to the next row */
           int cell_org = actCell;
           int cell = cell_org;
@@ -1639,43 +1915,52 @@ void LyXText::TableFeatures(int feature)
                  (cell == cell_org
                   || !cursor.par->table->IsFirstCell(cell))){
               while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos))
-                  pos++;
+                  ++pos;
               if (pos < cursor.par->Last())
-                  pos++;
-              cell++;
+                  ++pos;
+              ++cell;
           }
                
           /* insert the new cells */ 
           int number = cursor.par->table->NumberOfCellsInRow(cell_org);
-          int i;
-          for (i=0; i<number; i++)
-              cursor.par->InsertChar(pos, LYX_META_NEWLINE);
-               
+         Language const * lang = cursor.par->getParLanguage();
+         LyXFont font(LyXFont::ALL_INHERIT,lang);
+          for (int i = 0; i < number; ++i) {
+              cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE);
+             cursor.par->SetFont(pos, font);
+         }
+
           /* append the row into the table */
           cursor.par->table->AppendContRow(cell_org);
           RedoParagraph();
           return;
       }
-      case LyXTable::APPEND_COLUMN: { 
-          int pos = 0;
+      case LyXTable::APPEND_COLUMN: {
+             LyXParagraph::size_type pos = 0;
           int cell_org = actCell;
           int cell = 0;
+         Language const * lang = cursor.par->getParLanguage();
+         LyXFont font(LyXFont::ALL_INHERIT,lang);
           do{
               if (pos && (cursor.par->IsNewline(pos-1))){
-                  if (cursor.par->table->AppendCellAfterCell(cell_org, cell)){
-                      cursor.par->InsertChar(pos, LYX_META_NEWLINE);
-                      if (pos<=cursor.pos)
+                  if (cursor.par->table->AppendCellAfterCell(cell_org, cell)) {
+                      cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE);
+                     cursor.par->SetFont(pos, font);
+                      if (pos <= cursor.pos)
                           cursor.pos++;
-                      pos++;
+                      ++pos;
                   }
-                  cell++;
+                  ++cell;
               }
-              pos++;
-          } while (pos<= cursor.par->Last());
+              ++pos;
+          } while (pos <= cursor.par->Last());
           /* remember that the very last cell doesn't end with a newline.
-             This saves one byte memory per table ;-) */ 
-          if (cursor.par->table->AppendCellAfterCell(cell_org, cell))
-              cursor.par->InsertChar(cursor.par->Last(), LYX_META_NEWLINE);
+             This saves one byte memory per table ;-) */
+          if (cursor.par->table->AppendCellAfterCell(cell_org, cell)) {
+                 LyXParagraph::size_type last = cursor.par->Last();
+                 cursor.par->InsertChar(last, LyXParagraph::META_NEWLINE);
+                 cursor.par->SetFont(last, font);
+         }
                
           /* append the column into the table */ 
           cursor.par->table->AppendColumn(cell_org);
@@ -1684,18 +1969,18 @@ void LyXText::TableFeatures(int feature)
           return;
       }
       case LyXTable::DELETE_ROW:
-          if (current_view->currentBuffer()->the_locking_inset)
-              UnlockInset(current_view->currentBuffer()->the_locking_inset);
+          if (owner_->the_locking_inset)
+              owner_->unlockInset(owner_->the_locking_inset);
           RemoveTableRow(&cursor);
           RedoParagraph();
           return;
        
       case LyXTable::DELETE_COLUMN: {
-          int pos = 0;
+             LyXParagraph::size_type pos = 0;
           int cell_org = actCell;
           int cell = 0;
-          if (current_view->currentBuffer()->the_locking_inset)
-              UnlockInset(current_view->currentBuffer()->the_locking_inset);
+          if (owner_->the_locking_inset)
+              owner_->unlockInset(owner_->the_locking_inset);
           do {
               if (!pos || (cursor.par->IsNewline(pos-1))){
                   if (cursor.par->table->DeleteCellIfColumnIsDeleted(cell, cell_org)){
@@ -1706,12 +1991,12 @@ void LyXText::TableFeatures(int feature)
                           cursor.par->Erase(pos);
                       else 
                           cursor.par->Erase(pos - 1); // the missing newline at the end of a table
-                      pos--; // because of pos++ below
+                      --pos; // because of pos++ below
                   }   
-                  cell++;
+                  ++cell;
               }
-              pos++;
-          } while (pos<= cursor.par->Last());
+              ++pos;
+          } while (pos <= cursor.par->Last());
                
           /* delete the column from the table */ 
           cursor.par->table->DeleteColumn(cell_org);
@@ -1724,12 +2009,13 @@ void LyXText::TableFeatures(int feature)
       case LyXTable::TOGGLE_LINE_TOP:
           lineSet = !cursor.par->table->TopLine(actCell);
           if (!selection){
-              cursor.par->table->SetTopLine(actCell,lineSet);
+              cursor.par->table->SetTopLine(actCell, lineSet);
           } else {
-              int i,n=-1,m=-2;
-              for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){
-                  if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
-                      cursor.par->table->SetTopLine(n,lineSet);
+                 LyXParagraph::size_type i;
+                 int n = -1, m = -2;
+              for (i = sel_start_cursor.pos; i <= sel_end_cursor.pos; ++i){
+                  if ((n = NumberOfCell(sel_start_cursor.par, i)) != m) {
+                      cursor.par->table->SetTopLine(n, lineSet);
                       m = n;
                   }
               }
@@ -1740,12 +2026,13 @@ void LyXText::TableFeatures(int feature)
       case LyXTable::TOGGLE_LINE_BOTTOM:
           lineSet = !cursor.par->table->BottomLine(actCell);
           if (!selection){
-              cursor.par->table->SetBottomLine(actCell,lineSet);
+              cursor.par->table->SetBottomLine(actCell, lineSet);
           } else {
-              int i,n=-1,m=-2;
-              for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){
-                  if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
-                      cursor.par->table->SetBottomLine(n,lineSet);
+                 LyXParagraph::size_type i;
+                 int n = -1, m = -2;
+              for (i = sel_start_cursor.pos; i <= sel_end_cursor.pos; ++i) {
+                  if ((n = NumberOfCell(sel_start_cursor.par, i)) != m) {
+                      cursor.par->table->SetBottomLine(n, lineSet);
                       m = n;
                   }
               }
@@ -1756,12 +2043,13 @@ void LyXText::TableFeatures(int feature)
       case LyXTable::TOGGLE_LINE_LEFT:
           lineSet = !cursor.par->table->LeftLine(actCell);
           if (!selection){
-              cursor.par->table->SetLeftLine(actCell,lineSet);
+              cursor.par->table->SetLeftLine(actCell, lineSet);
           } else {
-              int i,n=-1,m=-2;
-              for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){
-                  if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
-                      cursor.par->table->SetLeftLine(n,lineSet);
+                 LyXParagraph::size_type i;
+                 int n = -1, m = -2;
+              for (i = sel_start_cursor.pos; i <= sel_end_cursor.pos; ++i){
+                  if ((n= NumberOfCell(sel_start_cursor.par, i)) != m) {
+                      cursor.par->table->SetLeftLine(n, lineSet);
                       m = n;
                   }
               }
@@ -1772,12 +2060,13 @@ void LyXText::TableFeatures(int feature)
       case LyXTable::TOGGLE_LINE_RIGHT:
           lineSet = !cursor.par->table->RightLine(actCell);
           if (!selection){
-              cursor.par->table->SetRightLine(actCell,lineSet);
+              cursor.par->table->SetRightLine(actCell, lineSet);
           } else {
-              int i,n=-1,m=-2;
-              for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){
-                  if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
-                      cursor.par->table->SetRightLine(n,lineSet);
+                 int n = -1, m = -2;
+                 LyXParagraph::size_type i = sel_start_cursor.pos;
+              for (; i <= sel_end_cursor.pos; ++i) {
+                  if ((n= NumberOfCell(sel_start_cursor.par, i)) != m) {
+                      cursor.par->table->SetRightLine(n, lineSet);
                       m = n;
                   }
               }
@@ -1789,12 +2078,13 @@ void LyXText::TableFeatures(int feature)
       case LyXTable::ALIGN_RIGHT:
       case LyXTable::ALIGN_CENTER:
           if (!selection){
-              cursor.par->table->SetAlignment(actCell,setAlign);
+              cursor.par->table->SetAlignment(actCell, setAlign);
           } else {
-              int i,n=-1,m=-2;
-              for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){
-                  if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
-                      cursor.par->table->SetAlignment(n,setAlign);
+              int n = -1, m = -2;
+             LyXParagraph::size_type i = sel_start_cursor.pos;
+              for (; i <= sel_end_cursor.pos; ++i) {
+                  if ((n= NumberOfCell(sel_start_cursor.par, i)) != m) {
+                      cursor.par->table->SetAlignment(n, setAlign);
                       m = n;
                   }
               }
@@ -1809,8 +2099,8 @@ void LyXText::TableFeatures(int feature)
           // temporary: Should put table in simple_cut_buffer (with before and after
           // dummy-paragraph !! 
           // not necessar anymore with UNDO :)
-          int i;
-          for (i = cursor.par->last-1; i>=0; i--)
+          for (LyXParagraph::size_type i = 
+                      cursor.par->size() - 1; i >= 0; --i)
              cursor.par->Erase(i);
           RedoParagraph();
           return;
@@ -1826,11 +2116,11 @@ void LyXText::TableFeatures(int feature)
 
           if (multicol){
              int newlines = cursor.par->table->UnsetMultiColumn(actCell);
-             int pos = cursor.pos;
-             while (pos<cursor.par->Last() && !cursor.par->IsNewline(pos))
-                  pos++;
-             for (;newlines;newlines--)
-                  cursor.par->InsertChar(pos, LYX_META_NEWLINE);
+             LyXParagraph::size_type pos = cursor.pos;
+             while (pos < cursor.par->Last() && !cursor.par->IsNewline(pos))
+                  ++pos;
+             for (; newlines; --newlines)
+                  cursor.par->InsertChar(pos, LyXParagraph::META_NEWLINE);
              RedoParagraph();
              return;
           }
@@ -1845,22 +2135,23 @@ void LyXText::TableFeatures(int feature)
              }
              else {
                   if (sel_start_cursor.row == sel_end_cursor.row){
-                      int i;
+                      LyXParagraph::size_type i;
                       number = 1;
-                      for (i=sel_start_cursor.pos; i<sel_end_cursor.pos; i++){
+                      for (i = sel_start_cursor.pos;
+                          i < sel_end_cursor.pos; ++i){
                           if (sel_start_cursor.par->IsNewline(i)){
                               sel_start_cursor.par->Erase(i);
                               // check for double-blanks
                               if ((i && !sel_start_cursor.par->IsLineSeparator(i-1))
                                   &&
-                                  (i<sel_start_cursor.par->Last() 
+                                  (i < sel_start_cursor.par->Last() 
                                    && !sel_start_cursor.par->IsLineSeparator(i)))
                                   sel_start_cursor.par->InsertChar(i, ' ');
                               else {
                                   sel_end_cursor.pos--;
-                                  i--;
+                                  --i;
                               }
-                              number++;
+                              ++number;
                           }
                       }
                       cursor.par->table->
@@ -1888,10 +2179,11 @@ void LyXText::TableFeatures(int feature)
                                                           cursor.pos),
                                              setLines);
           } else {
-              int i,n=-1,m=-2;
-              for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){
-                  if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
-                      cursor.par->table->SetAllLines(n,setLines);
+                 LyXParagraph::size_type i;
+                 int n = -1, m = -2;
+              for (i = sel_start_cursor.pos; i <= sel_end_cursor.pos; ++i) {
+                  if ((n= NumberOfCell(sel_start_cursor.par, i)) != m) {
+                      cursor.par->table->SetAllLines(n, setLines);
                       m = n;
                   }
               }
@@ -1912,12 +2204,13 @@ void LyXText::TableFeatures(int feature)
           return;
       case LyXTable::SET_ROTATE_CELL:
           if (!selection){
-              cursor.par->table->SetRotateCell(actCell,true);
+              cursor.par->table->SetRotateCell(actCell, true);
           } else {
-              int i,n=-1,m=-2;
-              for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){
-                  if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
-                      cursor.par->table->SetRotateCell(n,true);
+                 LyXParagraph::size_type i;
+                 int n = -1, m = -2;
+              for (i = sel_start_cursor.pos; i <= sel_end_cursor.pos; ++i){
+                  if ((n = NumberOfCell(sel_start_cursor.par, i)) != m) {
+                      cursor.par->table->SetRotateCell(n, true);
                       m = n;
                   }
               }
@@ -1925,12 +2218,13 @@ void LyXText::TableFeatures(int feature)
           return;
       case LyXTable::UNSET_ROTATE_CELL:
           if (!selection){
-              cursor.par->table->SetRotateCell(actCell,false);
+              cursor.par->table->SetRotateCell(actCell, false);
           } else {
-              int i,n=-1,m=-2;
-              for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){
-                  if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
-                      cursor.par->table->SetRotateCell(n,false);
+                 int n = -1, m = -2;
+                 LyXParagraph::size_type i = sel_start_cursor.pos;
+              for (; i <= sel_end_cursor.pos; ++i) {
+                  if ((n= NumberOfCell(sel_start_cursor.par, i)) != m) {
+                      cursor.par->table->SetRotateCell(n, false);
                       m = n;
                   }
               }
@@ -1939,32 +2233,33 @@ void LyXText::TableFeatures(int feature)
       case LyXTable::SET_LINEBREAKS:
           what = !cursor.par->table->Linebreaks(cursor.par->table->FirstVirtualCell(actCell));
           if (!selection){
-              cursor.par->table->SetLinebreaks(actCell,what);
+              cursor.par->table->SetLinebreaks(actCell, what);
           } else {
-              int i,n=-1,m=-2;
-              for (i=sel_start_cursor.pos; i<=sel_end_cursor.pos; i++){
-                  if ((n=NumberOfCell(sel_start_cursor.par,i)) != m) {
-                      cursor.par->table->SetLinebreaks(n,what);
+                 LyXParagraph::size_type i;
+                 int n = -1, m = -2;
+              for (i = sel_start_cursor.pos; i <= sel_end_cursor.pos; ++i) {
+                  if ((n = NumberOfCell(sel_start_cursor.par, i)) != m) {
+                      cursor.par->table->SetLinebreaks(n, what);
                       m = n;
                   }
               }
           }
           return;
       case LyXTable::SET_LTFIRSTHEAD:
-          cursor.par->table->SetLTHead(actCell,true);
+          cursor.par->table->SetLTHead(actCell, true);
           return;
       case LyXTable::SET_LTHEAD:
-          cursor.par->table->SetLTHead(actCell,false);
+          cursor.par->table->SetLTHead(actCell, false);
           return;
       case LyXTable::SET_LTFOOT:
-          cursor.par->table->SetLTFoot(actCell,false);
+          cursor.par->table->SetLTFoot(actCell, false);
           return;
       case LyXTable::SET_LTLASTFOOT:
-          cursor.par->table->SetLTFoot(actCell,true);
+          cursor.par->table->SetLTFoot(actCell, true);
           return;
       case LyXTable::SET_LTNEWPAGE:
           what = !cursor.par->table->LTNewPage(actCell);
-          cursor.par->table->SetLTNewPage(actCell,what);
+          cursor.par->table->SetLTNewPage(actCell, what);
           return;
     }
 }
@@ -1972,8 +2267,8 @@ void LyXText::TableFeatures(int feature)
 
 void LyXText::InsertCharInTable(char c)
 {
-       Row *row;
-       Row *tmprow;
+       Row * row;
+       Row * tmprow;
        long y;
        bool jumped_over_space;
        
@@ -1991,21 +2286,23 @@ void LyXText::InsertCharInTable(char c)
                                            * current font */
 
        // Get the font that is used to calculate the baselineskip
-       int const lastpos = cursor.par->Last();
+       LyXParagraph::size_type const lastpos = 
+               cursor.par->Last();
        LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
 
        jumped_over_space = false;
        if (IsLineSeparatorChar(c)) {
-               
+
+#ifndef FIX_DOUBLE_SPACE
                /* avoid double blanks but insert the new blank because
                 * of a possible font change */
                if (cursor.pos < lastpos &&
-                   cursor.par->IsLineSeparator(cursor.pos))
-               {
+                   cursor.par->IsLineSeparator(cursor.pos)) {
                        cursor.par->Erase(cursor.pos);
                        jumped_over_space = true;
-               }
-               else if ((cursor.pos > 0 && 
+               } else
+#endif
+                       if ((cursor.pos > 0 && 
                          cursor.par->IsLineSeparator(cursor.pos - 1))
                         || (cursor.pos > 0 && cursor.par->IsNewline(cursor.pos - 1))
                          || (cursor.pos == 0 &&
@@ -2013,23 +2310,17 @@ void LyXText::InsertCharInTable(char c)
                              && cursor.par->Previous()->footnoteflag
                              == LyXParagraph::OPEN_FOOTNOTE)))
                        return;
-       }
-       else if (IsNewlineChar(c)) {
+       } else if (IsNewlineChar(c)) {
             if (!IsEmptyTableCell()) {
                 TableFeatures(LyXTable::APPEND_CONT_ROW);
                 CursorDown();
             }
-         /* the newline character is the separator of the cells */
-         // cursor.par->InsertChar(cursor.pos, c);
-         // SetCharFont(cursor.par, cursor.pos, rawtmpfont);
-         // RedoParagraphs(cursor, cursor.par->Next());
-         // SetCursor(cursor.par, cursor.pos+1);
          return;
        }
    
        row = cursor.row;
        y = cursor.y - row->baseline;
-       if (c != LYX_META_INSET)        /* in this case LyXText::InsertInset 
+       if (c != LyXParagraph::META_INSET)      /* in this case LyXText::InsertInset 
                                         * already inserted the character */
                cursor.par->InsertChar(cursor.pos, c);
        SetCharFont(cursor.par, cursor.pos, rawtmpfont);
@@ -2057,25 +2348,25 @@ void LyXText::InsertCharInTable(char c)
 }
 
 
-void LyXText::CheckParagraphInTable(LyXParagraph* par, int pos)
+void LyXText::CheckParagraphInTable(LyXParagraph * par,
+                                   LyXParagraph::size_type pos)
 {
-       Row *row;
-       long y;
        
-       if (par->GetChar(pos) == LYX_META_INSET &&
-           par->GetInset(pos) && par->GetInset(pos)->Display()){
-         par->GetInset(pos)->SetDisplay(false);
+       if (par->GetChar(pos) == LyXParagraph::META_INSET &&
+           par->GetInset(pos) && par->GetInset(pos)->display()){
+         par->GetInset(pos)->display(false);
        }
 
-       row = GetRow(par, pos, y);
+       long y;
+       Row * row = GetRow(par, pos, y);
        
        int tmpheight = row->height;
        SetHeightOfRow(row);
-       
-       int tmp_pos = pos;
+
+       LyXParagraph::size_type tmp_pos = pos;
        /* update the table information */
        while (tmp_pos && !par->IsNewline(tmp_pos - 1))
-               tmp_pos--;
+               --tmp_pos;
        if (par->table->SetWidthOfCell(NumberOfCell(par, pos),
                                       WidthOfCell(par, tmp_pos))) {
                LyXCursor tmpcursor = cursor;
@@ -2088,6 +2379,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph* par, int pos)
                /* redraw only the row */
                LyXCursor tmpcursor = cursor;
                SetCursorIntern(par, pos);
+#warning See comment on top of text.C
                refresh_y = y;
                refresh_x = cursor.x;
                refresh_row = row;
@@ -2105,7 +2397,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph* par, int pos)
 
 void LyXText::BackspaceInTable()
 {
-       Row *tmprow, *row;
+       Row * tmprow, * row;
        long y;
        
        LyXFont rawtmpfont = current_font;
@@ -2119,18 +2411,17 @@ void LyXText::BackspaceInTable()
                /* no pasting of table paragraphs */
                
                CursorLeft();
-       }
-       else {
+       } else {
                /* this is the code for a normal backspace, not pasting
                 * any paragraphs */ 
-         SetUndo(Undo::DELETE, 
-                 cursor.par->ParFromPos(cursor.pos)->previous, 
-                 cursor.par->ParFromPos(cursor.pos)->next); 
+               SetUndo(Undo::DELETE, 
+                       cursor.par->ParFromPos(cursor.pos)->previous, 
+                       cursor.par->ParFromPos(cursor.pos)->next); 
          
                CursorLeftIntern();
                
                /* some insets are undeletable here */
-               if (cursor.par->GetChar(cursor.pos)==LYX_META_INSET) {
+               if (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET) {
                        if (!cursor.par->GetInset(cursor.pos)->Deletable())
                                return;
                }
@@ -2152,7 +2443,8 @@ void LyXText::BackspaceInTable()
                                tmprow = tmprow->next;
                                tmprow->pos--;
                        }
-                       
+
+#ifndef FIX_DOUBLE_SPACE
                        /* delete superfluous blanks */ 
                        if (cursor.pos < cursor.par->Last() - 1 &&
                        (cursor.par->IsLineSeparator(cursor.pos))) {
@@ -2172,6 +2464,7 @@ void LyXText::BackspaceInTable()
                                                cursor.pos--;
                                }
                        }
+#endif
                }
       
                CheckParagraphInTable(cursor.par, cursor.pos);
@@ -2193,62 +2486,51 @@ void LyXText::BackspaceInTable()
 
 
 /* just a macro to make some thing easier. */ 
-void LyXText::RedoParagraph()
+void LyXText::RedoParagraph() const
 {
-  LyXCursor tmpcursor = cursor;
-  ClearSelection();
-  RedoParagraphs(cursor, cursor.par->Next());;
-  SetCursorIntern(tmpcursor.par, tmpcursor.pos);
+#if 1
+       // I suspect this version will work
+       // also.
+       ClearSelection();
+       RedoParagraphs(cursor, cursor.par->Next());
+       SetCursorIntern(cursor.par, cursor.pos);
+#else
+       LyXCursor tmpcursor = cursor;
+       ClearSelection();
+       RedoParagraphs(cursor, cursor.par->Next());
+       SetCursorIntern(tmpcursor.par, tmpcursor.pos);
+#endif
 }
 
 
 /* insert a character, moves all the following breaks in the 
  * same Paragraph one to the right and make a rebreak */
-void  LyXText::InsertChar(char c)
+void LyXText::InsertChar(char c)
 {
-       Row *row;
-       Row *tmprow;
-       int z;
-       long y;
-       bool jumped_over_space;
-       LyXFont realtmpfont;
-       LyXFont rawtmpfont;
-       int lastpos;
-       LyXFont rawparfont;
-   
        SetUndo(Undo::INSERT, 
                cursor.par->ParFromPos(cursor.pos)->previous, 
                cursor.par->ParFromPos(cursor.pos)->next);
 
        /* When the free-spacing option is set for the current layout,
-        * all spaces are converted to protected spaces. */
-       bool freeSpacingBo =
-               lyxstyle.Style(parameters->textclass,
-                              cursor.row->par->GetLayout())->free_spacing;
-       //
-       // Is this wanted? There cannot be a line break between protected
-       // separators. Therefore I suggest the way implemented below
-       // (Matthias)
-       //
-       //   if ( freeSpacingBo && IsLineSeparatorChar(c) )
-       //         c = LYX_META_PROTECTED_SEPARATOR;
-   
-       if (freeSpacingBo && IsLineSeparatorChar(c) 
-           && (!cursor.pos || cursor.par->IsLineSeparator(cursor.pos-1))) 
-               c = LYX_META_PROTECTED_SEPARATOR;
-   
+        * disable the double-space checking */
+
+       bool freeSpacing = 
+               textclasslist.Style(parameters->textclass,
+                              cursor.row->par->GetLayout()).free_spacing;
+
        /* table stuff -- begin*/
        if (cursor.par->table) {
                InsertCharInTable(c);
-               goto out;
+               charInserted();
+               return;
        }
-       /* table stuff -- end*/
-   
-       /* 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 */ 
+       /* table stuff -- end*/
+   
+       /* 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
@@ -2257,21 +2539,21 @@ void  LyXText::InsertChar(char c)
 #warning There is a bug here! (Asger)
 #endif
        
-       realtmpfont = real_current_font;
-       rawtmpfont = current_font;  /* store the current font.
+       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 */
 
        // Get the font that is used to calculate the baselineskip
-       lastpos = cursor.par->Last();
-       rawparfont = cursor.par->GetFontSettings(lastpos - 1);
+       LyXParagraph::size_type lastpos = cursor.par->Last();
+       LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
 
-       jumped_over_space = false;
+       bool jumped_over_space = false;
    
-       if (IsLineSeparatorChar(c)) {
-          
+       if (!freeSpacing && IsLineSeparatorChar(c)) {
+#ifndef FIX_DOUBLE_SPACE
                if (cursor.pos < lastpos
                    && cursor.par->IsLineSeparator(cursor.pos)) {
                        /* the user inserted a space before a space. So we
@@ -2281,33 +2563,46 @@ void  LyXText::InsertChar(char c)
                         * blank at the end of a row we have to force
                         * a rebreak.*/ 
           
-                       minibuffer->Set(_("You cannot type two spaces this way.  Please read the Tutorial."));
+                       owner_->owner()->getMiniBuffer()
+                               ->Set(_("You cannot type two spaces this way. "
+                                       " Please read the Tutorial."));
+#if 1
+                       // How can this ever happen?
                        if (cursor.pos == RowLast(cursor.row)
                            && !IsLineSeparatorChar(c))
-                               cursor.row->fill = -1;    /* force rebreak  */
-          
+                               cursor.row->fill = -1;  // force rebreak
                        cursor.par->Erase(cursor.pos);
                        jumped_over_space = true;
-          
-               } else if ((cursor.pos > 0 
-                           && cursor.par->IsLineSeparator(cursor.pos - 1))
-                          || (cursor.pos > 0
-                              && cursor.par->IsNewline(cursor.pos - 1))
-                          || (cursor.pos == 0
-                              && !(cursor.par->Previous()
-                                   && cursor.par->Previous()->footnoteflag
-                                   == LyXParagraph::OPEN_FOOTNOTE))) {
+#else
+                       // Seems to me that this works just as well.
+                       CursorRight();
+                       charInserted();
+                       return;
+#endif
+               } else
+#endif   
+               if ((cursor.pos > 0 
+                    && cursor.par->IsLineSeparator(cursor.pos - 1))
+                   || (cursor.pos > 0
+                       && cursor.par->IsNewline(cursor.pos - 1))
+                   || (cursor.pos == 0
+                       && !(cursor.par->Previous()
+                            && cursor.par->Previous()->footnoteflag
+                            == LyXParagraph::OPEN_FOOTNOTE))) {
                        if (cursor.pos == 0 )
-                               minibuffer->Set(_("You cannot insert a space at the beginning of a paragraph.  Please read the Tutorial."));
+                               owner_->owner()->getMiniBuffer()->Set(_("You cannot insert a space at the beginning of a paragraph.  Please read the Tutorial."));
                        else
-                               minibuffer->Set(_("You cannot type two spaces this way.  Please read the Tutorial."));
-                       goto out;
+                               owner_->owner()->getMiniBuffer()->Set(_("You cannot type two spaces this way.  Please read the Tutorial."));
+                       charInserted();
+                       return;
                }
        } else if (IsNewlineChar(c)) {
                if (cursor.par->FirstPhysicalPar() == cursor.par
-                   && cursor.pos <= BeginningOfMainBody(cursor.par))
-                       goto out;
-               /* no newline at first position 
+                   && cursor.pos <= BeginningOfMainBody(cursor.par)) {
+                       charInserted();
+                       return;
+               }
+               /* No newline at first position 
                 * of a paragraph or behind labels. 
                 * TeX does not allow that. */
                
@@ -2317,43 +2612,40 @@ void  LyXText::InsertChar(char c)
                cursor.row->fill = -1;         // to force a new break
        }
    
-       /* the display inset stuff */ 
-       if (cursor.row->par->GetChar(cursor.row->pos) == LYX_META_INSET
+       // the display inset stuff
+       if (cursor.row->par->GetChar(cursor.row->pos) == LyXParagraph::META_INSET
            && cursor.row->par->GetInset(cursor.row->pos)
-           && cursor.row->par->GetInset(cursor.row->pos)->Display())
+           && cursor.row->par->GetInset(cursor.row->pos)->display())
                cursor.row->fill = -1; // to force a new break  
 
-       /* get the cursor row fist */
-       /* this is a dumb solution, i will try to hold the cursor.row
-          in future */ 
-       /* row = GetRow(cursor.par, cursor.pos, y);*/
-       /* ok, heres a better way: */ 
-       row = cursor.row;
-       y = cursor.y - row->baseline;
-       if (c != LYX_META_INSET)  /* in this case LyXText::InsertInset 
-                                  * already insertet the character */
+       // get the cursor row fist
+       Row * row = cursor.row;
+       long y = cursor.y - row->baseline;
+       if (c != LyXParagraph::META_INSET) /* Here case LyXText::InsertInset 
+                                           * already insertet the character */
                cursor.par->InsertChar(cursor.pos, c);
        SetCharFont(cursor.par, cursor.pos, rawtmpfont);
 
        if (!jumped_over_space) {
-               /* refresh the positions */
-               tmprow = row;
+               // refresh the positions
+               Row * tmprow = row;
                while (tmprow->next && tmprow->next->par == row->par) {
                        tmprow = tmprow->next;
                        tmprow->pos++;
                }
        }
    
-       /* Is there a break one row above */ 
+       // Is there a break one row above
        if ((cursor.par->IsLineSeparator(cursor.pos)
             || cursor.par->IsNewline(cursor.pos)
             || cursor.row->fill == -1)
            && row->previous && row->previous->par == row->par) {
-               z = NextBreakPoint(row->previous, paperwidth);
+               LyXParagraph::size_type z = NextBreakPoint(row->previous,
+                                                          paperwidth);
                if ( z >= row->pos) {
                        row->pos = z + 1;
                        
-                       /* set the dimensions of the row above  */ 
+                       // set the dimensions of the row above
                        row->previous->fill = Fill(row->previous, paperwidth);
 
                        SetHeightOfRow(row->previous);
@@ -2364,23 +2656,24 @@ void  LyXText::InsertChar(char c)
                        status = LyXText::NEED_MORE_REFRESH;
             
                        BreakAgainOneRow(row);
-                       SetCursor(cursor.par, cursor.pos + 1);
+
+                       current_font = rawtmpfont;
+                       real_current_font = realtmpfont;
+                       SetCursor(cursor.par, cursor.pos + 1, false);
                        /* cursor MUST be in row now */
             
                        if (row->next && row->next->par == row->par)
                                need_break_row = row->next;
                        else
                                need_break_row = 0;
-
-                       current_font = rawtmpfont;
-                       real_current_font = realtmpfont;
             
                        // check, wether the last characters font has changed. 
                        if (cursor.pos && cursor.pos == cursor.par->Last()
                            && rawparfont != rawtmpfont)
                                RedoHeightOfParagraph(cursor);
                        
-                       goto out;
+                       charInserted();
+                       return;
                }
        }
    
@@ -2404,14 +2697,13 @@ void  LyXText::InsertChar(char c)
                                row = row->next;
                        BreakAgainOneRow(row);
                }
-               SetCursor(cursor.par, cursor.pos + 1);
+               current_font = rawtmpfont;
+               real_current_font = realtmpfont;
+               SetCursor(cursor.par, cursor.pos + 1, false);
                if (row->next && row->next->par == row->par)
                        need_break_row = row->next;
                else
-                       need_break_row = 0;
-               
-               current_font = rawtmpfont;
-               real_current_font = realtmpfont;
+                       need_break_row = 0;             
        } else {
                refresh_y = y;
                refresh_x = cursor.x;
@@ -2425,9 +2717,9 @@ void  LyXText::InsertChar(char c)
                else
                        status = LyXText::NEED_MORE_REFRESH;
             
-               SetCursor(cursor.par, cursor.pos + 1);
                current_font = rawtmpfont;
                real_current_font = realtmpfont;
+               SetCursor(cursor.par, cursor.pos + 1, false);
        }
 
        /* check, wether the last characters font has changed. */ 
@@ -2436,45 +2728,62 @@ void  LyXText::InsertChar(char c)
                RedoHeightOfParagraph(cursor);
        } else {
                /* now the special right address boxes */
-               if (lyxstyle.Style(parameters->textclass,
-                                  cursor.par->GetLayout())->margintype
+               if (textclasslist.Style(parameters->textclass,
+                                  cursor.par->GetLayout()).margintype
                    == MARGIN_RIGHT_ADDRESS_BOX) {
                        RedoDrawingOfParagraph(cursor); 
                }
        }
-  out:
 
+       charInserted();
+}
+   
+
+void LyXText::charInserted()
+{
        // Here we could call FinishUndo for every 20 characters inserted.
        // This is from my experience how emacs does it.
-       static unsigned short counter = 0;
+       static unsigned int counter = 0;
        if (counter < 20) {
                ++counter;
        } else {
                FinishUndo();
                counter = 0;
        }
-       return;
 }
-   
-   
-void LyXText::PrepareToPrint(Row *row, float &x, float &fill_separator, 
-                            float &fill_hfill, float &fill_label_hfill)
+
+void LyXText::PrepareToPrint(Row * row, float & x,
+                            float & fill_separator, 
+                            float & fill_hfill,
+                            float & fill_label_hfill,
+                            bool bidi) const
 {
-       float w, nh, nlh, ns;
+       float nh, nlh, ns;
        
-       w = row->fill;
+       float w = row->fill;
        fill_hfill = 0;
        fill_label_hfill = 0;
        fill_separator = 0;
        fill_label_hfill = 0;
-       
-       x = LeftMargin(row);
+
+       LyXDirection direction = row->par->getParDirection();
+
+       if (direction == LYX_DIR_RIGHT_TO_LEFT) {
+               x = RightMargin(row);
+               if (row->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
+                       LyXFont font(LyXFont::ALL_SANE);
+                       font.setSize(LyXFont::SIZE_SMALL);
+                       x += font.textWidth("Mwide-figM", 10);
+               }
+       }
+       else
+               x = LeftMargin(row);
        
        /* is there a manual margin with a manual label */ 
-       if (lyxstyle.Style(parameters->textclass,
-                          row->par->GetLayout())->margintype == MARGIN_MANUAL
-           && lyxstyle.Style(parameters->textclass,
-                             row->par->GetLayout())->labeltype == LABEL_MANUAL) {
+       if (textclasslist.Style(parameters->textclass,
+                          row->par->GetLayout()).margintype == MARGIN_MANUAL
+           && textclasslist.Style(parameters->textclass,
+                             row->par->GetLayout()).labeltype == LABEL_MANUAL) {
               
                nlh = NumberOfLabelHfills(row) + 1; /* one more since labels 
                                                    * are left aligned*/ 
@@ -2499,16 +2808,16 @@ void LyXText::PrepareToPrint(Row *row, float &x, float &fill_separator,
        else  {
           /* is it block, flushleft or flushright? 
            * set x how you need it */
-          int align;
-          if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT)
-            align = lyxstyle.Style(parameters->textclass, row->par->GetLayout())->align;
-          else
-            align = row->par->FirstPhysicalPar()->align;
+       int align;
+       if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT)
+         align = textclasslist.Style(parameters->textclass, row->par->GetLayout()).align;
+       else
+         align = row->par->FirstPhysicalPar()->align;
           
           /* center displayed insets */ 
-          if (row->par->GetChar(row->pos) == LYX_META_INSET
+          if (row->par->GetChar(row->pos) == LyXParagraph::META_INSET
               && row->par->GetInset(row->pos)
-              && row->par->GetInset(row->pos)->Display())
+              && row->par->GetInset(row->pos)->display())
             align = LYX_ALIGN_CENTER;
 
           switch (align) {
@@ -2516,11 +2825,13 @@ void LyXText::PrepareToPrint(Row *row, float &x, float &fill_separator,
              ns = NumberOfSeparators(row);
              if (ns && row->next && row->next->par == row->par &&
                  !(row->next->par->IsNewline(row->next->pos-1))
-                 && !(row->next->par->GetChar(row->next->pos) == LYX_META_INSET
+                 && !(row->next->par->GetChar(row->next->pos) == LyXParagraph::META_INSET
                       && row->next->par->GetInset(row->next->pos)
-                      && row->next->par->GetInset(row->next->pos)->Display())
+                      && row->next->par->GetInset(row->next->pos)->display())
                  )
                fill_separator = w / ns;
+             else if (direction == LYX_DIR_RIGHT_TO_LEFT)
+               x += w;
              break;
            case LYX_ALIGN_RIGHT:
              x += w;
@@ -2530,8 +2841,32 @@ void LyXText::PrepareToPrint(Row *row, float &x, float &fill_separator,
              break;
           }
        }
-     }
+       if (!bidi)
+               return;
 
+       ComputeBidiTables(row);
+       if (direction == LYX_DIR_RIGHT_TO_LEFT) {
+               LyXParagraph::size_type main_body = 
+                       BeginningOfMainBody(row->par);
+               LyXParagraph::size_type last = RowLast(row);
+
+               if (row->pos <= last
+                   && !row->par->table
+                   && last != vis2log(last)
+                   && row->par->IsLineSeparator(last)) {
+                       if (!(main_body > 0 && main_body-1 == last))
+                               x -= fill_separator+SingleWidth(row->par,last);
+               } else if (main_body > 0 &&
+                          (main_body-1 > last || 
+                           !row->par->IsLineSeparator(main_body-1))) {
+                       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+                                                                      row->par->GetLayout());
+                       x += GetFont(row->par, -2).stringWidth(layout.labelsep);
+                       if (main_body-1 <= last)
+                               x += fill_label_hfill;
+               }
+       }
+}
       
 /* important for the screen */
 
@@ -2540,10 +2875,11 @@ void LyXText::PrepareToPrint(Row *row, float &x, float &fill_separator,
 * realize, that you left an empty paragraph, they will delete it.
 * They also delete the corresponding row */
 
-void LyXText::CursorRightOneWord()
+void LyXText::CursorRightOneWord() const
 {
        // treat floats, HFills and Insets as words
        LyXCursor tmpcursor = cursor;
+#warning See comment on top of text.C
 
        if (tmpcursor.pos == tmpcursor.par->Last()
            && tmpcursor.par->Next())
@@ -2557,24 +2893,24 @@ void LyXText::CursorRightOneWord()
                while ( tmpcursor.pos < tmpcursor.par->Last() &&
                        ! tmpcursor.par->IsWord( tmpcursor.pos ) ) 
                {
-                 //    printf("Current pos1 %d",tmpcursor.pos) ;
+                 //    printf("Current pos1 %d", tmpcursor.pos) ;
                        tmpcursor.pos++;
-                       steps++;
+                       ++steps;
                }
                // Advance through word.
                while ( tmpcursor.pos < tmpcursor.par->Last() &&
                        tmpcursor.par->IsWord( tmpcursor.pos ) )
                {
-                 //     printf("Current pos2 %d",tmpcursor.pos) ;
+                 //     printf("Current pos2 %d", tmpcursor.pos) ;
                        tmpcursor.pos++;
-                       steps++;
+                       ++steps;
                }
        }
        SetCursor(tmpcursor.par, tmpcursor.pos);
 }
 
 
-void LyXText::CursorTab()
+void LyXText::CursorTab() const
 {
     if (cursor.par->table) {
         int cell = NumberOfCell(cursor.par, cursor.pos);
@@ -2626,7 +2962,7 @@ void LyXText::CursorTab()
 /* -------> 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() 
+void LyXText::CursorLeftOneWord()  const
 {
        // treat HFills, floats and Insets as words
        LyXCursor tmpcursor = cursor;
@@ -2703,9 +3039,9 @@ int LyXText::SelectWordWhenUnderCursor()
 
 // This function is only used by the spellchecker for NextWord().
 // It doesn't handle LYX_ACCENTs and probably never will.
-char* LyXText::SelectNextWord(float &value)
+char * LyXText::SelectNextWord(float & value)
 {
-       LyXParagraph* tmppar = cursor.par;
+       LyXParagraph * tmppar = cursor.par;
        
        // If this is not the very first word, skip rest of
        // current word because we are probably in the middle
@@ -2738,32 +3074,42 @@ char* LyXText::SelectNextWord(float &value)
        /* Start the selection from here */
        sel_cursor = cursor;
 
-       string latex;
-   
+#ifdef HAVE_SSTREAM
+       ostringstream latex;
+#else
+       ostrstream latex;
+#endif
        /* and find the end of the word 
           (optional hyphens are part of a word) */
        while (cursor.pos < cursor.par->Last()
               && (cursor.par->IsLetter(cursor.pos)) 
-                  || (cursor.par->GetChar(cursor.pos) == LYX_META_INSET &&
-                      cursor.par->GetInset(cursor.pos) != 0 &&
-                      cursor.par->GetInset(cursor.pos)->Latex(latex,0)==0 &&
-                      latex == "\\-"))
+                  || (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET
+                      && cursor.par->GetInset(cursor.pos) != 0
+                      && cursor.par->GetInset(cursor.pos)->Latex(latex, 0, false) == 0
+#ifdef HAVE_SSTREAM
+                      && latex.str() == "\\-"
+#else
+               && string(latex.str(), 3) == "\\-" // this is not nice at all
+#endif
+                          ))
                cursor.pos++;
 
+#ifndef HAVE_SSTREAM
+       delete [] latex.str();
+#endif
        // Finally, we copy the word to a string and return it
-       char* string = 0;
+       char * str = 0;
 
        if (sel_cursor.pos < cursor.pos) {
-               string = new char [cursor.pos - sel_cursor.pos + 2];
-               int i,j;
-               
-               for (i=sel_cursor.pos, j=0; i<cursor.pos; i++) {
-                       if (cursor.par->GetChar(i) != LYX_META_INSET)
-                               string[j++] = cursor.par->GetChar(i);
+               str = new char [cursor.pos - sel_cursor.pos + 2];
+               LyXParagraph::size_type i, j;
+               for (i = sel_cursor.pos, j = 0; i < cursor.pos; ++i) {
+                       if (cursor.par->GetChar(i) != LyXParagraph::META_INSET)
+                               str[j++] = cursor.par->GetChar(i);
                }
-               string[j] = '\0';
+               str[j] = '\0';
        }
-       return string;
+       return str;
 }
 
 
@@ -2776,17 +3122,29 @@ void LyXText::SelectSelectedWord()
        /* set the sel cursor */
        sel_cursor = cursor;
 
-       string latex;
+#ifdef HAVE_SSTREAM
+       ostringstream latex;
+#else
+       ostrstream latex;
+#endif
        
        /* now find the end of the word */
        while (cursor.pos < cursor.par->Last()
               && (cursor.par->IsLetter(cursor.pos)
-                  || (cursor.par->GetChar(cursor.pos) == LYX_META_INSET &&
-                      cursor.par->GetInset(cursor.pos) != 0 &&
-                      cursor.par->GetInset(cursor.pos)->Latex(latex,0)==0 &&
-                      latex == "\\-")))
+                  || (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET
+                      && cursor.par->GetInset(cursor.pos) != 0
+                      && cursor.par->GetInset(cursor.pos)->Latex(latex, 0, false) == 0
+#ifdef HAVE_SSTREAM
+                      && latex.str() == "\\-"
+#else
+                      && string(latex.str(), 3) == "\\-"
+#endif
+                          )))
                cursor.pos++;
        
+#ifndef HAVE_SSTREAM
+       delete [] latex.str();
+#endif
        SetCursor(cursor.par, cursor.pos);
        
        /* finally set the selection */ 
@@ -2801,6 +3159,7 @@ void LyXText::DeleteWordForward()
         
        if (!cursor.par->Last())
                CursorRight();
+#warning See comment on top of text.C
        else {
                /* -------> Skip initial non-word stuff. */
                while ( cursor.pos < cursor.par->Last() 
@@ -2827,8 +3186,9 @@ void LyXText::DeleteWordBackward()
        LyXCursor tmpcursor = cursor;
        if (!cursor.par->Last())
          CursorLeft();
+#warning See comment on top of text.C
        else{
-         selection = True; // to avoid deletion 
+         selection = true; // to avoid deletion 
          CursorLeftOneWord();
          sel_cursor = cursor;
          cursor = tmpcursor;
@@ -2844,6 +3204,7 @@ void LyXText::DeleteLineForward()
        LyXCursor tmpcursor = cursor;
        if (!cursor.par->Last())
                CursorRight();
+#warning See comment on top of text.C
        else {
                CursorEnd();
                sel_cursor = cursor;
@@ -2857,6 +3218,7 @@ void LyXText::DeleteLineForward()
        }
 }
 
+
 // Change the case of a word at cursor position. The meaning of action
 // is:
 // 0  change to lowercase
@@ -2868,80 +3230,94 @@ void LyXText::DeleteLineForward()
 // LyXParagraph, but it will have to change for 1.1 anyway. At least
 // it does not access outside of the allocated array as the older
 // version did. (JMarc) 
-void LyXText::ChangeWordCase(int action) 
+void LyXText::ChangeWordCase(LyXText::TextCase action) 
 {
-       LyXParagraph *tmppar = cursor.par->ParFromPos(cursor.pos);
-       int tmppos = cursor.par->PositionInParFromPos(cursor.pos);
+       LyXParagraph * tmppar = cursor.par->ParFromPos(cursor.pos);
 
        SetUndo(Undo::FINISH, tmppar->previous, tmppar->next); 
 
-       while (tmppos < tmppar->last) {
-               unsigned char c = tmppar->text[tmppos];
+       LyXParagraph::size_type tmppos = 
+               cursor.par->PositionInParFromPos(cursor.pos);
+       while (tmppos < tmppar->size()) {
+               //unsigned char c = tmppar->text[tmppos];
+               unsigned char c = tmppar->GetChar(tmppos);
                if (IsKommaChar(c) || IsLineSeparatorChar(c))
                        break;
-               if (c != LYX_META_INSET) {
+               if (c != LyXParagraph::META_INSET) {
                        switch (action) {
-                       case 0:
+                       case text_lowercase:
                                c = tolower(c);
                                break;
-                       case 1:
+                       case text_capitalization:
                                c = toupper(c);
-                               action = 0;
+                               action = text_lowercase;
                                break;
-                       case 2:
+                       case text_uppercase:
                                c = toupper(c);
                                break;
                        }
                }
                
-               tmppar->text[tmppos] = c;
-               tmppos++;
+               //tmppar->text[tmppos] = c;
+               tmppar->SetChar(tmppos, c);
+               ++tmppos;
        }
        CheckParagraph(tmppar, tmppos);
        CursorRightOneWord();
 }
 
 
-void  LyXText::Delete()
+void LyXText::Delete()
 {
-   LyXCursor old_cursor = cursor;
-   LyXCursor tmpcursor;
-   /* this is a very easy implementation*/ 
-   
-   /* just move to the right */ 
-   CursorRightIntern();
-   
-   if (cursor.par->previous == old_cursor.par->previous
-       && cursor.par != old_cursor.par)
-     return; // delete-emty-paragraph-mechanism has done it
-   
-   /* if you had success make a backspace */ 
-   if (old_cursor.par != cursor.par || old_cursor.pos != cursor.pos) {
-     tmpcursor = cursor;
-     cursor = old_cursor; // to make sure undo gets the right cursor position
-     SetUndo(Undo::DELETE, 
-            cursor.par->ParFromPos(cursor.pos)->previous, 
-            cursor.par->ParFromPos(cursor.pos)->next); 
-     cursor = tmpcursor;
-     Backspace();
-   }
+       // this is a very easy implementation
+
+       LyXCursor old_cursor = cursor;
+       int old_cur_par_id = old_cursor.par->id();
+       int old_cur_par_prev_id = old_cursor.par->previous ?
+               old_cursor.par->previous->id() : 0;
+       
+       // just move to the right
+       CursorRightIntern();
+
+#warning Look at the comment here.
+       // This check is not very good...
+       // The CursorRightIntern calls DeleteEmptyParagrapgMechanism
+       // and that can very well delete the par or par->previous in
+       // old_cursor. Will a solution where we compare paragraph id's
+       //work better?
+#if 1
+       if ((cursor.par->previous ? cursor.par->previous->id() : 0)
+           == old_cur_par_prev_id
+           && cursor.par->id() != old_cur_par_id)
+               return; // delete-empty-paragraph-mechanism has done it
+#else
+       if (cursor.par->previous == old_cursor.par->previous
+           && cursor.par != old_cursor.par)
+               return; // delete-empty-paragraph-mechanism has done it
+#endif
+       // if you had success make a backspace
+       if (old_cursor.par != cursor.par || old_cursor.pos != cursor.pos) {
+               LyXCursor tmpcursor = cursor;
+               cursor = old_cursor; // to make sure undo gets the right cursor position
+               SetUndo(Undo::DELETE, 
+                       cursor.par->ParFromPos(cursor.pos)->previous, 
+                       cursor.par->ParFromPos(cursor.pos)->next); 
+               cursor = tmpcursor;
+               Backspace();
+       }
 }
 
 
-void  LyXText::Backspace()
+void LyXText::Backspace()
 {
-       LyXParagraph *tmppar;
-       Row *tmprow, *row;
-       long y;
-       int tmpheight;
-
-       /* table stuff -- begin*/
-   
+       DebugTracer trc1("LyXText::Backspace");
+       
+       /* table stuff -- begin */
        if (cursor.par->table) {
                BackspaceInTable();
                return;
        }
-       /* table stuff -- end*/
+       /* table stuff -- end */
        
        LyXFont rawtmpfont = current_font;
        LyXFont realtmpfont = real_current_font;
@@ -2951,24 +3327,31 @@ void  LyXText::Backspace()
        LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
 
        if (cursor.pos == 0) {
-               /* we may paste some paragraphs */
+               DebugTracer trc("LyXText::Backspace cursor.pos == 0");
+               
+               // The cursor is at the beginning of a paragraph, so the the backspace
+               // will collapse two paragraphs into one.
+               
+               // we may paste some paragraphs
       
-               /* is it an empty paragraph? */
+               // is it an empty paragraph?
       
                if ((lastpos == 0
                     || (lastpos == 1 && cursor.par->IsSeparator(0)))
                    && !(cursor.par->Next() 
-                        && cursor.par->footnoteflag ==
-                        LyXParagraph::NO_FOOTNOTE
-                        && cursor.par->Next()->footnoteflag ==
-                        LyXParagraph::OPEN_FOOTNOTE)) {
+                        && cursor.par->footnoteflag == LyXParagraph::NO_FOOTNOTE
+                        && cursor.par->Next()->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)) {
+                       // This is an empty paragraph and we delete it just by moving the curosr one step
+                       // left and let the DeleteEmptyParagraphMechanism handle the actual deleteion
+                       // of the paragraph.
                        
                        if (cursor.par->previous) {
-                               tmppar = cursor.par->previous->FirstPhysicalPar();
+                               LyXParagraph * tmppar = cursor.par->previous->FirstPhysicalPar();
                                if (cursor.par->GetLayout() == tmppar->GetLayout()
                                    && cursor.par->footnoteflag == tmppar->footnoteflag
                                    && cursor.par->GetAlign() == tmppar->GetAlign()) {
-                                       
+                                       // Inherit botom DTD from the paragraph below.
+                                       // (the one we are deleting)
                                        tmppar->line_bottom = cursor.par->line_bottom;
                                        tmppar->added_space_bottom = cursor.par->added_space_bottom;
                                        tmppar->pagebreak_bottom = cursor.par->pagebreak_bottom;
@@ -2976,8 +3359,8 @@ void  LyXText::Backspace()
                                
                                CursorLeftIntern();
                     
-                               /* the layout things can change the height of a row ! */ 
-                               tmpheight = cursor.row->height;
+                               // the layout things can change the height of a row !
+                               int tmpheight = cursor.row->height;
                                SetHeightOfRow(cursor.row);
                                if (cursor.row->height != tmpheight) {
                                        refresh_y = cursor.y - cursor.row->baseline;
@@ -2987,36 +3370,45 @@ void  LyXText::Backspace()
                                return;
                        }
                }
+               
                if (cursor.par->ParFromPos(cursor.pos)->previous){
-                       SetUndo(Undo::DELETE, 
-                               cursor.par->ParFromPos(cursor.pos)->previous->previous, 
-                               cursor.par->ParFromPos(cursor.pos)->next); 
+                       SetUndo(Undo::DELETE,
+                               cursor.par->ParFromPos(cursor.pos)->previous->previous,
+                               cursor.par->ParFromPos(cursor.pos)->next);
                }
-               tmppar = cursor.par;
-               tmprow = cursor.row;
+               
+               LyXParagraph * tmppar = cursor.par;
+               Row * tmprow = cursor.row;
                CursorLeftIntern();
-               /* 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 */
+#warning See comment on top of text.C
+               /* 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
+               */
                if (cursor.par != tmppar
                    && (cursor.par->GetLayout() == tmppar->GetLayout()
-                       || !tmppar->GetLayout())
+                       || tmppar->GetLayout() == 0 /*standard*/)
                    && cursor.par->footnoteflag == tmppar->footnoteflag
                    /* table stuff -- begin*/
                    && !cursor.par->table /* no pasting of tables */ 
                    /* table stuff -- end*/
                    && cursor.par->GetAlign() == tmppar->GetAlign()) {
-                       
+
+                       RemoveParagraph(tmprow);
+                       RemoveRow(tmprow);
                        cursor.par->PasteParagraph();
                        
-                       if (!(cursor.pos &&
-                             cursor.par->IsSeparator(cursor.pos - 1)))
-                               cursor.par->InsertChar(cursor.pos, ' ');
+                       if (!cursor.pos || !cursor.par->IsSeparator(cursor.pos - 1))
+                               ; //cursor.par->InsertChar(cursor.pos, ' ');
+                       // strangely enough it seems that commenting out the line above removes
+                       // most or all of the segfaults. I will however also try to move the
+                       // two Remove... lines in front of the PasteParagraph too.
                        else
                                if (cursor.pos)
                                        cursor.pos--;
@@ -3025,20 +3417,23 @@ void  LyXText::Backspace()
                        refresh_row = cursor.row;
                        refresh_y = cursor.y - cursor.row->baseline;
                        
-                       /* remove the lost paragraph */
-                       RemoveParagraph(tmprow);
-                       RemoveRow(tmprow);  
-                       
-                       /* break the paragraph again */ 
-                       /* BreakAgain(cursor.row); */ 
+                       // remove the lost paragraph
+                       // This one is not safe, since the paragraph that the tmprow and the
+                       // following rows belong to has been deleted by the PasteParagraph
+                       // above. The question is... could this be moved in front of the
+                       // PasteParagraph?
+                       //RemoveParagraph(tmprow);
+                       //RemoveRow(tmprow);  
                        
-                       AppendParagraph(cursor.row);
+                       AppendParagraph(cursor.row); // This rebuilds the rows.
                        UpdateCounters(cursor.row);
                        
-                       /* the row may have changed, block, hfills etc. */ 
+                       // the row may have changed, block, hfills etc.
                        SetCursor(cursor.par, cursor.pos);
                }
-       } else  {
+       } else {
+               DebugTracer trc("LyXText::Backspace normal backspace");
+               
                /* this is the code for a normal backspace, not pasting
                 * any paragraphs */ 
                SetUndo(Undo::DELETE, 
@@ -3046,23 +3441,22 @@ void  LyXText::Backspace()
                        cursor.par->ParFromPos(cursor.pos)->next); 
                CursorLeftIntern();
                
-               /* some insets are undeletable here */
-               if (cursor.par->GetChar(cursor.pos)==LYX_META_INSET) {
+               // some insets are undeletable here
+               if (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET) {
                        if (!cursor.par->GetInset(cursor.pos)->Deletable())
                                return; 
-                       /* force complete redo when erasing display insets */ 
-                       /* this is a cruel mathod but save..... Matthias */ 
-                       if (cursor.par->GetInset(cursor.pos)->Display()){
+                       // force complete redo when erasing display insets
+                       // this is a cruel mathod but save..... Matthias 
+                       if (cursor.par->GetInset(cursor.pos)->display()){
                                cursor.par->Erase(cursor.pos);
                                RedoParagraph();
                                return;
                        }
                }
                
-               row = cursor.row;
-               y = cursor.y - row->baseline;
-               int z;
-               
+               Row * row = cursor.row;
+               long y = cursor.y - row->baseline;
+               LyXParagraph::size_type z;
                /* remember that a space at the end of a row doesnt count
                 * when calculating the fill */ 
                if (cursor.pos < RowLast(row) ||
@@ -3074,8 +3468,8 @@ void  LyXText::Backspace()
                 * to the behavior when pasting paragraphs */ 
                if (cursor.pos && cursor.par->IsNewline(cursor.pos)) {
                        cursor.par->Erase(cursor.pos);
-                       /* refresh the positions */
-                       tmprow = row;
+                       // refresh the positions
+                       Row * tmprow = row;
                        while (tmprow->next && tmprow->next->par == row->par) {
                                tmprow = tmprow->next;
                                tmprow->pos--;
@@ -3085,7 +3479,7 @@ void  LyXText::Backspace()
                        
                        if (cursor.pos < cursor.par->Last() && !cursor.par->IsSeparator(cursor.pos)) {
                                cursor.par->InsertChar(cursor.pos, ' ');
-                               /* refresh the positions */
+                               // refresh the positions
                                tmprow = row;
                                while (tmprow->next && tmprow->next->par == row->par) {
                                        tmprow = tmprow->next;
@@ -3095,14 +3489,15 @@ void  LyXText::Backspace()
                } else {
                        cursor.par->Erase(cursor.pos);
                        
-                       /* refresh the positions */
-                       tmprow = row;
+                       // refresh the positions
+                       Row * tmprow = row;
                        while (tmprow->next && tmprow->next->par == row->par) {
                                tmprow = tmprow->next;
                                tmprow->pos--;
                        }
-                       
-                       /* delete superfluous blanks */ 
+
+#ifndef FIX_DOUBLE_SPACE
+                       // delete superfluous blanks 
                        if (cursor.pos < cursor.par->Last() - 1 &&
                            (cursor.par->IsLineSeparator(cursor.pos))) {
                                
@@ -3110,25 +3505,25 @@ void  LyXText::Backspace()
                                    || !cursor.pos 
                                    || cursor.par->IsLineSeparator(cursor.pos - 1)) {
                                        cursor.par->Erase(cursor.pos);
-                                       /* refresh the positions */
+                                       // refresh the positions
                                        tmprow = row;
                                        while (tmprow->next && 
                                               tmprow->next->par == row->par) {
                                                tmprow = tmprow->next;
                                                tmprow->pos--;
                                        }
-                                       if (cursor.pos)   /* move one character left */
+                                       if (cursor.pos)   // move one character left
                                                cursor.pos--;
                                }
                        }
+#endif
                        
-                       /* delete newlines at the beginning of paragraphs */ 
+                       // delete newlines at the beginning of paragraphs
                        while (cursor.par->Last() &&
                               cursor.par->IsNewline(cursor.pos) &&
-                              cursor.pos == BeginningOfMainBody(cursor.par)
-                               ) {
+                              cursor.pos == BeginningOfMainBody(cursor.par)) {
                                cursor.par->Erase(cursor.pos);
-                               /* refresh the positions */
+                               // refresh the positions
                                tmprow = row;
                                while (tmprow->next && 
                                       tmprow->next->par == row->par) {
@@ -3138,21 +3533,20 @@ void  LyXText::Backspace()
                        }
                }
                
-               /* is there a break one row above */ 
+               // is there a break one row above
                if (row->previous && row->previous->par == row->par) {
                        z = NextBreakPoint(row->previous, paperwidth);
                        if ( z >= row->pos) {
                                row->pos = z + 1;
                                
-                               tmprow = row->previous;
+                               Row * tmprow = row->previous;
                                
-                               /* maybe the current row is now empty */ 
+                               // maybe the current row is now empty
                                if (row->pos >= row->par->Last()) {
-                                       /* remove it */ 
+                                       // remove it
                                        RemoveRow(row);
                                        need_break_row = 0;
-                               }
-                               else  {
+                               } else {
                                        BreakAgainOneRow(row);
                                        if (row->next && row->next->par == row->par)
                                                need_break_row = row->next;
@@ -3160,7 +3554,7 @@ void  LyXText::Backspace()
                                                need_break_row = 0;
                                }
                                
-                               /* set the dimensions of the row above  */ 
+                               // set the dimensions of the row above
                                y -= tmprow->height;
                                tmprow->fill = Fill(tmprow, paperwidth);
                                SetHeightOfRow(tmprow);
@@ -3168,10 +3562,10 @@ void  LyXText::Backspace()
                                refresh_y = y;
                                refresh_row = tmprow;
                                status = LyXText::NEED_MORE_REFRESH;
-                               SetCursor(cursor.par, cursor.pos);
                                current_font = rawtmpfont;
                                real_current_font = realtmpfont;
-                               /* check, whether the last character's font has changed. */
+                               SetCursor(cursor.par, cursor.pos, false);
+                               // check, whether the last character's font has changed.
                                rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
                                if (rawparfont != rawtmpfont)
                                        RedoHeightOfParagraph(cursor);
@@ -3179,12 +3573,12 @@ void  LyXText::Backspace()
                        }
                }
                
-               /* break the cursor row again */ 
+               // break the cursor row again
                z = NextBreakPoint(row, paperwidth);
                
-               if ( z != RowLast(row) || 
-                    (row->next && row->next->par == row->par &&
-                     RowLast(row) == row->par->Last() - 1)){
+               if (z != RowLast(row) || 
+                   (row->next && row->next->par == row->par &&
+                    RowLast(row) == row->par->Last() - 1)){
                        
                        /* it can happen that a paragraph loses one row
                         * without a real breakup. This is when a word
@@ -3199,16 +3593,17 @@ void  LyXText::Backspace()
                        status = LyXText::NEED_MORE_REFRESH;
                        
                        BreakAgainOneRow(row);
-                       
-                       SetCursor(cursor.par, cursor.pos);
-                       /* cursor MUST be in row now */
+                       current_font = rawtmpfont; 
+                       real_current_font = realtmpfont;
+                       SetCursor(cursor.par, cursor.pos, false);
+                       // cursor MUST be in row now
                        
                        if (row->next && row->next->par == row->par)
                                need_break_row = row->next;
                        else
                                need_break_row = 0;
                } else  {
-                       /* set the dimensions of the row */ 
+                       // set the dimensions of the row
                        row->fill = Fill(row, paperwidth);
                        int tmpheight = row->height;
                        SetHeightOfRow(row);
@@ -3218,102 +3613,123 @@ void  LyXText::Backspace()
                                status = LyXText::NEED_MORE_REFRESH;
                        refresh_y = y;
                        refresh_row = row;
-                       SetCursor(cursor.par, cursor.pos);
+                       current_font = rawtmpfont; 
+                       real_current_font = realtmpfont;
+                       SetCursor(cursor.par, cursor.pos, false);
                }
        }
-   
-       /* restore the current font 
-        * That is what a user expects! */
+       DebugTracer trc2("LyXText::Backspace wrap up");
+       
+       // restore the current font
+       // That is what a user expects!
        current_font = rawtmpfont; 
        real_current_font = realtmpfont;
        
-       /* check, wether the last characters font has changed. */
+       // check, wether the last characters font has changed.
        rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
        if (rawparfont != rawtmpfont) {
                RedoHeightOfParagraph(cursor);
        } else {
-               /* now the special right address boxes */
-               if (lyxstyle.Style(parameters->textclass,
-                                  cursor.par->GetLayout())->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+               // now the special right address boxes
+               if (textclasslist.Style(parameters->textclass,
+                                       cursor.par->GetLayout()).margintype == MARGIN_RIGHT_ADDRESS_BOX) {
                        RedoDrawingOfParagraph(cursor); 
                }
        }
 }
 
 
-void LyXText::GetVisibleRow(LyXScreen &scr, int offset, 
-                           Row *row_ptr, long y)
+void LyXText::GetVisibleRow(int offset, 
+                           Row * row_ptr, long y)
 {
        /* returns a printed row */
+       Painter & pain = owner_->painter();
        
-       int pos, pos_end;
+       LyXDirection direction = row_ptr->par->getParDirection();
+       LyXParagraph::size_type vpos, pos, pos_end;
        float x, tmpx;
        int y_top, y_bottom;
        float fill_separator, fill_hfill, fill_label_hfill;
-       LyXParagraph *par, *firstpar;
-       int left_margin;
+       LyXParagraph * par, * firstpar;
        LyXFont font;
        int maxdesc;
        if (row_ptr->height <= 0) {
-               fprintf(stderr, "LYX_ERROR: row.height: %d \n",
-                       row_ptr->height);
+               lyxerr << "LYX_ERROR: row.height: " << row_ptr->height << endl;
                return;
        }
-       left_margin = LabelEnd(row_ptr);
        PrepareToPrint(row_ptr, x, fill_separator,
                       fill_hfill, fill_label_hfill);
        
-       int main_body = BeginningOfMainBody(row_ptr->par);
-       
        /* initialize the pixmap */
        
-       scr.fillRectangle(gc_clear,
-                         0, offset, paperwidth, row_ptr->height);
-       // check for NOT FAST SELECTION
-       if (!fast_selection && !mono_video && selection) {
+       pain.fillRectangle(0, offset, paperwidth, row_ptr->height);
+       
+       if (selection) {
                /* selection code */ 
                if (sel_start_cursor.row == row_ptr &&
                    sel_end_cursor.row == row_ptr) {
-                       scr.fillRectangle(gc_selection, sel_start_cursor.x,
-                                         offset,
-                                         sel_end_cursor.x -
-                                         sel_start_cursor.x,
-                                         row_ptr->height);
-               }
-               else if (sel_start_cursor.row == row_ptr) {
-                       scr.fillRectangle(gc_selection, sel_start_cursor.x,
-                                         offset,
-                                         paperwidth - sel_start_cursor.x,
-                                         row_ptr->height);
+                       if (sel_start_cursor.x < sel_end_cursor.x)
+                               pain.fillRectangle(sel_start_cursor.x, offset,
+                                                  sel_end_cursor.x - sel_start_cursor.x,
+                                                  row_ptr->height,
+                                                  LColor::selection);
+                       else
+                               pain.fillRectangle(sel_end_cursor.x, offset,
+                                                  sel_start_cursor.x - sel_end_cursor.x,
+                                                  row_ptr->height,
+                                                  LColor::selection);
+               } else if (sel_start_cursor.row == row_ptr) {
+                       if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                               pain.fillRectangle(sel_start_cursor.x, offset,
+                                                  paperwidth - sel_start_cursor.x,
+                                                  row_ptr->height,
+                                                  LColor::selection);
+                       else
+                               pain.fillRectangle(0, offset,
+                                                  sel_start_cursor.x,
+                                                  row_ptr->height,
+                                                  LColor::selection);
                } else if (sel_end_cursor.row == row_ptr) {
-                       scr.fillRectangle(gc_selection,0, offset,
-                                         sel_end_cursor.x, row_ptr->height);
-               } else if (y > sel_start_cursor.y && y < sel_end_cursor.y) {
-                       scr.fillRectangle(gc_selection, 0, offset,
-                                         paperwidth, row_ptr->height);
+                       if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                               pain.fillRectangle(0, offset,
+                                                  sel_end_cursor.x,
+                                                  row_ptr->height,
+                                                  LColor::selection);
+                       else
+                               pain.fillRectangle(sel_end_cursor.x, offset,
+                                                  paperwidth - sel_end_cursor.x,
+                                                  row_ptr->height,
+                                                  LColor::selection);
                        
+               } else if (y > sel_start_cursor.y && y < sel_end_cursor.y) {
+                       pain.fillRectangle(0, offset,
+                                          paperwidth, row_ptr->height,
+                                          LColor::selection);
                }
-       } // end of NOT FAST SELECTION code
+       }
        
        if (row_ptr->par->appendix){
-         scr.drawVerticalLine(gc_math, 1, offset, offset+row_ptr->height);
-         scr.drawVerticalLine(gc_math, paperwidth-2 , offset, offset+row_ptr->height);
+               pain.line(1, offset,
+                         1, offset + row_ptr->height,
+                         LColor::appendixline);
+               pain.line(paperwidth - 2, offset,
+                         paperwidth - 2, offset + row_ptr->height,
+                         LColor::appendixline);
        }
-
-       if (row_ptr->par->pextra_type == PEXTRA_MINIPAGE) {
+       
+       if (row_ptr->par->pextra_type == LyXParagraph::PEXTRA_MINIPAGE) {
                /* draw a marker at the left margin! */ 
                LyXFont font = GetFont(row_ptr->par, 0);
                int asc = font.maxAscent();
                int x = (LYX_PAPER_MARGIN - font.width('|')) / 2;
                int y1 = (offset + row_ptr->baseline);
                int y2 = (offset + row_ptr->baseline) - asc;
-
-               scr.drawVerticalLine(gc_minipage, x, y1, y2);
+               pain.line(x, y1, x, y2, LColor::minipageline);
        }       
        if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
                LyXFont font(LyXFont::ALL_SANE);
                font.setSize(LyXFont::SIZE_FOOTNOTE);
-               font.setColor(LyXFont::RED);
+               font.setColor(LColor::footnote);
                
                int box_x = LYX_PAPER_MARGIN;
                box_x += font.textWidth(" wide-tab ", 10);
@@ -3344,67 +3760,64 @@ void LyXText::GetVisibleRow(LyXScreen &scr, int offset,
                                break;
                        }
                        
-                       // Determine background color.
-                       gc_type back = gc_lighted;
-                       if (mono_video) {
-                               back = gc_clear;
-                       }
-                       scr.fillRectangle(back,LYX_PAPER_MARGIN, offset+1,
-                                         box_x - LYX_PAPER_MARGIN, 
-                                         int(font.maxAscent())+
-                                         int(font.maxDescent()));
+                       pain.fillRectangle(LYX_PAPER_MARGIN,
+                                          offset + 1,
+                                          box_x - LYX_PAPER_MARGIN,
+                                          int(font.maxAscent()
+                                              + font.maxDescent()),
+                                          LColor::footnotebg);
                        
-                       scr.drawLine(gc_foot,
-                                    offset,
-                                    LYX_PAPER_MARGIN,
-                                    paperwidth - 2*LYX_PAPER_MARGIN);
+                       pain.line(LYX_PAPER_MARGIN, offset,
+                                 paperwidth - LYX_PAPER_MARGIN, offset,
+                                 LColor::footnoteframe);
                        
-                       scr.drawString(font, fs,
-                                      offset + int(font.maxAscent())+1,
-                                      LYX_PAPER_MARGIN);
-                       scr.drawVerticalLine(gc_foot,
-                                            LYX_PAPER_MARGIN,
-                                            offset,
-                                            offset
-                                            + int(font.maxAscent())+
-                                            int(font.maxDescent()));
+                       pain.text(LYX_PAPER_MARGIN,
+                                 offset + int(font.maxAscent()) + 1,
+                                 fs, font);
+                       
+                       pain.line(LYX_PAPER_MARGIN, offset,
+                                 LYX_PAPER_MARGIN,
+                                 offset + int(font.maxAscent()
+                                              + font.maxDescent()),
+                                 LColor::footnoteframe);
+                       
+                       pain.line(LYX_PAPER_MARGIN,
+                                 offset + int(font.maxAscent()
+                                              + font.maxDescent()) + 1,
+                                 box_x,
+                                 offset + int(font.maxAscent()
+                                              + font.maxDescent()) + 1,
+                                 LColor::footnoteframe);
                        
-                       scr.drawLine(gc_foot,
-                                    offset
-                                    + int(font.maxAscent())
-                                    + int(font.maxDescent()) + 1,
-                                    LYX_PAPER_MARGIN, box_x - LYX_PAPER_MARGIN); 
                }
                
                /* draw the open floats in a red box */
-               scr.drawVerticalLine(gc_foot,
-                                    box_x,
-                                    offset,  offset + row_ptr->height);
+               pain.line(box_x, offset,
+                         box_x, offset + row_ptr->height,
+                         LColor::footnoteframe);
                
-               scr.drawVerticalLine(gc_foot,
-                                    paperwidth - LYX_PAPER_MARGIN,
-                                    offset,
-                                    offset + row_ptr->height);
-                       
+               pain.line(paperwidth - LYX_PAPER_MARGIN,
+                         offset,
+                         paperwidth - LYX_PAPER_MARGIN,
+                         offset + row_ptr->height,
+                         LColor::footnoteframe);
+       } else if (row_ptr->previous &&
+                  row_ptr->previous->par->footnoteflag
+                  == LyXParagraph::OPEN_FOOTNOTE) {
+               LyXFont font(LyXFont::ALL_SANE);
+               font.setSize(LyXFont::SIZE_FOOTNOTE);
                
-       } else  {
-               if (row_ptr->previous &&
-                   row_ptr->previous->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
-                       LyXFont font(LyXFont::ALL_SANE);
-                       font.setSize(LyXFont::SIZE_FOOTNOTE);
-                       
-                       int box_x = LYX_PAPER_MARGIN;
-                       box_x += font.textWidth(" wide-tab ", 10);
-                       
-                       scr.drawLine(gc_foot,
-                                    offset,
-                                    box_x,
-                                    paperwidth - LYX_PAPER_MARGIN - box_x);
-               }
+               int box_x = LYX_PAPER_MARGIN;
+               box_x += font.textWidth(" wide-tab ", 10);
+               
+               pain.line(box_x, offset,
+                         paperwidth - LYX_PAPER_MARGIN,
+                         offset, LColor::footnote);
        }
        
-       LyXLayout* layout = lyxstyle.Style(parameters->textclass,
-                                          row_ptr->par->GetLayout());
+       LyXLayout const & layout =
+               textclasslist.Style(parameters->textclass,
+                                   row_ptr->par->GetLayout());
        firstpar = row_ptr->par->FirstPhysicalPar();
        
        y_top = 0;
@@ -3414,132 +3827,181 @@ void LyXText::GetVisibleRow(LyXScreen &scr, int offset,
        if (row_ptr->pos == 0
            && row_ptr->par == firstpar) {
                
-                /* start of appendix? */
+               /* start of appendix? */
                if (row_ptr->par->start_of_appendix){
-                 scr.drawLine(gc_math, 
-                              offset,
-                              1, paperwidth-2);
+                       pain.line(1, offset,
+                                 paperwidth - 2, offset,
+                                 LColor::appendixline);
                }
-
+               
                /* think about the margins */ 
                if (!row_ptr->previous)
                        y_top += LYX_PAPER_MARGIN;
                
                if (row_ptr->par->pagebreak_top){ /* draw a top pagebreak  */
-                       scr.drawOnOffLine(offset + y_top + 2 * DefaultHeight(),
-                                         0, paperwidth);
+#if 0
+                       pain.line(0, offset + y_top + 2 * DefaultHeight(),
+                                 paperwidth,
+                                 offset + y_top + 2 * DefaultHeight(),
+                                 LColor::pagebreak, Painter::line_onoffdash);
+#else
+                       LyXFont pb_font;
+                       pb_font.setColor(LColor::pagebreak).decSize();
+                       int w = 0, a = 0, d = 0;
+                       pain.line(0, offset + y_top + 2*DefaultHeight(),
+                                 paperwidth, 
+                                 offset + y_top + 2*DefaultHeight(),
+                                 LColor::pagebreak, 
+                                 Painter::line_onoffdash)
+                               .rectText(0,
+                                         0,
+                                         _("Page Break (top)"),
+                                         pb_font,
+                                         LColor::background,
+                                         LColor::background, false, w, a, d);
+                       pain.rectText((paperwidth - w)/2,
+                                     offset +y_top + 2*DefaultHeight() +d,
+                                     _("Page Break (top)"),
+                                     pb_font,
+                                     LColor::background,
+                                     LColor::background);
+#endif
                        y_top += 3 * DefaultHeight();
                }
                
                if (row_ptr->par->added_space_top.kind() == VSpace::VFILL) {
                        /* draw a vfill top  */
-                       scr.drawLine(gc_fill, 
-                                    offset + 2 + y_top,
-                                    0, LYX_PAPER_MARGIN);
-                       scr.drawLine(gc_fill,
-                                    offset + y_top + 3 * DefaultHeight(),
-                                    0, LYX_PAPER_MARGIN);
-                       scr.drawVerticalOnOffLine(LYX_PAPER_MARGIN / 2, 
-                                                 offset + 2 + y_top,
-                                                 offset + y_top + 3 *
-                                                 DefaultHeight());
+                       pain.line(0, offset + 2 + y_top,
+                                 LYX_PAPER_MARGIN, offset + 2 + y_top,
+                                 LColor::vfillline);
+                       
+                       pain.line(0, offset + y_top + 3 * DefaultHeight(),
+                                 LYX_PAPER_MARGIN,
+                                 offset + y_top + 3 * DefaultHeight(),
+                                 LColor::vfillline);
+                       
+                       pain.line(LYX_PAPER_MARGIN / 2, offset + 2 + y_top,
+                                 LYX_PAPER_MARGIN / 2,
+                                 offset + y_top + 3 * DefaultHeight(),
+                                 LColor::vfillline);
                        
                        y_top += 3 * DefaultHeight();
                }
                
                /* think about user added space */ 
-               y_top += int(row_ptr->par->added_space_top.inPixels());
+               y_top += int(row_ptr->par->added_space_top.inPixels(owner_));
                
                /* think about the parskip */ 
                /* some parskips VERY EASY IMPLEMENTATION */ 
-               if (parameters->paragraph_separation == LYX_PARSEP_SKIP) {
-                       if (layout->latextype == LATEX_PARAGRAPH
+               if (parameters->paragraph_separation == BufferParams::PARSEP_SKIP) {
+                       if (layout.latextype == LATEX_PARAGRAPH
                            && firstpar->GetDepth() == 0
                            && firstpar->Previous())
-                               y_top += parameters->getDefSkip().inPixels();
+                               y_top += parameters->getDefSkip().inPixels(owner_);
                        else if (firstpar->Previous()
-                                && lyxstyle.Style(parameters->textclass,
-                                                  firstpar->Previous()->GetLayout())->latextype == LATEX_PARAGRAPH
+                                && textclasslist.Style(parameters->textclass,
+                                                       firstpar->Previous()->GetLayout()).latextype == LATEX_PARAGRAPH
                                 && firstpar->Previous()->GetDepth() == 0)
                                // is it right to use defskip here, too? (AS) 
-                               y_top += parameters->getDefSkip().inPixels();
+                               y_top += parameters->getDefSkip().inPixels(owner_);
                }
                
                if (row_ptr->par->line_top) {      /* draw a top line  */
                        y_top +=  GetFont(row_ptr->par, 0).ascent('x');
-
-                       scr.drawThickLine(offset + y_top,
-                                         0, paperwidth);
+                       
+                       pain.line(0, offset + y_top,
+                                 paperwidth, offset + y_top,
+                                 LColor::topline,
+                                 Painter::line_solid,
+                                 Painter::line_thick);
+                       
                        y_top +=  GetFont(row_ptr->par, 0).ascent('x');
                }
                
                /* 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
                        || row_ptr->par->IsFirstInSequence())) {
                        font = GetFont(row_ptr->par, -2);
                        if (!row_ptr->par->GetLabestring().empty()) {
                                tmpx = x;
                                string tmpstring = row_ptr->par->GetLabestring();
                                
-                               if (layout->labeltype == LABEL_COUNTER_CHAPTER) {
-                                       if (parameters->secnumdepth >=0){
+                               if (layout.labeltype == LABEL_COUNTER_CHAPTER) {
+                                       if (parameters->secnumdepth >= 0){
                                                /* this is special code for the chapter layout. This is printed in
                                                 * an extra row and has a pagebreak at the top. */
-                                               maxdesc = int(font.maxDescent() * layout->spacing.getValue() * parameters->spacing.getValue())
-                                                       + int(layout->parsep) * DefaultHeight();
-                                               scr.drawString(font, tmpstring,
-                                                              offset + row_ptr->baseline
-                                                              - row_ptr->ascent_of_text - maxdesc,
-                                                              int(x));
+                                               maxdesc = int(font.maxDescent() * layout.spacing.getValue() * parameters->spacing.getValue())
+                                                       + int(layout.parsep) * DefaultHeight();
+                                               if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                                                       tmpx = paperwidth - LeftMargin(row_ptr) - 
+                                                               font.stringWidth(tmpstring);
+                                               pain.text(int(tmpx),
+                                                         offset + row_ptr->baseline - row_ptr->ascent_of_text - maxdesc,
+                                                         tmpstring, font);
                                        }
                                } else {
-                                       x -= font.stringWidth( layout->labelsep);
-                                       x -= font.stringWidth( tmpstring);
+                                       if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                                               tmpx = x - font.stringWidth(layout.labelsep)
+                                                       - font.stringWidth(tmpstring);
+                                       else {
+                                               tmpx = paperwidth - LeftMargin(row_ptr)
+                                                       + font.stringWidth(layout.labelsep);
+                                               if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)  {
+                                                       LyXFont font(LyXFont::ALL_SANE);
+                                                       font.setSize(LyXFont::SIZE_SMALL);
+                                                       tmpx += font.textWidth("Mwide-figM", 10);
+                                               }
+                                       }
                                        /* draw it! */
-                                       scr.drawString(font, tmpstring,
-                                                      offset + row_ptr->baseline, int(x));
+                                       pain.text(int(tmpx),
+                                                 offset + row_ptr->baseline,
+                                                 tmpstring, font);
                                }
-                               x = tmpx;
                        }
                        /* the labels at the top of an environment. More or less for bibliography */ 
-               } else if (layout->labeltype == LABEL_TOP_ENVIRONMENT ||
-                          layout->labeltype == LABEL_BIBLIO ||
-                          layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) {
+               } else if (layout.labeltype == LABEL_TOP_ENVIRONMENT ||
+                          layout.labeltype == LABEL_BIBLIO ||
+                          layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) {
                        if (row_ptr->par->IsFirstInSequence()) {
                                font = GetFont(row_ptr->par, -2);
                                if (!row_ptr->par->GetLabestring().empty()) {
                                        string tmpstring = row_ptr->par->GetLabestring();
                                        
-                                       maxdesc = int(font.maxDescent() * layout->spacing.getValue() * parameters->spacing.getValue()
-                                                        + (layout->labelbottomsep * DefaultHeight()));
-                                       
-                                       int top_label_x = int(x);
-                                       if (layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT){
-                                               top_label_x = int(x + (paperwidth - RightMargin(row_ptr) - x) / 2); 
-                                               top_label_x -= (font.stringWidth( tmpstring)/2);
-                                       }
+                                       maxdesc = int(font.maxDescent() * layout.spacing.getValue() * parameters->spacing.getValue()
+                                                     + (layout.labelbottomsep * DefaultHeight()));
                                        
-                                       scr.drawString(font, tmpstring,
-                                                      offset + row_ptr->baseline
-                                                      - row_ptr->ascent_of_text - maxdesc,  
-                                                      top_label_x);                
+                                       tmpx = x;
+                                       if (layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT){
+                                               tmpx = ( ((direction == LYX_DIR_LEFT_TO_RIGHT)
+                                                         ? x : LeftMargin(row_ptr) )
+                                                        + paperwidth - RightMargin(row_ptr) ) / 2; 
+                                               tmpx -= (font.stringWidth(tmpstring)/2);
+                                       } else if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                                               tmpx = paperwidth - LeftMargin(row_ptr) - 
+                                                       font.stringWidth(tmpstring);
+                                       pain.text(int(tmpx),
+                                                 offset + row_ptr->baseline
+                                                 - row_ptr->ascent_of_text
+                                                 - maxdesc,
+                                                 tmpstring, font);
                                }
                        }
                }
-               if (layout->labeltype==LABEL_BIBLIO) { // ale970302
-                       if (row_ptr->par->bibkey) {
-                               tmpx = x;
-                               x -= font.stringWidth(layout->labelsep);
-                               font = GetFont(row_ptr->par, -1);
-                               x -= row_ptr->par->bibkey->Width(font);
-                               row_ptr->par->bibkey->Draw(font, scr,
-                                                          offset + row_ptr->baseline, 
-                                                          x);
-                               x = tmpx;
-                       }
-               } 
+               if (layout.labeltype == LABEL_BIBLIO && row_ptr->par->bibkey) {
+                       font = GetFont(row_ptr->par, -1);
+                       if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                               tmpx = x - font.stringWidth(layout.labelsep)
+                                       - row_ptr->par->bibkey->width(owner_->painter(), font);
+                       else
+                               tmpx = paperwidth - LeftMargin(row_ptr)
+                                       + font.stringWidth(layout.labelsep);
+                       row_ptr->par->bibkey->draw(owner_->painter(),
+                                                  font,
+                                                  offset + row_ptr->baseline, 
+                                                  tmpx);
+               }
        }
        
        /* is it a last row? */
@@ -3553,43 +4015,107 @@ void LyXText::GetVisibleRow(LyXScreen &scr, int offset,
                
                /* draw a bottom pagebreak */ 
                if (firstpar->pagebreak_bottom) {
-                       scr.drawOnOffLine(offset + y_bottom - 2 *
-                                         DefaultHeight(),
-                                         0, paperwidth);
+#if 0
+                       pain.line(0, offset + y_bottom - 2 * DefaultHeight(),
+                                 paperwidth,
+                                 offset + y_bottom - 2 * DefaultHeight(),
+                                 LColor::pagebreak, Painter::line_onoffdash);
+#else
+                       LyXFont pb_font;
+                       pb_font.setColor(LColor::pagebreak).decSize();
+                       int w = 0, a = 0, d = 0;
+                       pain.line(0,
+                                 offset + y_bottom - 2 * DefaultHeight(), 
+                                 paperwidth, 
+                                 offset + y_bottom - 2 * DefaultHeight(),
+                                 LColor::pagebreak,
+                                 Painter::line_onoffdash)
+                               .rectText(0,
+                                         0,
+                                         _("Page Break (bottom)"),
+                                         pb_font,
+                                         LColor::background,
+                                         LColor::background, false, w, a, d);
+                       pain.rectText((paperwidth - w)/2,
+                                     offset +y_top + 2*DefaultHeight() +d,
+                                     _("Page Break (bottom)"),
+                                     pb_font,
+                                     LColor::background,
+                                     LColor::background);
+#endif
                        y_bottom -= 3 * DefaultHeight();
                }
                
                if (firstpar->added_space_bottom.kind() == VSpace::VFILL) {
                        /* draw a vfill bottom  */
-                       scr.drawLine(gc_fill,
-                                    offset + y_bottom - 3 * DefaultHeight(),
-                                    0, LYX_PAPER_MARGIN);
-                       scr.drawLine(gc_fill, offset + y_bottom - 2,
-                                    0, LYX_PAPER_MARGIN);
-                       scr.drawVerticalOnOffLine(LYX_PAPER_MARGIN / 2, 
-                                                 offset + y_bottom - 3 * DefaultHeight(),
-                                                 offset + y_bottom - 2
-                               );          
+                       pain.line(0, offset + y_bottom - 3 * DefaultHeight(),
+                                 LYX_PAPER_MARGIN,
+                                 offset + y_bottom - 3 * DefaultHeight(),
+                                 LColor::vfillline);
+                       pain.line(0, offset + y_bottom - 2,
+                                 LYX_PAPER_MARGIN,
+                                 offset + y_bottom - 2,
+                                 LColor::vfillline);
+                       pain.line(LYX_PAPER_MARGIN / 2,
+                                 offset + y_bottom - 3 * DefaultHeight(),
+                                 LYX_PAPER_MARGIN / 2,
+                                 offset + y_bottom - 2,
+                                 LColor::vfillline);
                        y_bottom -= 3* DefaultHeight();
                }
                
                /* think about user added space */ 
-               y_bottom -= int(firstpar->added_space_bottom.inPixels());
+               y_bottom -= int(firstpar->added_space_bottom.inPixels(owner_));
                
                if (firstpar->line_bottom) {
                        /* draw a bottom line */
                        y_bottom -= GetFont(par, par->Last() - 1).ascent('x');
-
-                       scr.drawThickLine(offset + y_bottom,
-                                         0, paperwidth);           
+                       pain.line(0, offset + y_bottom,
+                                 paperwidth, offset + y_bottom,
+                                 LColor::topline, Painter::line_solid,
+                                 Painter::line_thick);
                        y_bottom -= GetFont(par, par->Last() - 1).ascent('x');
                }
+
+               // draw an endlabel
+               int endlabel = row_ptr->par->GetEndLabel();
+               if (endlabel == END_LABEL_BOX ||
+                   endlabel == END_LABEL_FILLED_BOX) {
+                       LyXFont font = GetFont(row_ptr->par, RowLast(row_ptr));
+                       int size = int(0.75*font.maxAscent());
+                       int y = (offset + row_ptr->baseline) - size;
+                       int x = (direction == LYX_DIR_LEFT_TO_RIGHT)
+                               ? paperwidth - LYX_PAPER_MARGIN - size
+                               : LYX_PAPER_MARGIN;
+                       if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)
+                               if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                                       x -= LYX_PAPER_MARGIN/2;
+                               else {
+                                       LyXFont font(LyXFont::ALL_SANE);
+                                       font.setSize(LyXFont::SIZE_SMALL);
+                                       x += font.textWidth("Mwide-figM", 10);
+                               }
+                       if (row_ptr->fill <= size)
+                               x += (size - row_ptr->fill + 1) * direction;
+                       if (endlabel == END_LABEL_BOX) {
+                               pain.line(x, y, x, y + size,
+                                         LColor::eolmarker);
+                               pain.line(x + size, y, x + size , y + size,
+                                         LColor::eolmarker);
+                               pain.line(x, y, x + size, y,
+                                         LColor::eolmarker);
+                               pain.line(x, y + size, x + size, y + size,
+                                         LColor::eolmarker);
+                       } else
+                               pain.fillRectangle(x, y, size, size,
+                                                  LColor::eolmarker);
+               }
        }
        
        /* draw the text in the pixmap */  
        pos_end = RowLast(row_ptr);
        
-       pos = row_ptr->pos;
+       vpos = row_ptr->pos;
        /* table stuff -- begin*/
        if (row_ptr->par->table) {
                bool on_off;
@@ -3597,7 +4123,8 @@ void LyXText::GetVisibleRow(LyXScreen &scr, int offset,
                float x_old = x;
                x += row_ptr->par->table->GetBeginningOfTextInCell(cell);
                
-               while (pos <= pos_end)  {
+               while (vpos <= pos_end)  {
+                       pos = vis2log(vpos);
                        if (row_ptr->par->IsNewline(pos)) {
                                
                                x = x_old + row_ptr->par->table->WidthOfColumn(cell);
@@ -3606,76 +4133,100 @@ void LyXText::GetVisibleRow(LyXScreen &scr, int offset,
                                if ((!on_off ||
                                     !row_ptr->par->table->TopAlreadyDrawed(cell)) &&
                                    !row_ptr->par->table->IsContRow(cell))
-                                       scr.drawTableLine(offset + row_ptr->baseline -
-                                                         row_ptr->ascent_of_text,
-                                                         int(x_old), int(x - x_old), on_off);
+                                       pain.line(int(x_old),
+                                                 offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                                 int(x),
+                                                 offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                                 LColor::tableline,
+                                                 on_off ? Painter::line_onoffdash : Painter::line_solid);
+                               
                                on_off = !row_ptr->par->table->BottomLine(cell);
                                if ((!on_off && !row_ptr->par->table->RowHasContRow(cell)) ||
                                    row_ptr->par->table->VeryLastRow(cell))
-                                       scr.drawTableLine(offset + y_bottom - 1,
-                                                         int(x_old), int(x - x_old), on_off);
+                                       
+                                       pain.line(int(x_old),
+                                                 offset + y_bottom - 1,
+                                                 int(x),
+                                                 offset + y_bottom - 1,
+                                                 LColor::tableline,
+                                                 on_off ? Painter::line_onoffdash : Painter::line_solid);
+                               
                                on_off = !row_ptr->par->table->LeftLine(cell);
                                
-                               scr.drawVerticalTableLine(int(x_old), 
-                                                         offset + row_ptr->baseline -
-                                                         row_ptr->ascent_of_text,
-                                                         offset + y_bottom - 1,
-                                                         on_off);
+                               pain.line(int(x_old),
+                                         offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                         int(x_old),
+                                         offset + y_bottom - 1,
+                                         LColor::tableline,
+                                         on_off ? Painter::line_onoffdash : Painter::line_solid);
+                               
                                on_off = !row_ptr->par->table->RightLine(cell);
                                
-                               scr.drawVerticalTableLine(int(x) -
-                                                         row_ptr->par->table->AdditionalWidth(cell),
-                                                         offset + row_ptr->baseline -
-                                                         row_ptr->ascent_of_text,
-                                                         offset + y_bottom - 1,
-                                                         on_off);
+                               pain.line(int(x) - row_ptr->par->table->AdditionalWidth(cell),
+                                         offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                         int(x) - row_ptr->par->table->AdditionalWidth(cell),
+                                         offset + y_bottom - 1,
+                                         LColor::tableline,
+                                         on_off ? Painter::line_onoffdash : Painter::line_solid);
+                               
                                x_old = x;
-                /* take care about the alignment and other spaces */
-                               cell++;
+                               /* take care about the alignment and other spaces */
+                               ++cell;
                                x += row_ptr->par->table->GetBeginningOfTextInCell(cell);
                                if (row_ptr->par->table->IsFirstCell(cell))
-                                       cell--; // little hack, sorry
-                               pos++;
+                                       --cell; // little hack, sorry
+                               ++vpos;
                        } else if (row_ptr->par->IsHfill(pos)) {
                                x += 1;
                                
-                               scr.drawVerticalLine(gc_fill, int(x),  
-                                                    offset + row_ptr->baseline - DefaultHeight()/2, 
-                                                    offset + row_ptr->baseline);               
+                               pain.line(int(x),
+                                         offset + row_ptr->baseline - DefaultHeight() / 2,
+                                         int(x),
+                                         offset + row_ptr->baseline,
+                                         LColor::vfillline);
+                               
                                x += 2;
-                               pos++;
-                       } else {
-                               if (row_ptr->par->IsSeparator(pos)) {
-                                       tmpx = x;
-                                       x+=SingleWidth(row_ptr->par, pos);
-                                       /* -------> Only draw protected spaces when not in
-                                        * free-spacing mode. */
-                                       if (row_ptr->par->GetChar(pos)==LYX_META_PROTECTED_SEPARATOR && !layout->free_spacing) {
-                                               scr.drawVerticalLine(gc_fill, int(tmpx),
-                                                                    offset + row_ptr->baseline - 3,
-                                                                    offset + row_ptr->baseline - 1);
-                                               scr.drawLine(gc_fill,
-                                                            offset + row_ptr->baseline - 1,
-                                                            int(tmpx),
-                                                            int(x-tmpx-2));
-                                               scr.drawVerticalLine(gc_fill, int(x-2),
-                                                                    offset + row_ptr->baseline - 3,
-                                                                    offset + row_ptr->baseline - 1);                   
-                                               /* what about underbars? */
-                                               font = GetFont(row_ptr->par, pos); 
-                                               if (font.underbar() == LyXFont::ON
-                                                   && font.latex() != LyXFont::ON) {
-                                                       scr.drawLine(gc_copy,
-                                                                    offset +
-                                                                    row_ptr->baseline + 2,
-                                                                    int(tmpx),
-                                                                    int(x - tmpx));                        
-                                               }
+                               ++vpos;
+                       } else if (row_ptr->par->IsSeparator(pos)) {
+                               tmpx = x;
+                               x+= SingleWidth(row_ptr->par, pos);
+#warning Think about this.
+#if 0
+                               /* -------> Only draw protected spaces when
+                                * not in free-spacing mode. */
+                               if (row_ptr->par->GetChar(pos) == LyXParagraph::META_PROTECTED_SEPARATOR && !layout.free_spacing) {
+                                       pain.line(int(tmpx),
+                                                 offset + row_ptr->baseline - 3,
+                                                 int(tmpx),
+                                                 offset + row_ptr->baseline - 1,
+                                                 LColor::vfillline);
+                                       
+                                       pain.line(int(tmpx),
+                                                 offset + row_ptr->baseline - 1,
+                                                 int(x - 2),
+                                                 offset + row_ptr->baseline - 1,
+                                                 LColor::vfillline);
+                                       
+                                       pain.line(int(x - 2),
+                                                 offset + row_ptr->baseline - 3,
+                                                 int(x - 2),
+                                                 offset + row_ptr->baseline - 1,
+                                                 LColor::vfillline);
+                                       
+                                       /* what about underbars? */
+                                       font = GetFont(row_ptr->par, pos); 
+                                       if (font.underbar() == LyXFont::ON
+                                           && font.latex() != LyXFont::ON) {
+                                               pain.line(int(tmpx),
+                                                         offset + row_ptr->baseline + 2,
+                                                         int(x - tmpx),
+                                                         offset + row_ptr->baseline + 2);
                                        }
-                                       pos++;
-                               } else
-                                       Draw(row_ptr, pos, scr, offset, x);
-                       }
+                               }
+#endif
+                               ++vpos;
+                       } else
+                               draw(row_ptr, vpos, offset, x);
                }
                
                /* do not forget the very last cell. This has no NEWLINE so 
@@ -3687,136 +4238,142 @@ void LyXText::GetVisibleRow(LyXScreen &scr, int offset,
                             !row_ptr->par->table->TopAlreadyDrawed(cell)) &&
                            !row_ptr->par->table->IsContRow(cell))
                                
-                               scr.drawTableLine(offset + row_ptr->baseline -
-                                                 row_ptr->ascent_of_text,
-                                                 int(x_old), int(x - x_old), on_off);      
+                               pain.line(int(x_old),
+                                         offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                         int(x),
+                                         offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                         LColor::tableline,
+                                         on_off ? Painter::line_onoffdash : Painter::line_solid);
                        on_off = !row_ptr->par->table->BottomLine(cell);
                        if ((!on_off && !row_ptr->par->table->RowHasContRow(cell)) ||
                            row_ptr->par->table->VeryLastRow(cell))
                                
-                               scr.drawTableLine(offset + y_bottom - 1,
-                                                 int(x_old), int(x - x_old), on_off);      
+                               pain.line(int(x_old),
+                                         offset + y_bottom - 1,
+                                         int(x),
+                                         offset + y_bottom - 1,
+                                         LColor::tableline,
+                                         on_off ? Painter::line_onoffdash : Painter::line_solid);
+                       
                        on_off = !row_ptr->par->table->LeftLine(cell);
                        
-                       scr.drawVerticalTableLine(int(x_old), 
-                                                 offset + row_ptr->baseline -
-                                                 row_ptr->ascent_of_text,
-                                                 offset + y_bottom - 1,
-                                                 on_off);          
+                       pain.line(int(x_old),
+                                 offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                 int(x_old),
+                                 offset + y_bottom - 1,
+                                 LColor::tableline,
+                                 on_off ? Painter::line_onoffdash : Painter::line_solid);
+                       
                        on_off = !row_ptr->par->table->RightLine(cell);
                        
-                       scr.drawVerticalTableLine(int(x) -
-                                                 row_ptr->par->table->AdditionalWidth(cell),
-                                                 offset + row_ptr->baseline -
-                                                 row_ptr->ascent_of_text,
-                                                 offset + y_bottom - 1,
-                                                 on_off);          
+                       pain.line(int(x) - row_ptr->par->table->AdditionalWidth(cell),
+                                 offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                 int(x) - row_ptr->par->table->AdditionalWidth(cell),
+                                 offset + y_bottom - 1,
+                                 LColor::tableline,
+                                 on_off ? Painter::line_onoffdash : Painter::line_solid);
                }
        } else {
                /* table stuff -- end*/
+               LyXParagraph::size_type main_body = 
+                       BeginningOfMainBody(row_ptr->par);
+               if (main_body > 0 &&
+                   (main_body-1 > pos_end || 
+                    !row_ptr->par->IsLineSeparator(main_body-1)))
+                       main_body = 0;
                
-               while (pos <= pos_end)  {
+               while (vpos <= pos_end)  {
+                       pos = vis2log(vpos);
+                       if (main_body > 0 && pos == main_body-1) {
+                               x += fill_label_hfill
+                                       + GetFont(row_ptr->par, -2).stringWidth(layout.labelsep)
+                                       - SingleWidth(row_ptr->par, main_body-1);
+                       }
                        
                        if (row_ptr->par->IsHfill(pos)) {
                                x += 1;
-                               scr.drawVerticalLine(gc_fill, int(x),  
-                                                    offset + row_ptr->baseline - DefaultHeight()/2, 
-                                                    offset + row_ptr->baseline);               
-                               if (HfillExpansion(row_ptr,pos)) {
+                               pain.line(int(x),
+                                         offset + row_ptr->baseline - DefaultHeight() / 2,
+                                         int(x),
+                                         offset + row_ptr->baseline,
+                                         LColor::vfillline);
+                               
+                               if (HfillExpansion(row_ptr, pos)) {
                                        if (pos >= main_body) {
-                                               scr.drawOnOffLine(offset + row_ptr->baseline -
-                                                                 DefaultHeight()/4,
-                                                                 int(x),
-                                                                 int(fill_hfill));                     
+                                               pain.line(int(x),
+                                                         offset + row_ptr->baseline - DefaultHeight() / 4,
+                                                         int(x + fill_hfill),
+                                                         offset + row_ptr->baseline - DefaultHeight() / 4,
+                                                         LColor::vfillline,
+                                                         Painter::line_onoffdash);
                                                x += fill_hfill;
-                    } else {
-                           scr.drawOnOffLine(offset + row_ptr->baseline -
-                                             DefaultHeight()/4,
-                                             int(x),
-                                             int(fill_label_hfill));
-                           x += fill_label_hfill;
-                    }
-                                       scr.drawVerticalLine(gc_fill, int(x),
-                                                            offset + row_ptr->baseline -
-                                                            DefaultHeight()/2, 
-                                                            offset + row_ptr->baseline);
+                                       } else {
+                                               pain.line(int(x),
+                                                         offset + row_ptr->baseline - DefaultHeight() / 4,
+                                                         int(x + fill_label_hfill),
+                                                         offset + row_ptr->baseline - DefaultHeight() / 4,
+                                                         LColor::vfillline,
+                                                         Painter::line_onoffdash);
+                                               
+                                               x += fill_label_hfill;
+                                       }
+                                       pain.line(int(x),
+                                                 offset + row_ptr->baseline - DefaultHeight() / 2,
+                                                 int(x),
+                                                 offset + row_ptr->baseline,
+                                                 LColor::vfillline);
                                }
                                x += 2;
-                               pos++;
-                       } else {
-                               if (row_ptr->par->IsSeparator(pos)) {
-                                       tmpx = x;
-                                       x+=SingleWidth(row_ptr->par, pos);
-                                       if (pos >= main_body)
-                                               x+= fill_separator;
-                                       /* -------> Only draw protected spaces when not in
-                                        * free-spacing mode. */
-                                       if (row_ptr->par->GetChar(pos)==LYX_META_PROTECTED_SEPARATOR && !layout->free_spacing) {
-                                               
-                                               scr.drawVerticalLine(gc_fill, int(tmpx),
-                                                                    offset + row_ptr->baseline - 3,
-                                                                    offset + row_ptr->baseline - 1);
-                                               scr.drawLine(gc_fill,
-                                                            offset + row_ptr->baseline - 1,
-                                                            int(tmpx),
-                                                            int(x-tmpx-2));
-                                               scr.drawVerticalLine(gc_fill, int(x-2),
-                                                                    offset + row_ptr->baseline - 3,
-                                                                    offset + row_ptr->baseline - 1);                   
-                                               /* what about underbars? */
-                                               font = GetFont(row_ptr->par, pos); 
-                                               if (font.underbar() == LyXFont::ON
-                                                   && font.latex() != LyXFont::ON) {
-                                                       scr.drawLine(gc_copy,
-                                            offset + row_ptr->baseline + 2,
-                                                                    int(tmpx),
-                                                                    int(x - tmpx));
-                                               }
+                               ++vpos;
+                       } else if (row_ptr->par->IsSeparator(pos)) {
+                               tmpx = x;
+                               x+= SingleWidth(row_ptr->par, pos);
+                               if (pos >= main_body)
+                                       x+= fill_separator;
+#warning Think about this
+#if 0
+                               /* -------> Only draw protected spaces when
+                                * not in free-spacing mode. */
+                               if (row_ptr->par->GetChar(pos) == LyXParagraph::META_PROTECTED_SEPARATOR && !layout.free_spacing) {
+                                       
+                                       pain.line(int(tmpx),
+                                                 offset + row_ptr->baseline - 3,
+                                                 int(tmpx),
+                                                 offset + row_ptr->baseline - 1,
+                                                 LColor::vfillline);
+                                       
+                                       pain.line(int(tmpx),
+                                                 offset + row_ptr->baseline - 1,
+                                                 int(x - 2),
+                                                 offset + row_ptr->baseline - 1,
+                                                 LColor::vfillline);
+                                       
+                                       pain.line(int(x - 2),
+                                                 offset + row_ptr->baseline - 3,
+                                                 int(x - 2),
+                                                 offset + row_ptr->baseline - 1,
+                                                 LColor::vfillline);
+                                       
+                                       /* what about underbars? */
+                                       font = GetFont(row_ptr->par, pos); 
+                                       if (font.underbar() == LyXFont::ON
+                                           && font.latex() != LyXFont::ON) {
+                                               pain.line(int(tmpx),
+                                                         offset + row_ptr->baseline + 2,
+                                                         int(x - tmpx),
+                                                         offset + row_ptr->baseline + 2);
                                        }
-                                       pos++;
-                               } else
-                                       Draw(row_ptr, pos, scr, offset, x);
-                       }
-                       if (pos == main_body) {
-                               x += GetFont(row_ptr->par, -2).stringWidth(
-                                       layout->labelsep);
-                               if (row_ptr->par->IsLineSeparator(pos - 1))
-                                       x-= SingleWidth(row_ptr->par, pos - 1);
-                               if (x < left_margin)
-                                       x = left_margin;
-                       }
-               }
-       }
-       // check for FAST SELECTION
-       if (fast_selection || mono_video){
-               if (selection) {
-                       
-                       /* selection code */ 
-                       if (sel_start_cursor.row == row_ptr && sel_end_cursor.row == row_ptr) {
-                               scr.fillRectangle(gc_select,sel_start_cursor.x, offset,
-                                                 sel_end_cursor.x - sel_start_cursor.x,
-                                                 row_ptr->height); 
-                       } else if (sel_start_cursor.row == row_ptr) {
-                               scr.fillRectangle(gc_select, sel_start_cursor.x, offset,
-                                                 paperwidth - sel_start_cursor.x,
-                                                 row_ptr->height);
-                       } else if (sel_end_cursor.row == row_ptr) {
-                               scr.fillRectangle(gc_select, 0, offset,
-                                                 sel_end_cursor.x,
-                                                 row_ptr->height);
-                       } else if (y > sel_start_cursor.y && y < sel_end_cursor.y) {
-                               scr.fillRectangle(gc_select, 0, offset,
-                                                 paperwidth, row_ptr->height);
-                               
-                       }
+                               }
+#endif
+                               ++vpos;
+                       } else
+                               draw(row_ptr, vpos, offset, x);
                }
        }
-// end of FAST SELECTION code
-       /* thats it */ 
 }
 
 
-int LyXText::DefaultHeight()
+int LyXText::DefaultHeight() const
 {
        LyXFont font(LyXFont::ALL_SANE);
        return int(font.maxAscent() + font.maxDescent() * 1.5);
@@ -3825,63 +4382,66 @@ int LyXText::DefaultHeight()
    
 /* returns the column near the specified x-coordinate of the row 
 * x is set to the real beginning of this column  */ 
-int  LyXText::GetColumnNearX(Row *row, int& x)
+int LyXText::GetColumnNearX(Row * row, int & x) const
 {
-       int c; 
        float tmpx = 0.0;
        float fill_separator, fill_hfill, fill_label_hfill;
-       int left_margin;
    
-       left_margin = LabelEnd(row);
        PrepareToPrint(row, tmpx, fill_separator,
                       fill_hfill, fill_label_hfill);
-       int main_body = BeginningOfMainBody(row->par);
-   
-       c = row->pos;
 
-       int last = RowLast(row);
-       if (row->par->IsNewline(last))
-               last--;
-   
-       LyXLayout *layout = lyxstyle.Style(parameters->textclass,
-                                          row->par->GetLayout());
-       /* table stuff -- begin*/
+       LyXDirection direction = row->par->getParDirection();
+       LyXParagraph::size_type vc = row->pos;
+       LyXParagraph::size_type last = RowLast(row);
+       LyXParagraph::size_type c = 0;
+
+       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+                                                      row->par->GetLayout());
+       /* table stuff -- begin */
        if (row->par->table) {
-               if (!row->next || row->next->par != row->par)
-                       last = RowLast(row); /* the last row doesn't need a newline at the end*/
+               if (row->next && row->next->par == row->par //the last row doesn't need a newline at the end
+                   && row->par->IsNewline(last))
+                       last--;
                int cell = NumberOfCell(row->par, row->pos);
                float x_old = tmpx;
                bool ready = false;
                tmpx += row->par->table->GetBeginningOfTextInCell(cell);
-               while (c <= last
+               while (vc <= last
+                      && (c = vis2log(vc)) >= 0
                       && tmpx + (SingleWidth(row->par, c)/2) <= x
                       && !ready){
                        if (row->par->IsNewline(c)) {
                                if (x_old + row->par->table->WidthOfColumn(cell) <= x){
                                        tmpx = x_old + row->par->table->WidthOfColumn(cell);
                                        x_old = tmpx;
-                                       cell++;
+                                       ++cell;
                                        tmpx += row->par->table->GetBeginningOfTextInCell(cell);
-                                       c++;
+                                       ++vc;
                                } else
                                        ready = true;
                        } else {
                                tmpx += SingleWidth(row->par, c);
-                               c++;
+                               ++vc;
                        }
                }
-       } else
+       } else {
                /* table stuff -- end*/
-
-               while (c <= last
-                      && tmpx + (SingleWidth(row->par, c)/2)  <= x) {
-                       
-                       if (c && c == main_body
-                           && !row->par->IsLineSeparator(c - 1)) {
-                               tmpx += GetFont(row->par, -2)
-                                       .stringWidth(layout->labelsep);
-                               if (tmpx < left_margin)
-                                       tmpx = left_margin;
+               LyXParagraph::size_type main_body = BeginningOfMainBody(row->par);
+               float last_tmpx = tmpx;
+
+               if (main_body > 0 &&
+                   (main_body-1 > last || 
+                    !row->par->IsLineSeparator(main_body-1)))
+                       main_body = 0;
+
+               while (vc <= last && tmpx <= x) {
+                       c = vis2log(vc);
+                       last_tmpx = tmpx;
+                       if (main_body > 0 && c == main_body-1) {
+                               tmpx += fill_label_hfill +
+                                       GetFont(row->par, -2).stringWidth(layout.labelsep);
+                               if (row->par->IsLineSeparator(main_body-1))
+                                       tmpx -= SingleWidth(row->par, main_body-1);
                        }
             
                        tmpx += SingleWidth(row->par, c);
@@ -3895,25 +4455,55 @@ int  LyXText::GetColumnNearX(Row *row, int& x)
                                 && row->par->IsSeparator(c)) {
                                tmpx+= fill_separator;  
                        }
-                       c++;
-                       if (c == main_body
-                           && row->par->IsLineSeparator(c - 1)) {
-                               tmpx += GetFont(row->par, -2)
-                                       .stringWidth(layout->labelsep);
-                               tmpx-= SingleWidth(row->par, c - 1);
-                               if (tmpx < left_margin)
-                                       tmpx = left_margin;
-                       }
+                       ++vc;
+               }
+
+               if (vc > row->pos && (tmpx+last_tmpx)/2 > x) {
+                       vc--;
+                       tmpx = last_tmpx;
                }
+       }
        /* make sure that a last space in a row doesnt count */
-       if (c > 0 && c >= last
-           && row->par->IsLineSeparator(c - 1)
-           && !(!row->next || row->next->par != row->par)) {
-               tmpx -= SingleWidth(row->par, c - 1);
-               tmpx -= fill_separator;
+       if (row->pos <= last
+           && !(!row->next || row->next->par != row->par))
+               if (direction == LYX_DIR_LEFT_TO_RIGHT && vc > last
+                   && row->par->IsLineSeparator(vis2log(last)) ) {
+                       vc = last;
+                       tmpx -= fill_separator+SingleWidth(row->par, vis2log(last));
+               } else if (direction == LYX_DIR_RIGHT_TO_LEFT 
+                          && vc == row->pos
+                          && row->par->IsLineSeparator(vis2log(row->pos)) ) {
+                       vc = row->pos+1;
+                       tmpx += fill_separator+SingleWidth(row->par, vis2log(row->pos));
+               }
+       if (row->pos > last)  // Row is empty?
+               c = row->pos;
+       else if (vc > last ||
+                (row->par->table && vc > row->pos && row->par->IsNewline(vc)) ){
+               int pos = (vc > last+1) ? last : vc - 1; 
+               c = vis2log(pos);
+               if (row->par->getLetterDirection(c) == LYX_DIR_LEFT_TO_RIGHT)
+                       ++c;
+       } else {
+               c = vis2log(vc);
+               LyXDirection direction = row->par->getLetterDirection(c);
+               if (vc > row->pos && row->par->IsLineSeparator(c)
+                   && row->par->getLetterDirection(vis2log(vc - 1)) != direction)
+                       c = vis2log(vc-1);
+               if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                       ++c;
        }
-       c-=row->pos;
-       
+
+       if (!row->par->table && row->pos <= last && c > last
+           && row->par->IsNewline(last)) {
+               if (row->par->getLetterDirection(last) == LYX_DIR_LEFT_TO_RIGHT)
+                       tmpx -= SingleWidth(row->par, last);
+               else
+                       tmpx += SingleWidth(row->par, last);
+               c = last;
+       }
+
+       c -= row->pos;
        x = int(tmpx);
        return c;
 }
@@ -3932,7 +4522,7 @@ void LyXText::InsertFootnoteEnvironment(LyXParagraph::footnote_kind kind)
    }
    /* no marginpars in minipages */
    if (kind == LyXParagraph::MARGIN 
-      && cursor.par->pextra_type == PEXTRA_MINIPAGE) {
+      && cursor.par->pextra_type == LyXParagraph::PEXTRA_MINIPAGE) {
       WriteAlert(_("Impossible operation"), 
                 _("You can't insert a marginpar in a minipage!"), 
                 _("Sorry."));
@@ -4021,11 +4611,17 @@ void LyXText::InsertFootnoteEnvironment(LyXParagraph::footnote_kind kind)
                || kind == LyXParagraph::WIDE_TAB
               || kind == LyXParagraph::WIDE_FIG 
                || kind == LyXParagraph::ALGORITHM) {
-                  int lay = lyxstyle.NumberOfLayout(parameters->textclass,
-                                                    "Caption");
-                  if (lay == -1) // layout not found
-                          // use default layout "Standard" (0)
-                          lay = 0;
+                  pair<bool, LyXTextClass::size_type> lres =
+                          textclasslist.NumberOfLayout(parameters->textclass,
+                                                       "Caption");
+                  LyXTextClass::size_type lay;
+                  if (lres.first) {
+                          // layout fount
+                          lay = lres.second;
+                  } else {
+                          // layout not found
+                          lay = 0; // use default layout "Standard" (0)
+                  }
                   tmppar->SetLayout(lay);
           }
    }
@@ -4056,61 +4652,77 @@ void LyXText::InsertFootnoteEnvironment(LyXParagraph::footnote_kind kind)
 }
    
 
-/* returns pointer to a specified row */
-Row* LyXText::GetRow(LyXParagraph *par, int pos, long &y)
+// returns pointer to a specified row
+Row * LyXText::GetRow(LyXParagraph * par,
+                     LyXParagraph::size_type pos, long & y) const
 {
-   Row* tmprow;
-
-   if (currentrow){
-     if (par == currentrow->par || par == currentrow->par->Previous()){
-            // do not dereference par, it may have been deleted
-            // already! (Matthias) 
-            while (currentrow->previous && currentrow->previous->par != par){
-                    currentrow = currentrow->previous;
-                    currentrow_y -= currentrow->height;
-            }
-            while (currentrow->previous && currentrow->previous->par == par){
-                    currentrow = currentrow->previous;
-                    currentrow_y -= currentrow->height;
-            }
-     }
-     tmprow = currentrow;
-     y = currentrow_y;
-     /* find the first row of the specified paragraph */ 
-     while (tmprow->next && (tmprow->par != par)) {
-       y += tmprow->height;
-       tmprow = tmprow->next;
-     }
+       Row * tmprow;
+
+       if (currentrow) {
+               if (par == currentrow->par
+                   || par == currentrow->par->Previous()) {
+                       // do not dereference par, it may have been deleted
+                       // already! (Matthias)
+
+                       // Walk backwards as long as the previous
+                       // rows par is not par
+                       while (currentrow->previous
+                              && currentrow->previous->par != par) {
+                               currentrow = currentrow->previous;
+                               currentrow_y -= currentrow->height;
+                       }
+                       // Walk backwards as long as the previous
+                       // rows par _is_ par
+                       while (currentrow->previous
+                              && currentrow->previous->par == par) {
+                               currentrow = currentrow->previous;
+                               currentrow_y -= currentrow->height;
+                       }
+               }
 
-     if (tmprow->par == par){
-       /* now find the wanted row */ 
-       while (tmprow->pos < pos && tmprow->next && tmprow->next->par == par && 
-             tmprow->next->pos <= pos) {
-        y += tmprow->height;
-       tmprow = tmprow->next;
-       }
-       currentrow = tmprow;
-       currentrow_y = y;
-       return tmprow;
-     }
-   }
-   tmprow = firstrow;
-   y = 0;
-   /* find the first row of the specified paragraph */ 
-   while (tmprow->next && (tmprow->par != par)) {
-      y += tmprow->height;
-      tmprow = tmprow->next;
-   }
-   /* now find the wanted row */ 
-   while (tmprow->pos < pos && tmprow->next && tmprow->next->par == par && 
-         tmprow->next->pos <= pos) {
-            y += tmprow->height;
-            tmprow = tmprow->next;
-   }
-   
-   currentrow = tmprow;
-   currentrow_y = y;
+               tmprow = currentrow;
+               y = currentrow_y;
+               // find the first row of the specified paragraph
+               while (tmprow->next
+                      && tmprow->par != par) {
+                       y += tmprow->height;
+                       tmprow = tmprow->next;
+               }
+               
+               if (tmprow->par == par){
+                       // now find the wanted row
+                       while (tmprow->pos < pos
+                              && tmprow->next
+                              && tmprow->next->par == par
+                              && tmprow->next->pos <= pos) {
+                               y += tmprow->height;
+                               tmprow = tmprow->next;
+                       }
+                       currentrow = tmprow;
+                       currentrow_y = y;
+                       return tmprow;
+               }
+       }
 
-   return tmprow;
+       tmprow = firstrow;
+       y = 0;
+       // find the first row of the specified paragraph
+       while (tmprow->next && tmprow->par != par) {
+               y += tmprow->height;
+               tmprow = tmprow->next;
+       }
+       
+       // now find the wanted row
+       while (tmprow->pos < pos
+              && tmprow->next
+              && tmprow->next->par == par
+              && tmprow->next->pos <= pos) {
+               y += tmprow->height;
+               tmprow = tmprow->next;
+       }
+       
+       currentrow = tmprow;
+       currentrow_y = y;
+       
+       return tmprow;
 }