]> git.lyx.org Git - features.git/blobdiff - src/text.C
clear()->erase() ; lots of using directives for cxx
[features.git] / src / text.C
index 6f9d5cb112b84f57e8efea62b7513866ae80eb04..923b5f90395f1c3ea7c346f97a766c97c6fa344b 100644 (file)
@@ -4,7 +4,7 @@
  *           LyX, The Document Processor
  *      
  *           Copyright 1995 Matthias Ettrich
- *           Copyright 1995-1999 The LyX Team.
+ *           Copyright 1995-2000 The LyX Team.
  *
  * ====================================================== */
 
 #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"
+#include "font.h"
 
 using std::max;
 using std::min;
+using std::endl;
+using std::pair;
 
 static const int LYX_PAPER_MARGIN = 20;
 
-extern int mono_video;
-extern int reverse_video;
-extern int fast_selection;
-extern BufferView * current_view;
-extern LyXRC * lyxrc;
 
 // ale070405
-#ifdef USE_PAINTER
 extern int bibitemMaxWidth(Painter &, LyXFont const &);
-#else
-extern int bibitemMaxWidth(LyXFont const &);
-#endif
 
-#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;
+}
+
+
+unsigned char LyXText::TransformChar(unsigned char c, LyXParagraph * par,
+                       LyXParagraph::size_type pos) const
+{
+       if (!is_arabic(c))
+               if (isdigit(c))
+                       return c + (0xb0 - '0');
+               else
+                       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);
+}
+
+// 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
@@ -61,7 +172,6 @@ int LyXText::SingleWidth(LyXParagraph * par,
 }
 
 
-#ifdef USE_PAINTER
 int LyXText::SingleWidth(LyXParagraph * par,
                         LyXParagraph::size_type pos, char c) const
 {
@@ -69,7 +179,10 @@ int LyXText::SingleWidth(LyXParagraph * par,
 
        // The most common case is handled first (Asger)
        if (IsPrintable(c)) {
-               return font.width(c);
+               if (font.language()->lang == "arabic" &&
+                   lyxrc.font_norm == "iso8859-6.8x")
+                       c = TransformChar(c, par, pos);
+               return lyxfont::width(c, font);
 
        } else if (IsHfillChar(c)) {
                return 3;       /* Because of the representation
@@ -107,7 +220,7 @@ int LyXText::SingleWidth(LyXParagraph * par,
                }
                font.decSize();
                font.decSize();
-               return font.stringWidth(fs);
+               return lyxfont::width(fs, font);
        } else if (c == LyXParagraph::META_INSET) {
                Inset * tmpinset= par->GetInset(pos);
                if (tmpinset)
@@ -120,73 +233,8 @@ int LyXText::SingleWidth(LyXParagraph * par,
                c = ' ';
        else if (IsNewlineChar(c))
                c = 'n';
-       return font.width(c);
-}
-#else
-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)) {
-               return font.width(c);
-
-       } else if (IsHfillChar(c)) {
-               return 3;       /* Because of the representation
-                                * as vertical lines */
-
-       } 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 LyXParagraph::META_MARGIN:
-                       fs = "margin";
-                       break;
-               case LyXParagraph::META_FIG:
-                       fs = "fig";
-                       break;
-               case LyXParagraph::META_TAB:
-                       fs = "tab";
-                       break;
-               case LyXParagraph::META_ALGORITHM:
-                       fs = "alg";
-                       break;
-               case LyXParagraph::META_WIDE_FIG:
-                       fs = "wide-fig";
-                       break;
-               case LyXParagraph::META_WIDE_TAB:
-                       fs = "wide-tab";
-                       break;
-               case LyXParagraph::META_FOOTNOTE:
-                       fs = "foot";
-                       break;
-               }
-               font.decSize();
-               font.decSize();
-               return font.stringWidth(fs);
-       } 
-   
-       else if (c == LyXParagraph::META_INSET) {
-               Inset *tmpinset= par->GetInset(pos);
-               if (tmpinset)
-                       return par->GetInset(pos)->Width(font);
-               else
-                       return 0;
-
-       } else if (IsSeparatorChar(c))
-               c = ' ';
-       else if (IsNewlineChar(c))
-               c = 'n';
-       return font.width(c);
+       return lyxfont::width(c, font);
 }
-#endif
 
 
 // Returns the paragraph position of the last character in the specified row
@@ -201,60 +249,25 @@ LyXParagraph::size_type LyXText::RowLast(Row const * row) const
 }
 
 
-LyXDirection BufferParams::getDocumentDirection() const
-{
-       return (lyxrc->rtl_support && language == "hebrew")
-               ? LYX_DIR_RIGHT_TO_LEFT : LYX_DIR_LEFT_TO_RIGHT;
-}
-
-LyXDirection LyXParagraph::getParDirection() const
-{
-       if (!lyxrc->rtl_support || table)
-               return LYX_DIR_LEFT_TO_RIGHT;
-
-       if (size() > 0)
-               return (getFont(0).direction() ==  LyXFont::RTL_DIR)
-                       ? LYX_DIR_RIGHT_TO_LEFT : LYX_DIR_LEFT_TO_RIGHT;
-       else
-               return current_view->buffer()->params.getDocumentDirection();
-}
-
-LyXDirection LyXFont::getFontDirection() const
-{
-       if (lyxrc->rtl_support 
-           && direction() == LyXFont::RTL_DIR
-           && latex() != LyXFont::ON)
-               return LYX_DIR_RIGHT_TO_LEFT;
-       else
-               return LYX_DIR_LEFT_TO_RIGHT;
-}
-
-LyXDirection
-LyXParagraph::getLetterDirection(LyXParagraph::size_type pos) const
+LyXParagraph::size_type LyXText::RowLastPrintable(Row const * row) const
 {
-       if (!lyxrc->rtl_support)
-               return LYX_DIR_LEFT_TO_RIGHT;
-
-       LyXDirection direction = getFont(pos).getFontDirection();
-       if (IsLineSeparator(pos) && 0 < pos && pos < Last() - 1
-           && !IsLineSeparator(pos + 1)
-           && !(table && IsNewline(pos + 1))
-           && (getFont(pos - 1).getFontDirection() != direction
-               || getFont(pos + 1).getFontDirection() != direction))
-               return getParDirection();
+       LyXParagraph::size_type last = RowLast(row);
+       if (last >= row->pos && row->next && row->next->par == row->par &&
+           row->par->IsSeparator(last))
+               return last - 1;
        else
-               return direction;
+               return last;
 }
 
 
 void LyXText::ComputeBidiTables(Row * row) const
 {
-
-       if (!lyxrc->rtl_support) {
+       bidi_same_direction = true;
+       if (!lyxrc.rtl_support) {
                bidi_start = -1;
                return;
        }
-       LyXParagraph::size_type last = RowLast(row);
+       LyXParagraph::size_type last = RowLastPrintable(row);
        bidi_start = row->pos;
 
        if (bidi_start > last) {
@@ -269,90 +282,86 @@ void LyXText::ComputeBidiTables(Row * row) const
                        500 : 2 * (last + 2 - bidi_start);
                log2vis_list.resize(new_size);
                vis2log_list.resize(new_size);
+               bidi_levels.resize(new_size);
        }
 
        vis2log_list[last + 1 - bidi_start] = -1;
        log2vis_list[last + 1 - bidi_start] = -1;
 
+       LyXParagraph::size_type stack[2];
+       bool rtl_par = row->par->getParLanguage()->RightToLeft;
+       int level = 0;
+       bool rtl = false;
+       bool rtl0 = false;
        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);
-}
 
+       for (LyXParagraph::size_type lpos = bidi_start; lpos <= last; ++lpos) {
+               bool is_space = row->par->IsLineSeparator(lpos);
+               LyXParagraph::size_type pos =
+                       (is_space && lpos+1 <= last &&
+                        (!row->par->table || !row->par->IsNewline(lpos+1)) )
+                       ? lpos + 1 : lpos;
+               LyXFont font = row->par->GetFontSettings(pos);
+               bool new_rtl = font.isVisibleRightToLeft();
+               bool new_rtl0 = font.isRightToLeft();
+               int new_level;
+
+               if (row->par->table && row->par->IsNewline(lpos)) {
+                       new_level = 0;
+                       new_rtl = new_rtl0 = false;
+               } else if (lpos == main_body - 1 && row->pos < main_body - 1 &&
+                          row->par->IsLineSeparator(lpos)) {
+                       new_level = (rtl_par) ? 1 : 0;
+                       new_rtl = new_rtl0 = rtl_par;
+               } else if (new_rtl0)
+                       new_level = (new_rtl) ? 1 : 2;
+               else
+                       new_level = (rtl_par) ? 2 : 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;
+               if (is_space && new_level >= level) {
+                       new_level = level;
+                       new_rtl = rtl;
+                       new_rtl0 = rtl0;
+               }
 
-       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).direction() ==
-                            LyXFont::RTL_DIR
-                            && 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);
+               int new_level2 = new_level;
+
+               if (level == new_level && rtl0 != new_rtl0) {
+                       --new_level2;
+                       log2vis_list[lpos - bidi_start] = (rtl) ? 1 : -1;
+               } else if (level < new_level) {
+                       log2vis_list[lpos - bidi_start] =  (rtl) ? -1 : 1;
+                       if (new_level > rtl_par)
+                               bidi_same_direction = false;
+               } else
+                       log2vis_list[lpos - bidi_start] = (new_rtl) ? -1 : 1;
+               rtl = new_rtl;
+               rtl0 = new_rtl0;
+               bidi_levels[lpos - bidi_start] = new_level;
+
+               while (level > new_level2) {
+                       LyXParagraph::size_type old_lpos =
+                               stack[--level];
+                       int delta = lpos - old_lpos - 1;
+                       if (level % 2)
+                               delta = -delta;
+                       log2vis_list[lpos - bidi_start] += delta;
+                       log2vis_list[old_lpos - bidi_start] += delta;
                }
+               while (level < new_level)
+                       stack[level++] = lpos;
        }
 
        while (level > 0) {
-               old_lpos = stack[--level];
-               log2vis_list[old_lpos - bidi_start] =
-                       (old_lpos - (to + 1)) * direction; 
-               direction = static_cast<LyXDirection>(-direction);
+               LyXParagraph::size_type old_lpos = stack[--level];
+               int delta = last - old_lpos;
+               if (level % 2)
+                       delta = -delta;
+               log2vis_list[old_lpos - bidi_start] += delta;
        }
 
-       vpos = (par_direction == LYX_DIR_LEFT_TO_RIGHT)
-               ? from - 1 : to + 1;
-       vpos += offset;
-       for (lpos = from; lpos <= to; ++lpos) {
+       LyXParagraph::size_type vpos = bidi_start - 1;
+       for (LyXParagraph::size_type lpos = bidi_start; lpos <= last; ++lpos) {
                vpos += log2vis_list[lpos - bidi_start];
                vis2log_list[vpos - bidi_start] = lpos;
                log2vis_list[lpos - bidi_start] = vpos;
@@ -360,7 +369,6 @@ void LyXText::ComputeBidiTablesFromTo(Row * row,
 }
 
 
-#ifdef USE_PAINTER
 void LyXText::draw(Row const * row,
                   LyXParagraph::size_type & vpos,
                   int offset, float & x)
@@ -374,13 +382,12 @@ void LyXText::draw(Row const * row,
                ++vpos;
                // Draw end-of-line marker
                LyXFont font = GetFont(row->par, pos);
-               int wid = font.width('n');
-               int asc = font.maxAscent();
+               int wid = lyxfont::width('n', font);
+               int asc = lyxfont::maxAscent(font);
                int y = offset + row->baseline;
-#ifdef USE_PAINTER
                int xp[3], yp[3];
                
-               if (row->par->getLetterDirection(pos) == LYX_DIR_LEFT_TO_RIGHT) {
+               if (bidi_level(pos) % 2 == 0) {
                        xp[0] = int(x + wid * 0.375);
                        yp[0] = int(y - 0.875 * asc * 0.75);
                        
@@ -425,31 +432,6 @@ void LyXText::draw(Row const * row,
                        
                        pain.lines(xp, yp, 3, LColor::eolmarker);
                }
-#else
-               XPoint p[3];
-               
-               if (row->par->getLetterDirection(pos) == LYX_DIR_LEFT_TO_RIGHT) {
-                       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);
-               
-                       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);
-               } else {
-                       p[0].x = int(x + wid*0.625); p[0].y = int(y - 0.875*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*0.625); p[2].y = int(y - 0.125*asc*0.75);
-                       scr.drawLines(::getGC(gc_new_line), p, 3);
-               
-                       p[0].x = int(x + wid);       p[0].y = int(y - 0.500*asc*0.75);
-                       p[1].x = int(x);             p[1].y = int(y - 0.500*asc*0.75);
-                       p[2].x = int(x);             p[2].y = int(y - asc*0.75);
-                       scr.drawLines(::getGC(gc_new_line), p, 3);
-               }
-#endif
                x += wid;
                return;
        }
@@ -470,7 +452,7 @@ void LyXText::draw(Row const * row,
                        fs = "margin";
                        // Draw a sign at the left margin!
                        owner_->painter()
-                               .text((LYX_PAPER_MARGIN - font.width('!'))/2,
+                               .text((LYX_PAPER_MARGIN - lyxfont::width('!', font))/2,
                                      offset + row->baseline, "!", 1, font);
                        break;
                case LyXParagraph::META_FIG:
@@ -496,8 +478,8 @@ void LyXText::draw(Row const * row,
                font.decSize();
          
                // calculate the position of the footnotemark
-               int y = (row->baseline - font2.maxAscent(
-                        + font.maxAscent());
+               int y = (row->baseline - lyxfont::maxAscent(font2
+                        + lyxfont::maxAscent(font));
          
                font.setColor(LColor::footnote);
 
@@ -506,19 +488,19 @@ void LyXText::draw(Row const * row,
                // draw it and set new x position
                
                pain.text(int(x), offset + y, fs, font);
-               x += pain.width(fs, font);
+               x += lyxfont::width(fs, font);
                pain.line(int(tmpx), offset + row->baseline,
                          int(x), offset + row->baseline,
                          LColor::footnote);
 
-         
                ++vpos;
                return;
        } else if (c == LyXParagraph::META_INSET) {
                Inset * tmpinset = row->par->GetInset(pos);
-               if (tmpinset) 
+               if (tmpinset) {
                        tmpinset->draw(owner_->painter(), font,
                                       offset + row->baseline, x);
+               }
                ++vpos;
                return;
        }
@@ -536,37 +518,31 @@ void LyXText::draw(Row const * row,
        // 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 =
+               font2.language()->lang == "arabic" &&
+               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);
+       LyXParagraph::size_type last = RowLastPrintable(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;
        }
        float tmpx = x;
 
-#if 0
-       // If monochrome and LaTeX mode, provide reverse background
-       if (mono_video &&
-           font.latex() == LyXFont::ON) {
-               int a = font.maxAscent();
-               int d = font.maxDescent();
-               scr.fillRectangle(gc_copy, int(tmpx),
-                                 offset + row->baseline - a,
-                                 font.textWidth(textstring.c_str(),
-                                                textstring.length()), a + d);
-       }
-#endif
-
        // Draw text and set the new x position
        pain.text(int(x), offset + row->baseline, textstring, font);
-       x += pain.width(textstring, font);
+       x += lyxfont::width(textstring, font);
        
        // what about underbars?
        if (font.underbar() == LyXFont::ON && font.latex() != LyXFont::ON) {
@@ -579,170 +555,6 @@ void LyXText::draw(Row const * row,
        // routines should go here. (Asger)
        // Why shouldn't LyXFont::drawText handle it internally?
 }
-#else
-void LyXText::Draw(Row const * row, LyXParagraph::size_type & vpos,
-                  LyXScreen & scr, int offset, float & x)
-{
-       LyXParagraph::size_type pos = vis2log(vpos);
-       char c = row->par->GetChar(pos);
-
-       if (IsNewlineChar(c)) {
-               ++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];
-               if (row->par->getLetterDirection(pos) == LYX_DIR_LEFT_TO_RIGHT) {
-                       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);
-               
-                       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);
-               } else {
-                       p[0].x = int(x + wid*0.625); p[0].y = int(y - 0.875*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*0.625); p[2].y = int(y - 0.125*asc*0.75);
-                       scr.drawLines(::getGC(gc_new_line), p, 3);
-               
-                       p[0].x = int(x + wid);       p[0].y = int(y - 0.500*asc*0.75);
-                       p[1].x = int(x);             p[1].y = int(y - 0.500*asc*0.75);
-                       p[2].x = int(x);             p[2].y = int(y - asc*0.75);
-                       scr.drawLines(::getGC(gc_new_line), p, 3);
-               }
-               x += wid;
-               return;
-       }
-
-       LyXFont font = GetFont(row->par, pos);
-       LyXFont font2 = font;
-
-       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 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);
-                       break;
-               case LyXParagraph::META_FIG:
-                       fs = "fig";
-                       break;
-               case LyXParagraph::META_TAB:
-                       fs = "tab";
-                       break;
-               case LyXParagraph::META_ALGORITHM:
-                       fs = "alg";
-                       break;
-               case LyXParagraph::META_WIDE_FIG:
-                       fs = "wide-fig";
-                       break;
-               case LyXParagraph::META_WIDE_TAB:
-                       fs = "wide-tab";
-                       break;
-               case LyXParagraph::META_FOOTNOTE:
-                       fs = "foot";
-                       break;
-               }
-               font.decSize();
-               font.decSize();
-         
-               // calculate the position of the footnotemark
-               int y = (row->baseline - font2.maxAscent() 
-                        + font.maxAscent());
-
-#ifdef USE_PAINTER
-               font.setColor(LColor::footnote);
-#else
-               font.setColor(LyXFont::RED);
-#endif
-
-               float tmpx = x;
-
-               // draw it and set new x position
-               x += scr.drawString(font, fs, offset + y, int(x));
-
-               scr.drawLine(gc_foot, offset + row->baseline,
-                            int(tmpx), int(x - tmpx));
-         
-               ++vpos;
-               return;
-       } else if (c == LyXParagraph::META_INSET) {
-               Inset * tmpinset = row->par->GetInset(pos);
-               if (tmpinset) 
-                       tmpinset->Draw(font, scr, offset + row->baseline, x);
-               ++vpos;
-               return;
-       }
-
-       /* usual characters, no insets */
-
-       // Collect character that we can draw in one command
-
-       // 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)
-       // 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...
-       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)) {
-               textstring += c;
-               ++vpos;
-       }
-       float tmpx = x;
-
-       // If monochrome and LaTeX mode, provide reverse background
-       if (mono_video &&
-           font.latex() == LyXFont::ON) {
-               int a = font.maxAscent();
-               int d = font.maxDescent();
-               scr.fillRectangle(gc_copy, int(tmpx),
-                                 offset + row->baseline - a,
-                                 font.textWidth(textstring.c_str(),
-                                                textstring.length()), a + d);
-       }
-
-       // Draw text and set the new x position
-       x += scr.drawText(font, textstring.c_str(), textstring.length(),
-                         offset + row->baseline, 
-                         int(x));
-       
-       // 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));
-       }
-
-       // If we want ulem.sty support, drawing
-       // routines should go here. (Asger)
-       // Why shouldn't LyXFont::drawText handle it internally?
-}
-#endif
 
 
 // Returns the left beginning of the text. 
@@ -751,28 +563,31 @@ void LyXText::Draw(Row const * row, LyXParagraph::size_type & vpos,
 // exactly the label-width.
 int LyXText::LeftMargin(Row const * row) const
 {
-       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
-                                                      row->par->GetLayout());
+       LyXLayout const & layout =
+               textclasslist.Style(buffer->params.textclass,
+                                   row->par->GetLayout());
        
        string parindent = layout.parindent; 
        
        /* table stuff -- begin */ 
        if (row->par->table)
-               parindent.clear();
+               parindent.erase();
        /* table stuff -- end */
        
        int x = LYX_PAPER_MARGIN;
        
-       x += textclasslist.TextClass(parameters->textclass)
-               .defaultfont()
-               .signedStringWidth(textclasslist
-                                  .TextClass(parameters->textclass)
-                                  .leftmargin());
+       x += lyxfont::signedWidth(textclasslist
+                                 .TextClass(buffer->params.textclass)
+                                 .leftmargin(),
+                                 textclasslist
+                                 .TextClass(buffer->params.textclass)
+                                 .defaultfont());
        
        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;
+               x += lyxfont::width("Mwide-figM", font)
+                       + LYX_PAPER_MARGIN/2;
        }
        
        // this is the way, LyX handles the LaTeX-Environments.
@@ -785,10 +600,10 @@ int LyXText::LeftMargin(Row const * row) const
                                LyXParagraph * newpar = row->par
                                        ->DepthHook(row->par->GetDepth());
                                if (newpar &&
-                                   textclasslist.Style(parameters->textclass,
+                                   textclasslist.Style(buffer->params.textclass,
                                                        newpar->GetLayout())
                                    .nextnoindent)
-                                       parindent.clear();
+                                       parindent.erase();
                        }
                }
        } else {
@@ -801,7 +616,7 @@ int LyXText::LeftMargin(Row const * row) const
                // check wether it is a sufficent paragraph 
                if (newpar && newpar->footnoteflag == row->par->footnoteflag
                    && textclasslist
-                       .Style(parameters->textclass, 
+                       .Style(buffer->params.textclass, 
                               newpar->GetLayout()).isEnvironment()) {
                        Row dummyrow;
                        dummyrow.par = newpar;
@@ -817,10 +632,10 @@ int LyXText::LeftMargin(Row const * row) const
                
                if (newpar && !row->par->GetLayout()) {
                        if (newpar->FirstPhysicalPar()->noindent)
-                               parindent.clear();
+                               parindent.erase();
                        else
                                parindent = textclasslist
-                                       .Style(parameters->textclass, 
+                                       .Style(buffer->params.textclass, 
                                               newpar->GetLayout()).parindent;
                }
                
@@ -830,41 +645,39 @@ int LyXText::LeftMargin(Row const * row) const
        switch (layout.margintype) {
        case MARGIN_DYNAMIC:
                if (!layout.leftmargin.empty()) {
-                       x += textclasslist
-                               .TextClass(parameters->textclass)
-                               .defaultfont()
-                               .signedStringWidth(layout.leftmargin);
+                       x += lyxfont::signedWidth(layout.leftmargin,
+                                                 textclasslist
+                                                 .TextClass(buffer->params.
+                                                            textclass)
+                                                 .defaultfont());
                }
-               if (!row->par->GetLabestring().empty()) {
-                       x += labelfont.signedStringWidth(layout.labelindent);
-                       x += labelfont.stringWidth(row->par->GetLabestring());
-                       x += labelfont.stringWidth(layout.labelsep);
+               if (!row->par->GetLabelstring().empty()) {
+                       x += lyxfont::signedWidth(layout.labelindent,
+                                                 labelfont);
+                       x += lyxfont::width(row->par->GetLabelstring(), labelfont);
+                       x += lyxfont::width(layout.labelsep, labelfont);
                }
                break;
        case MARGIN_MANUAL:
-               x += labelfont.signedStringWidth(layout.labelindent);
+               x += lyxfont::signedWidth(layout.labelindent, labelfont);
                if (row->pos >= BeginningOfMainBody(row->par)) {
                        if (!row->par->GetLabelWidthString().empty()) {
-                               x += labelfont
-                                       .stringWidth(row->par
-                                                    ->GetLabelWidthString());
-                               x += labelfont.stringWidth(layout.labelsep);
+                               x += lyxfont::width(row->par->GetLabelWidthString(),
+                                              labelfont);
+                               x += lyxfont::width(layout.labelsep, labelfont);
                        }
                }
                break;
        case MARGIN_STATIC:
-               x += textclasslist.TextClass(parameters->textclass)
-                       .defaultfont().signedStringWidth(layout.leftmargin) * 4
+               x += lyxfont::signedWidth(layout.leftmargin, textclasslist.TextClass(buffer->params.textclass).defaultfont()) * 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);
+                               x += lyxfont::signedWidth(layout.leftmargin, labelfont);
                        } else {
-                               x += labelfont
-                                       .signedStringWidth(layout.labelindent);
+                               x += lyxfont::signedWidth(layout.labelindent, labelfont);
                        }
                } else if (row->pos
                           // Special case to fix problems with
@@ -872,14 +685,15 @@ int LyXText::LeftMargin(Row const * row) const
                           || (layout.labeltype == LABEL_STATIC
                               && layout.latextype == LATEX_ENVIRONMENT
                               && ! row->par->IsFirstInSequence())) {
-                       x += labelfont.signedStringWidth(layout.leftmargin);
+                       x += lyxfont::signedWidth(layout.leftmargin, labelfont);
                } 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());
+                       x += lyxfont::signedWidth(layout.labelindent,
+                                                 labelfont);
+                       x += lyxfont::width(layout.labelsep, labelfont);
+                       x += lyxfont::width(row->par->GetLabelstring(), labelfont);
                } 
                break;
                
@@ -901,8 +715,10 @@ int LyXText::LeftMargin(Row const * row) const
                                minfill = tmprow->fill;
                }
                
-               x += textclasslist.TextClass(parameters->textclass)
-                       .defaultfont().signedStringWidth(layout.leftmargin);
+               x += lyxfont::signedWidth(layout.leftmargin,
+                                         textclasslist
+                                         .TextClass(buffer->params.textclass)
+                                         .defaultfont());
                x += minfill;
        }
        break;
@@ -912,18 +728,18 @@ int LyXText::LeftMargin(Row const * row) const
                        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();
+                       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");
+                       x += lyxfont::width("XXXXXX", font);
                }
        }
        
-       int align;
+       int align; // wrong type
        if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT)
                align = layout.align;
        else
@@ -941,45 +757,39 @@ int LyXText::LeftMargin(Row const * row) const
                    && align == LYX_ALIGN_BLOCK
                    && !row->par->noindent
                    && (row->par->layout ||
-                       parameters->paragraph_separation ==
+                       buffer->params.paragraph_separation ==
                        BufferParams::PARSEP_INDENT))
-                       x += textclasslist.TextClass(parameters->textclass)
-                               .defaultfont().signedStringWidth(parindent);
-               else 
-                       if (layout.labeltype == LABEL_BIBLIO) {
-                               // ale970405 Right width for bibitems
-#ifdef USE_PAINTER
-                               x += bibitemMaxWidth(owner_->painter(),
-                                                    textclasslist
-                                                    .TextClass(parameters
-                                                               ->textclass)
-                                                    .defaultfont());
-#else
-                               x += bibitemMaxWidth(textclasslist
-                                                    .TextClass(parameters
-                                                               ->textclass)
-                                                    .defaultfont());
-#endif
-                       }
+                       x += lyxfont::signedWidth(parindent,
+                                                 textclasslist
+                                                 .TextClass(buffer->params
+                                                            .textclass)
+                                                 .defaultfont());
+               else if (layout.labeltype == LABEL_BIBLIO) {
+                       // ale970405 Right width for bibitems
+                       x += bibitemMaxWidth(owner_->painter(),
+                                            textclasslist
+                                            .TextClass(buffer->params
+                                                       .textclass)
+                                            .defaultfont());
+               }
        }
-       
        return x;
 }
-    
-   
+
+
 int LyXText::RightMargin(Row const * row) const
 {
        LyXLayout const & layout =
-               textclasslist.Style(parameters->textclass,
+               textclasslist.Style(buffer->params.textclass,
                                    row->par->GetLayout());
        
        int x = LYX_PAPER_MARGIN
-               + textclasslist
-               .TextClass(parameters->textclass)
-               .defaultfont()
-               .signedStringWidth(textclasslist
-                                  .TextClass(parameters->textclass)
-                                  .rightmargin());
+               + lyxfont::signedWidth(textclasslist
+                                      .TextClass(buffer->params.textclass)
+                                      .rightmargin(),
+                                      textclasslist
+                                      .TextClass(buffer->params.textclass)
+                                      .defaultfont());
        
        if (row->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)  {
                x += LYX_PAPER_MARGIN / 2;
@@ -1004,7 +814,7 @@ int LyXText::RightMargin(Row const * row) const
                
                // check wether it is a sufficent paragraph
                if (newpar && newpar->footnoteflag == row->par->footnoteflag
-                   && textclasslist.Style(parameters->textclass,
+                   && textclasslist.Style(buffer->params.textclass,
                                           newpar->GetLayout())
                       .isEnvironment()) {
                        Row dummyrow;
@@ -1021,9 +831,7 @@ int LyXText::RightMargin(Row const * row) const
        }
        
        //lyxerr << "rightmargin: " << layout->rightmargin << endl;
-       x += textclasslist.TextClass(parameters->textclass)
-               .defaultfont()
-               .signedStringWidth(layout.rightmargin) * 4
+       x += lyxfont::signedWidth(layout.rightmargin, textclasslist.TextClass(buffer->params.textclass).defaultfont()) * 4
              / (row->par->GetDepth() + 4);
        return x;
 }
@@ -1031,7 +839,7 @@ int LyXText::RightMargin(Row const * row) const
 
 int LyXText::LabelEnd (Row const * row) const
 {
-       if (textclasslist.Style(parameters->textclass,
+       if (textclasslist.Style(buffer->params.textclass,
                                row->par->GetLayout()).margintype
            == MARGIN_MANUAL) {
                Row tmprow;
@@ -1122,12 +930,11 @@ LyXText::NextBreakPoint(Row const * row, int width) const
        // position of the last possible breakpoint 
        // -1 isn't a suitable value, but a flag
        LyXParagraph::size_type last_separator = -1;
-       int left_margin = LabelEnd(row);
        width -= RightMargin(row);
        
        LyXParagraph::size_type main_body = BeginningOfMainBody(par);
        LyXLayout const & layout =
-               textclasslist.Style(parameters->textclass, par->GetLayout());
+               textclasslist.Style(buffer->params.textclass, par->GetLayout());
        LyXParagraph::size_type i = pos;
 
        if (layout.margintype == MARGIN_RIGHT_ADDRESS_BOX) {
@@ -1185,9 +992,11 @@ LyXText::NextBreakPoint(Row const * row, int width) const
                        }
                        ++i;
                        if (i == main_body) {
-                               x += GetFont(par, -2).stringWidth(layout.labelsep);
+                               x += lyxfont::width(layout.labelsep,
+                                                   GetFont(par, -2));
                                if (par->IsLineSeparator(i - 1))
                                        x-= SingleWidth(par, i - 1);
+                               int left_margin = LabelEnd(row);
                                if (x < left_margin)
                                        x = left_margin;
                        }
@@ -1216,7 +1025,7 @@ int LyXText::Fill(Row const * row, int paper_width) const
 {
        int w, fill;
        // get the pure distance
-       LyXParagraph::size_type last = RowLast(row);
+       LyXParagraph::size_type last = RowLastPrintable(row);
        /* table stuff -- begin */
        if (row->par->table) {
                // for tables FILL does calculate the widthes of each cell in 
@@ -1241,19 +1050,9 @@ int LyXText::Fill(Row const * row, int paper_width) const
                           * this point. */ 
        }
        /* table stuff -- end*/ 
-       
-       int 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 (textclasslist.Style(parameters->textclass,
+       if (textclasslist.Style(buffer->params.textclass,
                                row->par->GetLayout()).margintype
            == MARGIN_RIGHT_ADDRESS_BOX) {
                int tmpfill = row->fill;
@@ -1263,7 +1062,7 @@ int LyXText::Fill(Row const * row, int paper_width) const
        } else
                w = LeftMargin(row);
        
-       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+       LyXLayout const & layout = textclasslist.Style(buffer->params.textclass,
                                                       row->par->GetLayout());
        LyXParagraph::size_type main_body = 
                BeginningOfMainBody(row->par);
@@ -1271,10 +1070,10 @@ int LyXText::Fill(Row const * row, int paper_width) const
 
        while (i <= last) {
                if (main_body > 0 && i == main_body) {
-                       w += GetFont(row->par, -2).
-                               stringWidth(layout.labelsep);
+                       w += lyxfont::width(layout.labelsep, GetFont(row->par, -2));
                        if (row->par->IsLineSeparator(i - 1))
                                w -= SingleWidth(row->par, i - 1);
+                       int left_margin = LabelEnd(row);
                        if (w < left_margin)
                                w = left_margin;
                }
@@ -1282,9 +1081,10 @@ int LyXText::Fill(Row const * row, int paper_width) const
                ++i;
        }
        if (main_body > 0 && main_body > last) {
-               w += GetFont(row->par, -2).stringWidth(layout.labelsep);
+               w += lyxfont::width(layout.labelsep, GetFont(row->par, -2));
                if (last >= 0 && row->par->IsLineSeparator(last))
                        w -= SingleWidth(row->par, last);
+               int left_margin = LabelEnd(row);
                if (w < left_margin)
                        w = left_margin;
        }
@@ -1321,13 +1121,11 @@ int LyXText::LabelFill(Row const * row) const
        
        int fill = 0;
        if (!row->par->labelwidthstring.empty()) {
-               fill = GetFont(row->par, -2)
-                       .stringWidth(row->par->labelwidthstring) - w;
+               fill = max(lyxfont::width(row->par->labelwidthstring,
+                                         GetFont(row->par, -2)) - w,
+                          0);
        }
        
-       if (fill < 0)
-               fill = 0;
-       
        return fill;
 }
 
@@ -1337,11 +1135,6 @@ int LyXText::LabelFill(Row const * row) const
 int LyXText::NumberOfSeparators(Row const * row) const
 {
        int last = RowLast(row);
-       //int p = row->pos;
-       //int main_body = BeginningOfMainBody(row->par);
-       //if (p < main_body)
-       //      p = main_body;
-       // I think this is equivalent to the above. (Lgb)
        int p = max(row->pos, BeginningOfMainBody(row->par));
        int n = 0;
        for (; p < last; ++p) {
@@ -1366,10 +1159,6 @@ int LyXText::NumberOfHfills(Row const * row) const
                        ++first;
        }
 
-       //int main_body = BeginningOfMainBody(row->par);
-       //if (first < main_body)
-       //      first = main_body;
-       // I think this is equivalent to the above. (Lgb)
        first = max(first, BeginningOfMainBody(row->par));
        int n = 0;
        for (int p = first; p <= last; ++p) { // last, because the end is ignored!
@@ -1391,11 +1180,7 @@ int LyXText::NumberOfLabelHfills(Row const * row) const
                while(first < last && row->par->IsHfill(first))
                        ++first;
        }
-       //LyXParagraph::size_type main_body = 
-       //BeginningOfMainBody(row->par);
-       //if (last > main_body)
-       //last = main_body;
-       // I think this is eqvialent to the above. (Lgb)
+
        last = min(last, BeginningOfMainBody(row->par));
        int n = 0;
        for (LyXParagraph::size_type p = first;
@@ -1427,7 +1212,7 @@ bool LyXText::HfillExpansion(Row const * row_ptr,
                return true;
        
        // in some labels  it does not count
-       if (textclasslist.Style(parameters->textclass,
+       if (textclasslist.Style(buffer->params.textclass,
                                row_ptr->par->GetLayout()).margintype
            != MARGIN_MANUAL
            && pos < BeginningOfMainBody(row_ptr->par))
@@ -1445,7 +1230,6 @@ bool LyXText::HfillExpansion(Row const * row_ptr,
 }
 
 
-#ifdef USE_PAINTER
 void LyXText::SetHeightOfRow(Row * row_ptr) const
 {
     /* get the maximum ascent and the maximum descent */
@@ -1472,22 +1256,30 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
    LyXParagraph * par = row_ptr->par->LastPhysicalPar();
    LyXParagraph * firstpar = row_ptr->par->FirstPhysicalPar();
    
-   LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+   LyXLayout const & layout = textclasslist.Style(buffer->params.textclass,
                                                  firstpar->GetLayout());
    
-   LyXFont font = GetFont(par, par->Last()-1);
+   LyXFont font = GetFont(par, par->Last() - 1);
    LyXFont::FONT_SIZE size = font.size();
    font = GetFont(par, -1);
    font.setSize(size);
 
    LyXFont labelfont = GetFont(par, -2);
 
-   int maxasc = int(font.maxAscent() *
-                  layout.spacing.getValue() *
-                  parameters->spacing.getValue());
-   int maxdesc = int(font.maxDescent() *
+   float spacing_val = 1.0;
+   if (!row_ptr->par->spacing.isDefault()) {
+          spacing_val = row_ptr->par->spacing.getValue();
+   } else {
+          spacing_val = buffer->params.spacing.getValue();
+   }
+   //lyxerr << "spacing_val = " << spacing_val << endl;
+   
+   int maxasc = int(lyxfont::maxAscent(font) *
+                  layout.spacing.getValue() *
+                  spacing_val);
+   int maxdesc = int(lyxfont::maxDescent(font) *
                    layout.spacing.getValue() *
-                   parameters->spacing.getValue());
+                   spacing_val);
 
    int pos_end = RowLast(row_ptr);
    
@@ -1517,8 +1309,8 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
    if (maxsize > font.size()) {
        font.setSize(maxsize);
 
-       asc = font.maxAscent();
-       desc = font.maxDescent();
+       asc = lyxfont::maxAscent(font);
+       desc = lyxfont::maxDescent(font);
        if (asc > maxasc) 
                maxasc = asc;
        if (desc > maxdesc)
@@ -1544,17 +1336,17 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
        && row_ptr->par == firstpar) {
       
       /* some parksips VERY EASY IMPLEMENTATION */ 
-      if (parameters->paragraph_separation == BufferParams::PARSEP_SKIP) {
+      if (buffer->params.paragraph_separation == BufferParams::PARSEP_SKIP) {
         if (layout.isParagraph()
             && firstpar->GetDepth() == 0
             && firstpar->Previous())
-           maxasc += parameters->getDefSkip().inPixels();
+           maxasc += buffer->params.getDefSkip().inPixels(owner_);
         else if (firstpar->Previous()
-                 && textclasslist.Style(parameters->textclass,
+                 && textclasslist.Style(buffer->params.textclass,
                           firstpar->Previous()->GetLayout()).isParagraph()
                  && firstpar->Previous()->GetDepth() == 0)
           // is it right to use defskip here too? (AS)
-          maxasc += parameters->getDefSkip().inPixels();
+          maxasc += buffer->params.getDefSkip().inPixels(owner_);
       }
       
       /* the paper margins */ 
@@ -1563,12 +1355,12 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
       
       /* 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 */
       if (firstpar->line_top)
-        maxasc += 2 * GetFont(firstpar, 0).ascent('x');
+        maxasc += 2 * lyxfont::ascent('x', GetFont(firstpar, 0));
       
       /* and now the pagebreaks */ 
       if (firstpar->pagebreak_top)
@@ -1577,13 +1369,20 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
       /*  this is special code for the chapter, since the label of this
        * layout is printed in an extra row */ 
       if (layout.labeltype == LABEL_COUNTER_CHAPTER
-         && parameters->secnumdepth>= 0) {
-             labeladdon = int(labelfont.maxDescent() *
-                                 layout.spacing.getValue() *
-                                 parameters->spacing.getValue())
-                     + int(labelfont.maxAscent() *
+         && buffer->params.secnumdepth >= 0) {
+             float spacing_val = 1.0;
+             if (!row_ptr->par->spacing.isDefault()) {
+                     spacing_val = row_ptr->par->spacing.getValue();
+             } else {
+                     spacing_val = buffer->params.spacing.getValue();
+             }
+             
+             labeladdon = int(lyxfont::maxDescent(labelfont) *
                               layout.spacing.getValue() *
-                              parameters->spacing.getValue());
+                              spacing_val)
+                     + int(lyxfont::maxAscent(labelfont) *
+                           layout.spacing.getValue() *
+                           spacing_val);
       }
       
       /* special code for the top label */ 
@@ -1591,16 +1390,23 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
           || 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() *
-                 parameters->spacing.getValue())
-                +(labelfont.maxDescent() *
-                  layout.spacing.getValue() *
-                  parameters->spacing.getValue())
-                + layout.topsep * DefaultHeight()
-                + layout.labelbottomsep *  DefaultHeight());
+         && !row_ptr->par->GetLabelstring().empty()) {
+             float spacing_val = 1.0;
+             if (!row_ptr->par->spacing.isDefault()) {
+                     spacing_val = row_ptr->par->spacing.getValue();
+             } else {
+                     spacing_val = buffer->params.spacing.getValue();
+             }
+             
+             labeladdon = int(
+                     (lyxfont::maxAscent(labelfont) *
+                      layout.spacing.getValue() *
+                      spacing_val)
+                     +(lyxfont::maxDescent(labelfont) *
+                       layout.spacing.getValue() *
+                       spacing_val)
+                     + layout.topsep * DefaultHeight()
+                     + layout.labelbottomsep *  DefaultHeight());
       }
    
       /* and now the layout spaces, for example before and after a section, 
@@ -1620,7 +1426,7 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
            tmptop = layout.topsep;
            
            if (row_ptr->previous->par->GetDepth() >= row_ptr->par->GetDepth())
-              tmptop-= textclasslist.Style(parameters->textclass, row_ptr->previous->par->GetLayout()).bottomsep;
+              tmptop-= textclasslist.Style(buffer->params.textclass, row_ptr->previous->par->GetLayout()).bottomsep;
            
            if (tmptop > 0)
               layoutasc = (tmptop * DefaultHeight());
@@ -1634,7 +1440,7 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
         
         prev = row_ptr->par->DepthHook(row_ptr->par->GetDepth()-1);
         if (prev)  {
-           maxasc += int(textclasslist.Style(parameters->textclass,
+           maxasc += int(textclasslist.Style(buffer->params.textclass,
                                         prev->GetLayout()).parsep * DefaultHeight());
         }
         else {
@@ -1660,12 +1466,12 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
        
          /* 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 */
          if (firstpar->line_bottom)
-           maxdesc += 2 * (GetFont(par, par->Last()-1).ascent('x'));
+           maxdesc += 2 * lyxfont::ascent('x', GetFont(par, par->Last() - 1));
          
          /* and now the pagebreaks */
          if (firstpar->pagebreak_bottom)
@@ -1680,12 +1486,12 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
             float  unusual = 0;
             
             if (comparepar->GetDepth() > nextpar->GetDepth()) {
-               usual = (textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
+               usual = (textclasslist.Style(buffer->params.textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
                comparepar = comparepar->DepthHook(nextpar->GetDepth());
                if (comparepar->GetLayout()!= nextpar->GetLayout()
                    || nextpar->GetLabelWidthString() != 
                        comparepar->GetLabelWidthString())
-                 unusual = (textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
+                 unusual = (textclasslist.Style(buffer->params.textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
                
                if (unusual > usual)
                  layoutdesc = unusual;
@@ -1697,7 +1503,7 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
                if (comparepar->GetLayout()!= nextpar->GetLayout()
                    || nextpar->GetLabelWidthString() != 
                        comparepar->GetLabelWidthString())
-                 layoutdesc = int(textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
+                 layoutdesc = int(textclasslist.Style(buffer->params.textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
             }
          }
        }
@@ -1721,282 +1527,6 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
    
    height += row_ptr->height;
 }
-#else
-void LyXText::SetHeightOfRow(Row * row_ptr) const
-{
-    /* get the maximum ascent and the maximum descent */
-   int asc, maxasc, desc, maxdesc, pos_end, pos, labeladdon;
-   float layoutasc = 0;
-   float layoutdesc = 0;
-   float tmptop = 0;
-   LyXFont tmpfont;
-   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 */
-   long unused_y;
-   GetRow(row_ptr->par, row_ptr->pos, unused_y);
-
-   /* ok , let us initialize the maxasc and maxdesc value. 
-    * This depends in LaTeX of the font of the last character
-    * in the paragraph. The hack below is necessary because
-    * of the possibility of open footnotes */
-
-   /* Correction: only the fontsize count. The other properties
-      are taken from the layoutfont. Nicer on the screen :) */
-   
-   LyXParagraph * par = row_ptr->par->LastPhysicalPar();
-   LyXParagraph * firstpar = row_ptr->par->FirstPhysicalPar();
-   
-   LyXLayout const & layout = textclasslist.Style(parameters->textclass, firstpar->GetLayout());
-   
-   LyXFont font = GetFont(par, par->Last()-1);
-   LyXFont::FONT_SIZE size = font.size();
-   font = GetFont(par, -1);
-   font.setSize(size);
-
-   LyXFont labelfont = GetFont(par, -2);
-
-   maxasc = int(font.maxAscent() *
-                  layout.spacing.getValue() *
-                  parameters->spacing.getValue());
-   maxdesc = int(font.maxDescent() *
-                   layout.spacing.getValue() *
-                   parameters->spacing.getValue());
-
-   pos_end = RowLast(row_ptr);
-   
-   labeladdon = 0;
-
-   // Check if any insets are larger
-   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);
-           if (asc > maxasc) 
-             maxasc = asc;
-           if (desc > maxdesc)
-             maxdesc = desc;
-        }
-      }
-   }
-
-   // 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);
-   if (maxsize > font.size()) {
-       font.setSize(maxsize);
-
-       asc = font.maxAscent();
-       desc = font.maxDescent();
-       if (asc > maxasc) 
-               maxasc = asc;
-       if (desc > maxdesc)
-               maxdesc = desc;
-   }
-
-   /* table stuff -- begin*/
-   if (row_ptr->par->table){
-     // stretch the rows a bit
-      maxasc += 1;
-      maxdesc += 1;
-   }
-   /* table stuff -- end*/
-
-   // This is nicer with box insets:
-   ++maxasc;
-   ++maxdesc;
-
-   row_ptr->ascent_of_text = maxasc;
-   
-   /* is it a top line? */ 
-   if (row_ptr->pos == 0
-       && row_ptr->par == firstpar) {
-      
-      /* some parksips VERY EASY IMPLEMENTATION */ 
-      if (parameters->paragraph_separation == BufferParams::PARSEP_SKIP) {
-        if (layout.isParagraph()
-            && firstpar->GetDepth() == 0
-            && firstpar->Previous())
-           maxasc += parameters->getDefSkip().inPixels();
-        else if (firstpar->Previous()
-                 && 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();
-      }
-      
-      /* the paper margins */ 
-      if (!row_ptr->par->previous)
-        maxasc += LYX_PAPER_MARGIN;
-      
-      /* add the vertical spaces, that the user added */
-      if (firstpar->added_space_top.kind() != VSpace::NONE)
-        maxasc += int(firstpar->added_space_top.inPixels());
-      
-      /* do not forget the DTP-lines! 
-       * there height depends on the font of the nearest character */
-      if (firstpar->line_top)
-        maxasc += 2 * GetFont(firstpar, 0).ascent('x');
-      
-      /* and now the pagebreaks */ 
-      if (firstpar->pagebreak_top)
-        maxasc += 3 * DefaultHeight();
-      
-      /*  this is special code for the chapter, since the label of this
-       * layout is printed in an extra row */ 
-      if (layout.labeltype == LABEL_COUNTER_CHAPTER
-         && parameters->secnumdepth>= 0) {
-             labeladdon = int(labelfont.maxDescent() *
-                                 layout.spacing.getValue() *
-                                 parameters->spacing.getValue())
-                     + int(labelfont.maxAscent() *
-                              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)
-         && row_ptr->par->IsFirstInSequence()
-         && !row_ptr->par->GetLabestring().empty()) {
-        labeladdon = int(
-                (labelfont.maxAscent() *
-                 layout.spacing.getValue() *
-                 parameters->spacing.getValue())
-                +(labelfont.maxDescent() *
-                  layout.spacing.getValue() *
-                  parameters->spacing.getValue())
-                + 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();
-        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());
-          }
-        else if (row_ptr->previous) {
-           tmptop = layout.topsep;
-           
-           if (row_ptr->previous->par->GetDepth() >= row_ptr->par->GetDepth())
-              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;
-           
-           if (tmptop > 0)
-              layoutasc = (tmptop * DefaultHeight());
-        }
-        
-        prev = row_ptr->par->DepthHook(row_ptr->par->GetDepth()-1);
-        if (prev)  {
-           maxasc += int(textclasslist.Style(parameters->textclass,
-                                        prev->GetLayout()).parsep * DefaultHeight());
-        }
-        else {
-               if (firstpar->Previous()
-                   && firstpar->Previous()->GetDepth() == 0
-                   && firstpar->Previous()->GetLayout() != firstpar->GetLayout()) {
-                  /* avoid parsep */ 
-               }
-           else if (firstpar->Previous()){
-              maxasc += int(layout.parsep * DefaultHeight());
-           }
-        }
-      }
-   }
-   
-   /* is it a bottom line? */ 
-   if (row_ptr->par->ParFromPos(RowLast(row_ptr) + 1) == par
-       && (!row_ptr->next || row_ptr->next->par != row_ptr->par)) {     
-         
-         /* the paper margins */ 
-         if (!par->next)
-           maxdesc += LYX_PAPER_MARGIN;
-       
-         /* add the vertical spaces, that the user added */
-         if (firstpar->added_space_bottom.kind() != VSpace::NONE)
-           maxdesc += int(firstpar->added_space_bottom.inPixels());
-         
-         /* do not forget the DTP-lines! 
-          * there height depends on the font of the nearest character */
-         if (firstpar->line_bottom)
-           maxdesc += 2 * (GetFont(par, par->Last()-1).ascent('x'));
-         
-         /* and now the pagebreaks */
-         if (firstpar->pagebreak_bottom)
-           maxdesc += 3 * 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_bottom && row_ptr->par->Next()) {
-            LyXParagraph *nextpar = row_ptr->par->Next();
-            LyXParagraph *comparepar = row_ptr->par;
-            float usual = 0;
-            float  unusual = 0;
-            
-            if (comparepar->GetDepth() > nextpar->GetDepth()) {
-               usual = (textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
-               comparepar = comparepar->DepthHook(nextpar->GetDepth());
-               if (comparepar->GetLayout()!= nextpar->GetLayout()
-                   || nextpar->GetLabelWidthString() != 
-                       comparepar->GetLabelWidthString())
-                 unusual = (textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
-               
-               if (unusual > usual)
-                 layoutdesc = unusual;
-               else
-                 layoutdesc = usual;
-            }
-            else if (comparepar->GetDepth() ==  nextpar->GetDepth()) {
-               
-               if (comparepar->GetLayout()!= nextpar->GetLayout()
-                   || nextpar->GetLabelWidthString() != 
-                       comparepar->GetLabelWidthString())
-                 layoutdesc = int(textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
-            }
-         }
-       }
-   
-   /* incalculate the layout spaces */ 
-   maxasc += int(layoutasc * 2 / (2 + firstpar->GetDepth()));
-   maxdesc += int(layoutdesc * 2 / (2 + firstpar->GetDepth()));
-
-   /* table stuff -- begin*/
-   if (row_ptr->par->table){
-      maxasc += row_ptr->par->table->
-       AdditionalHeight(NumberOfCell(row_ptr->par, row_ptr->pos));
-   }
-   /* table stuff -- end*/
-   
-   /* calculate the new height of the text */ 
-   height -= row_ptr->height;
-   
-   row_ptr->height= maxasc+maxdesc+labeladdon;
-   row_ptr->baseline= maxasc+labeladdon;
-   
-   height += row_ptr->height;
-}
-#endif
 
 
 /* Appends the implicit specified paragraph behind the specified row,
@@ -2123,7 +1653,7 @@ void LyXText::BreakAgainOneRow(Row * row)
 
 void LyXText::BreakParagraph(char keep_layout)
 {
-   LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+   LyXLayout const & layout = textclasslist.Style(buffer->params.textclass,
                                      cursor.par->GetLayout());
    
    /* table stuff -- begin */
@@ -2149,7 +1679,7 @@ void LyXText::BreakParagraph(char keep_layout)
    if (cursor.par->table) {
        int cell = NumberOfCell(cursor.par, cursor.pos);
        if (cursor.par->table->ShouldBeVeryLastCell(cell))
-           SetCursor(cursor.par, cursor.par->text.size());
+           SetCursor(cursor.par, cursor.par->size());
    }
    /* table stuff -- end */
    
@@ -2176,7 +1706,7 @@ void LyXText::BreakParagraph(char keep_layout)
    /* table stuff -- end */
 
    // well this is the caption hack since one caption is really enough
-   if (layout.labeltype == LABEL_SENSITIVE){
+   if (layout.labeltype == LABEL_SENSITIVE) {
      if (!cursor.pos)
             cursor.par->SetLayout(0); // set to standard-layout
      else
@@ -2252,7 +1782,7 @@ void LyXText::OpenFootnote()
        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)->text.size());
+            cursor.pos + cursor.par->ParFromPos(cursor.pos)->size());
    
    /* the cursor must be exactly before the footnote */ 
    par = cursor.par->ParFromPos(cursor.pos);
@@ -2270,6 +1800,7 @@ void LyXText::OpenFootnote()
    /* set the dimensions of the cursor row */
    row->fill = Fill(row, paperwidth);
    SetHeightOfRow(row);
+   // CHECK See comment on top of text.C
    tmppar = tmppar->Next();
    
    while (tmppar != endpar) {
@@ -2385,8 +1916,12 @@ void LyXText::TableFeatures(int feature) const
                
           /* insert the new cells */ 
           int number = cursor.par->table->NumberOfCellsInRow(cell_org);
-          for (int i = 0; i < number; ++i)
+         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);
@@ -2420,9 +1955,13 @@ void LyXText::TableFeatures(int feature) const
                
           /* insert the new cells */ 
           int number = cursor.par->table->NumberOfCellsInRow(cell_org);
-          for (int i = 0; i < number; ++i)
+         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();
@@ -2432,10 +1971,13 @@ void LyXText::TableFeatures(int feature) const
              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)){
+                  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;
@@ -2445,9 +1987,12 @@ void LyXText::TableFeatures(int feature) const
               ++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(), LyXParagraph::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);
@@ -2456,8 +2001,8 @@ void LyXText::TableFeatures(int feature) const
           return;
       }
       case LyXTable::DELETE_ROW:
-          if (current_view->the_locking_inset)
-              current_view->unlockInset(current_view->the_locking_inset);
+          if (owner_->the_locking_inset)
+              owner_->unlockInset(owner_->the_locking_inset);
           RemoveTableRow(&cursor);
           RedoParagraph();
           return;
@@ -2466,8 +2011,8 @@ void LyXText::TableFeatures(int feature) const
              LyXParagraph::size_type pos = 0;
           int cell_org = actCell;
           int cell = 0;
-          if (current_view->the_locking_inset)
-              current_view->unlockInset(current_view->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)){
@@ -2587,7 +2132,7 @@ void LyXText::TableFeatures(int feature) const
           // dummy-paragraph !! 
           // not necessar anymore with UNDO :)
           for (LyXParagraph::size_type i = 
-                      cursor.par->text.size() - 1; i >= 0; --i)
+                      cursor.par->size() - 1; i >= 0; --i)
              cursor.par->Erase(i);
           RedoParagraph();
           return;
@@ -2779,25 +2324,15 @@ void LyXText::InsertCharInTable(char c)
 
        jumped_over_space = false;
        if (IsLineSeparatorChar(c)) {
-               
-               /* 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->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)))
+               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)))
                        return;
-       }
-       else if (IsNewlineChar(c)) {
+       } else if (IsNewlineChar(c)) {
             if (!IsEmptyTableCell()) {
                 TableFeatures(LyXTable::APPEND_CONT_ROW);
                 CursorDown();
@@ -2866,6 +2401,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph * par,
                /* redraw only the row */
                LyXCursor tmpcursor = cursor;
                SetCursorIntern(par, pos);
+               //CHECK See comment on top of text.C
                refresh_y = y;
                refresh_x = cursor.x;
                refresh_row = row;
@@ -2897,13 +2433,12 @@ 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();
                
@@ -2920,8 +2455,7 @@ void LyXText::BackspaceInTable()
                if (cursor.par->IsNewline(cursor.pos)) {
                        /* nothing :-) */
                        return;
-               }
-               else {
+               } else {
                        cursor.par->Erase(cursor.pos);
                        
                        /* refresh the positions */
@@ -2930,26 +2464,6 @@ void LyXText::BackspaceInTable()
                                tmprow = tmprow->next;
                                tmprow->pos--;
                        }
-                       
-                       /* delete superfluous blanks */ 
-                       if (cursor.pos < cursor.par->Last() - 1 &&
-                       (cursor.par->IsLineSeparator(cursor.pos))) {
-                               
-                               if (cursor.pos == BeginningOfMainBody(cursor.par)
-                               || !cursor.pos 
-                               || cursor.par->IsLineSeparator(cursor.pos - 1)) {
-                                       cursor.par->Erase(cursor.pos);
-                                       /* 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 */
-                                               cursor.pos--;
-                               }
-                       }
                }
       
                CheckParagraphInTable(cursor.par, cursor.pos);
@@ -2973,39 +2487,27 @@ void LyXText::BackspaceInTable()
 /* just a macro to make some thing easier. */ 
 void LyXText::RedoParagraph() const
 {
-#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)
 {
        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 = 
-               textclasslist.Style(parameters->textclass,
+        * disable the double-space checking */
+
+       bool freeSpacing = 
+               textclasslist.Style(buffer->params.textclass,
                               cursor.row->par->GetLayout()).free_spacing;
-   
-       if (freeSpacingBo && IsLineSeparatorChar(c) 
-           && (!cursor.pos || cursor.par->IsLineSeparator(cursor.pos - 1))) 
-               c = LyXParagraph::META_PROTECTED_SEPARATOR;
-   
+
        /* table stuff -- begin*/
        if (cursor.par->table) {
                InsertCharInTable(c);
@@ -3023,9 +2525,7 @@ void  LyXText::InsertChar(char c)
        // 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
        // and it should (along with realtmpfont) when we type the space.
-#ifdef WITH_WARNINGS
-#warning There is a bug here! (Asger)
-#endif
+       // CHECK There is a bug here! (Asger)
        
        LyXFont realtmpfont = real_current_font;
        LyXFont rawtmpfont = current_font;  /* store the current font.
@@ -3040,35 +2540,7 @@ void  LyXText::InsertChar(char c)
 
        bool jumped_over_space = false;
    
-       if (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
-                        * will just make a CursorRight. BUT: The font of this
-                        * space should be set to current font. That is why
-                        * we need to rebreak perhaps. If there is a protected
-                        * blank at the end of a row we have to force
-                        * a rebreak.*/ 
-          
-                       current_view->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.par->Erase(cursor.pos);
-                       jumped_over_space = true;
-#else
-                       // Seems to me that this works just as well.
-                       CursorRight();
-                       charInserted();
-                       return;
-#endif
-               } else
-#endif   
+       if (!freeSpacing && IsLineSeparatorChar(c)) {
                if ((cursor.pos > 0 
                     && cursor.par->IsLineSeparator(cursor.pos - 1))
                    || (cursor.pos > 0
@@ -3078,9 +2550,9 @@ void  LyXText::InsertChar(char c)
                             && cursor.par->Previous()->footnoteflag
                             == LyXParagraph::OPEN_FOOTNOTE))) {
                        if (cursor.pos == 0 )
-                               current_view->owner()->getMiniBuffer()->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
-                               current_view->owner()->getMiniBuffer()->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."));
                        charInserted();
                        return;
                }
@@ -3216,7 +2688,7 @@ void  LyXText::InsertChar(char c)
                RedoHeightOfParagraph(cursor);
        } else {
                /* now the special right address boxes */
-               if (textclasslist.Style(parameters->textclass,
+               if (textclasslist.Style(buffer->params.textclass,
                                   cursor.par->GetLayout()).margintype
                    == MARGIN_RIGHT_ADDRESS_BOX) {
                        RedoDrawingOfParagraph(cursor); 
@@ -3254,23 +2726,22 @@ void LyXText::PrepareToPrint(Row * row, float & x,
        fill_separator = 0;
        fill_label_hfill = 0;
 
-       LyXDirection direction = row->par->getParDirection();
+        bool is_rtl = row->par->isRightToLeftPar();
 
-       if (direction == LYX_DIR_RIGHT_TO_LEFT) {
+       if (is_rtl) {
                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);
+                       x += lyxfont::width("Mwide-figM", font);
                }
-       }
-       else
+       } else
                x = LeftMargin(row);
        
        /* is there a manual margin with a manual label */ 
-       if (textclasslist.Style(parameters->textclass,
+       if (textclasslist.Style(buffer->params.textclass,
                           row->par->GetLayout()).margintype == MARGIN_MANUAL
-           && textclasslist.Style(parameters->textclass,
+           && textclasslist.Style(buffer->params.textclass,
                              row->par->GetLayout()).labeltype == LABEL_MANUAL) {
               
                nlh = NumberOfLabelHfills(row) + 1; /* one more since labels 
@@ -3298,7 +2769,7 @@ void LyXText::PrepareToPrint(Row * row, float & x,
            * set x how you need it */
        int align;
        if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT)
-         align = textclasslist.Style(parameters->textclass, row->par->GetLayout()).align;
+         align = textclasslist.Style(buffer->params.textclass, row->par->GetLayout()).align;
        else
          align = row->par->FirstPhysicalPar()->align;
           
@@ -3318,7 +2789,7 @@ void LyXText::PrepareToPrint(Row * row, float & x,
                       && row->next->par->GetInset(row->next->pos)->display())
                  )
                fill_separator = w / ns;
-             else if (direction == LYX_DIR_RIGHT_TO_LEFT)
+             else if (is_rtl)
                x += w;
              break;
            case LYX_ALIGN_RIGHT:
@@ -3333,23 +2804,18 @@ void LyXText::PrepareToPrint(Row * row, float & x,
                return;
 
        ComputeBidiTables(row);
-       if (direction == LYX_DIR_RIGHT_TO_LEFT) {
+       if (is_rtl) {
                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,
+               if (main_body > 0 &&
+                   (main_body-1 > last || 
+                    !row->par->IsLineSeparator(main_body-1))) {
+                       LyXLayout const & layout = textclasslist.Style(buffer->params.textclass,
                                                                       row->par->GetLayout());
-                       x += GetFont(row->par, -2).stringWidth(layout.labelsep);
+                       x += lyxfont::width(layout.labelsep,
+                                           GetFont(row->par, -2));
                        if (main_body-1 <= last)
                                x += fill_label_hfill;
                }
@@ -3367,6 +2833,7 @@ void LyXText::CursorRightOneWord() const
 {
        // treat floats, HFills and Insets as words
        LyXCursor tmpcursor = cursor;
+       // CHECK See comment on top of text.C
 
        if (tmpcursor.pos == tmpcursor.par->Last()
            && tmpcursor.par->Next())
@@ -3508,19 +2975,18 @@ void LyXText::SelectWord()
                        1: no selection is currently set,
                        2: the cursor is not at the borders of the word. */
 
-int LyXText::SelectWordWhenUnderCursor() 
+bool LyXText::SelectWordWhenUnderCursor() 
 {
-       if ( selection ) return 0;
-       if ( cursor.pos < cursor.par->Last()
-                && !cursor.par->IsSeparator(cursor.pos)
-                && !cursor.par->IsKomma(cursor.pos)
-                && cursor.pos 
-                && !cursor.par->IsSeparator(cursor.pos -1)
-                && !cursor.par->IsKomma(cursor.pos -1) ) {
+       if (!selection &&
+           cursor.pos > 0 && cursor.pos < cursor.par->Last()
+           && !cursor.par->IsSeparator(cursor.pos)
+           && !cursor.par->IsKomma(cursor.pos)
+           && !cursor.par->IsSeparator(cursor.pos -1)
+           && !cursor.par->IsKomma(cursor.pos -1) ) {
                SelectWord();
-               return 1;
+               return true;
        }
-       return 0;
+       return false;
 }
 
 
@@ -3561,18 +3027,29 @@ char * LyXText::SelectNextWord(float & value)
        /* Start the selection from here */
        sel_cursor = cursor;
 
-       string latex;
-   
+#ifdef HAVE_SSTREAM
+       std::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) == LyXParagraph::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, false, 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 * str = 0;
 
@@ -3598,17 +3075,29 @@ void LyXText::SelectSelectedWord()
        /* set the sel cursor */
        sel_cursor = cursor;
 
-       string latex;
+#ifdef HAVE_SSTREAM
+       std::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) == LyXParagraph::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, false, 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 */ 
@@ -3623,6 +3112,7 @@ void LyXText::DeleteWordForward()
         
        if (!cursor.par->Last())
                CursorRight();
+       // CHECK See comment on top of text.C
        else {
                /* -------> Skip initial non-word stuff. */
                while ( cursor.pos < cursor.par->Last() 
@@ -3649,6 +3139,7 @@ void LyXText::DeleteWordBackward()
        LyXCursor tmpcursor = cursor;
        if (!cursor.par->Last())
          CursorLeft();
+       // CHECK See comment on top of text.C
        else{
          selection = true; // to avoid deletion 
          CursorLeftOneWord();
@@ -3666,6 +3157,7 @@ void LyXText::DeleteLineForward()
        LyXCursor tmpcursor = cursor;
        if (!cursor.par->Last())
                CursorRight();
+       // CHECK See comment on top of text.C
        else {
                CursorEnd();
                sel_cursor = cursor;
@@ -3700,7 +3192,7 @@ void LyXText::ChangeWordCase(LyXText::TextCase action)
        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 != LyXParagraph::META_INSET) {
@@ -3718,7 +3210,8 @@ void LyXText::ChangeWordCase(LyXText::TextCase action)
                        }
                }
                
-               tmppar->text[tmppos] = c;
+               //tmppar->text[tmppos] = c;
+               tmppar->SetChar(tmppos, c);
                ++tmppos;
        }
        CheckParagraph(tmppar, tmppos);
@@ -3738,21 +3231,17 @@ void LyXText::Delete()
        // just move to the right
        CursorRightIntern();
 
+       // CHECK 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;
@@ -3766,13 +3255,8 @@ void LyXText::Delete()
 }
 
 
-void  LyXText::Backspace()
+void LyXText::Backspace()
 {
-       LyXParagraph * tmppar;
-       Row * tmprow, * row;
-       long y;
-       int tmpheight;
-
        /* table stuff -- begin */
        if (cursor.par->table) {
                BackspaceInTable();
@@ -3788,6 +3272,9 @@ void  LyXText::Backspace()
        LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
 
        if (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?
@@ -3795,17 +3282,19 @@ void  LyXText::Backspace()
                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 cursor one step
+                       // left and let the DeleteEmptyParagraphMechanism handle the actual deletion
+                       // 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;
@@ -3814,7 +3303,7 @@ void  LyXText::Backspace()
                                CursorLeftIntern();
                     
                                // the layout things can change the height of a row !
-                               tmpheight = cursor.row->height;
+                               int tmpheight = cursor.row->height;
                                SetHeightOfRow(cursor.row);
                                if (cursor.row->height != tmpheight) {
                                        refresh_y = cursor.y - cursor.row->baseline;
@@ -3824,14 +3313,26 @@ 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);
                }
-               tmppar = cursor.par;
-               tmprow = cursor.row;
-               CursorLeftIntern();
+               
+               LyXParagraph * tmppar = cursor.par;
+               Row * tmprow = cursor.row;
+
+               // We used to do CursorLeftIntern() here, but it is
+               // not a good idea since it triggers the auto-delete
+               // mechanism. So we do a CursorLeftIntern()-lite,
+               // without the dreaded mechanism. (JMarc)
+               if (cursor.par->Previous()) { 
+                       // steps into the above paragraph.
+                       SetCursorIntern(cursor.par->Previous(), 
+                                       cursor.par->Previous()->Last());
+               }
+
                /* 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.
@@ -3844,18 +3345,22 @@ void  LyXText::Backspace()
                */
                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--;
@@ -3865,10 +3370,14 @@ void  LyXText::Backspace()
                        refresh_y = cursor.y - cursor.row->baseline;
                        
                        // remove the lost paragraph
-                       RemoveParagraph(tmprow);
-                       RemoveRow(tmprow);  
+                       // 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.
@@ -3880,14 +3389,18 @@ void  LyXText::Backspace()
                SetUndo(Undo::DELETE, 
                        cursor.par->ParFromPos(cursor.pos)->previous, 
                        cursor.par->ParFromPos(cursor.pos)->next); 
-               CursorLeftIntern();
+               // We used to do CursorLeftIntern() here, but it is
+               // not a good idea since it triggers the auto-delete
+               // mechanism. So we do a CursorLeftIntern()-lite,
+               // without the dreaded mechanism. (JMarc)
+               SetCursorIntern(cursor.par, cursor.pos - 1);
                
                // 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 
+                       // this is a cruel method but safe..... Matthias 
                        if (cursor.par->GetInset(cursor.pos)->display()){
                                cursor.par->Erase(cursor.pos);
                                RedoParagraph();
@@ -3895,8 +3408,8 @@ void  LyXText::Backspace()
                        }
                }
                
-               row = cursor.row;
-               y = cursor.y - row->baseline;
+               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 */ 
@@ -3910,7 +3423,7 @@ void  LyXText::Backspace()
                if (cursor.pos && cursor.par->IsNewline(cursor.pos)) {
                        cursor.par->Erase(cursor.pos);
                        // refresh the positions
-                       tmprow = row;
+                       Row * tmprow = row;
                        while (tmprow->next && tmprow->next->par == row->par) {
                                tmprow = tmprow->next;
                                tmprow->pos--;
@@ -3931,34 +3444,12 @@ void  LyXText::Backspace()
                        cursor.par->Erase(cursor.pos);
                        
                        // refresh the positions
-                       tmprow = row;
+                       Row * tmprow = row;
                        while (tmprow->next && tmprow->next->par == row->par) {
                                tmprow = tmprow->next;
                                tmprow->pos--;
                        }
 
-#ifndef FIX_DOUBLE_SPACE
-                       // delete superfluous blanks 
-                       if (cursor.pos < cursor.par->Last() - 1 &&
-                           (cursor.par->IsLineSeparator(cursor.pos))) {
-                               
-                               if (cursor.pos == BeginningOfMainBody(cursor.par)
-                                   || !cursor.pos 
-                                   || cursor.par->IsLineSeparator(cursor.pos - 1)) {
-                                       cursor.par->Erase(cursor.pos);
-                                       // 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
-                                               cursor.pos--;
-                               }
-                       }
-#endif
-                       
                        // delete newlines at the beginning of paragraphs
                        while (cursor.par->Last() &&
                               cursor.par->IsNewline(cursor.pos) &&
@@ -3980,7 +3471,7 @@ void  LyXText::Backspace()
                        if ( z >= row->pos) {
                                row->pos = z + 1;
                                
-                               tmprow = row->previous;
+                               Row * tmprow = row->previous;
                                
                                // maybe the current row is now empty
                                if (row->pos >= row->par->Last()) {
@@ -4059,7 +3550,6 @@ void  LyXText::Backspace()
                        SetCursor(cursor.par, cursor.pos, false);
                }
        }
-   
        // restore the current font
        // That is what a user expects!
        current_font = rawtmpfont; 
@@ -4071,7 +3561,7 @@ void  LyXText::Backspace()
                RedoHeightOfParagraph(cursor);
        } else {
                // now the special right address boxes
-               if (textclasslist.Style(parameters->textclass,
+               if (textclasslist.Style(buffer->params.textclass,
                                        cursor.par->GetLayout()).margintype == MARGIN_RIGHT_ADDRESS_BOX) {
                        RedoDrawingOfParagraph(cursor); 
                }
@@ -4079,15 +3569,15 @@ void  LyXText::Backspace()
 }
 
 
-#ifdef USE_PAINTER
-void LyXText::GetVisibleRow(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();
        
-       LyXDirection direction = row_ptr->par->getParDirection();
-       LyXParagraph::size_type vpos, pos, pos_end;
+       bool is_rtl = row_ptr->par->isRightToLeftPar();
+       LyXParagraph::size_type last = RowLastPrintable(row_ptr);
+
+       LyXParagraph::size_type vpos, pos;
        float x, tmpx;
        int y_top, y_bottom;
        float fill_separator, fill_hfill, fill_label_hfill;
@@ -4100,57 +3590,143 @@ void LyXText::GetVisibleRow(int offset,
        }
        PrepareToPrint(row_ptr, x, fill_separator,
                       fill_hfill, fill_label_hfill);
-
-       /* initialize the pixmap */
        
+       // clear the area where we want to paint/print
        pain.fillRectangle(0, offset, paperwidth, row_ptr->height);
        
-       // check for NOT FAST SELECTION
-       if (!fast_selection && !mono_video && selection) {
-               /* selection code */ 
-               if (sel_start_cursor.row == row_ptr &&
-                   sel_end_cursor.row == row_ptr) {
-                       if (sel_start_cursor.x < sel_end_cursor.x)
-                               pain.fillRectangle(sel_start_cursor.x, offset,
-                                                  sel_end_cursor.x,
-                                                  row_ptr->height,
-                                                  LColor::selection);
-                       else
-                               pain.fillRectangle(sel_end_cursor.x, offset,
-                                                  sel_start_cursor.x,
-                                                  row_ptr->height,
+       if (selection) {
+               /* selection code */
+               if (bidi_same_direction) {
+                       if (sel_start_cursor.row == row_ptr &&
+                           sel_end_cursor.row == row_ptr) {
+                               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 (is_rtl)
+                                       pain.fillRectangle(0, offset,
+                                                          sel_start_cursor.x,
+                                                          row_ptr->height,
+                                                          LColor::selection);
+                               else
+                                       pain.fillRectangle(sel_start_cursor.x, offset,
+                                                          paperwidth - sel_start_cursor.x,
+                                                          row_ptr->height,
+                                                          LColor::selection);
+                       } else if (sel_end_cursor.row == row_ptr) {
+                               if (is_rtl)
+                                       pain.fillRectangle(sel_end_cursor.x, offset,
+                                                          paperwidth - sel_end_cursor.x,
+                                                          row_ptr->height,
+                                                          LColor::selection);
+                               else
+                                       pain.fillRectangle(0, offset,
+                                                          sel_end_cursor.x,
+                                                          row_ptr->height,
+                                                          LColor::selection);
+                       } else if (y > long(sel_start_cursor.y)
+                                  && y < long(sel_end_cursor.y)) {
+                               pain.fillRectangle(0, offset,
+                                                  paperwidth, 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) {
-                    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) {
+                       }
+               } else if ( sel_start_cursor.row != row_ptr &&
+                           sel_end_cursor.row != row_ptr &&
+                           y > long(sel_start_cursor.y)
+                           && y < long(sel_end_cursor.y)) {
                        pain.fillRectangle(0, offset,
                                           paperwidth, row_ptr->height,
                                           LColor::selection);
+               } else if (sel_start_cursor.row == row_ptr ||
+                          sel_end_cursor.row == row_ptr) {
+                       float tmpx = x;
+                       int cell = 0;
+                       if (row_ptr->par->table) {
+                               cell = NumberOfCell(row_ptr->par, row_ptr->pos);
+                               tmpx += row_ptr->par->table->GetBeginningOfTextInCell(cell);
+                       }
+                       if ( (sel_start_cursor.row != row_ptr && !is_rtl) ||
+                            (sel_end_cursor.row != row_ptr && is_rtl))
+                               pain.fillRectangle(0, offset,
+                                                  tmpx, row_ptr->height,
+                                                  LColor::selection);
+                       if (row_ptr->par->table) {
+                               float x_old = x;
+                               for (vpos = row_ptr->pos; vpos <= last; ++vpos)  {
+                                       pos = vis2log(vpos);
+                                       float old_tmpx = tmpx;
+                                       if (row_ptr->par->IsNewline(pos)) {
+                                               tmpx = x_old + row_ptr->par->table->WidthOfColumn(cell);
+                                               x_old = tmpx;
+                                               ++cell;
+                                               tmpx += row_ptr->par->table->GetBeginningOfTextInCell(cell);
+                                       } else {
+                                               tmpx += SingleWidth(row_ptr->par, pos);
+                                       }
+                                       if ( (sel_start_cursor.row != row_ptr ||
+                                             sel_start_cursor.pos <= pos) &&
+                                            (sel_end_cursor.row != row_ptr ||
+                                             pos < sel_end_cursor.pos) )
+                                               pain.fillRectangle(old_tmpx, offset,
+                                                                  tmpx - old_tmpx + 1,
+                                                                  row_ptr->height,
+                                                                  LColor::selection);
+                               }
+                       } else {
+                               LyXParagraph::size_type main_body =
+                                       BeginningOfMainBody(row_ptr->par);
+
+                               for (vpos = row_ptr->pos; vpos <= last; ++vpos)  {
+                                       pos = vis2log(vpos);
+                                       float old_tmpx = tmpx;
+                                       if (main_body > 0 && pos == main_body-1) {
+                                               tmpx += fill_label_hfill +
+                                                       lyxfont::width(textclasslist.Style(buffer->params.textclass,
+                                                                                          row_ptr->par->GetLayout()).labelsep,
+                                                                      GetFont(row_ptr->par, -2));
+                                               if (row_ptr->par->IsLineSeparator(main_body-1))
+                                                       tmpx -= SingleWidth(row_ptr->par, main_body-1);
+                                       }
+                                       if (HfillExpansion(row_ptr, pos)) {
+                                               tmpx += SingleWidth(row_ptr->par, pos);
+                                               if (pos >= main_body)
+                                                       tmpx += fill_hfill;
+                                               else 
+                                                       tmpx += fill_label_hfill;
+                                       }
+                                       else if (row_ptr->par->IsSeparator(pos)) {
+                                               tmpx += SingleWidth(row_ptr->par, pos);
+                                               if (pos >= main_body)
+                                                       tmpx += fill_separator;
+                                       } else
+                                               tmpx += SingleWidth(row_ptr->par, pos);
+
+                                       if ( (sel_start_cursor.row != row_ptr ||
+                                             sel_start_cursor.pos <= pos) &&
+                                            (sel_end_cursor.row != row_ptr ||
+                                             pos < sel_end_cursor.pos) )
+                                               pain.fillRectangle(old_tmpx, offset,
+                                                                  tmpx - old_tmpx + 1,
+                                                                  row_ptr->height,
+                                                          LColor::selection);
+                               }
+                       }
+                       if ( (sel_start_cursor.row != row_ptr && is_rtl) ||
+                            (sel_end_cursor.row != row_ptr && !is_rtl) )
+                               pain.fillRectangle(tmpx, offset,
+                                                  paperwidth - tmpx,
+                                                  row_ptr->height,
+                                                  LColor::selection);
                }
-       } // end of NOT FAST SELECTION code
-       
+       }
+
        if (row_ptr->par->appendix){
                pain.line(1, offset,
                          1, offset + row_ptr->height,
@@ -4160,11 +3736,34 @@ void LyXText::GetVisibleRow(int offset,
                          LColor::appendixline);
        }
 
+       int depth = row_ptr->par->GetDepth();
+       if (depth > 0) {
+               int next_depth = (row_ptr->next)
+                       ? next_depth = row_ptr->next->par->GetDepth() : 0; 
+               int prev_depth = (row_ptr->previous)
+                       ? row_ptr->previous->par->GetDepth() : 0;
+
+               for (int i = 1; i <= depth; ++i)
+                       pain.line(4*i, offset,
+                                 4*i, offset + row_ptr->height - 1 - (i-next_depth-1)*3,
+                                 LColor::depthbar);
+
+               for (int i = prev_depth + 1; i <= depth; ++i)
+                       pain.fillRectangle(4*i, offset,
+                                          4, 2,
+                                          LColor::depthbar);
+
+               for (int i = next_depth + 1; i <= depth; ++i)
+                       pain.fillRectangle(4*i, offset + row_ptr->height - 2 - (i-next_depth-1)*3,
+                                          4, 2,
+                                          LColor::depthbar);
+       }
+       
        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 asc = lyxfont::maxAscent(font);
+               int x = (LYX_PAPER_MARGIN - lyxfont::width('|', font)) / 2;
                int y1 = (offset + row_ptr->baseline);
                int y2 = (offset + row_ptr->baseline) - asc;
                pain.line(x, y1, x, y2, LColor::minipageline);
@@ -4172,10 +3771,10 @@ void LyXText::GetVisibleRow(int offset,
        if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
                LyXFont font(LyXFont::ALL_SANE);
                font.setSize(LyXFont::SIZE_FOOTNOTE);
-               font.setColor(LColor::red);
+               font.setColor(LColor::footnote);
                
                int box_x = LYX_PAPER_MARGIN;
-               box_x += font.textWidth(" wide-tab ", 10);
+               box_x += lyxfont::width(" wide-tab ", font);
                if (row_ptr->previous && 
                    row_ptr->previous->par->footnoteflag != LyXParagraph::OPEN_FOOTNOTE){
                        string fs;
@@ -4202,41 +3801,34 @@ void LyXText::GetVisibleRow(int offset,
                                fs = " foot";
                                break;
                        }
-
-#if 0
-                       // Determine background color.
-                       gc_type back = gc_lighted;
-                       if (mono_video) {
-                               back = gc_clear;
-                       }
-#endif
+                       
                        pain.fillRectangle(LYX_PAPER_MARGIN,
                                           offset + 1,
                                           box_x - LYX_PAPER_MARGIN,
-                                          int(font.maxAscent()
-                                              + font.maxDescent()),
+                                          int(lyxfont::maxAscent(font)
+                                              + lyxfont::maxDescent(font)),
                                           LColor::footnotebg);
-
+                       
                        pain.line(LYX_PAPER_MARGIN, offset,
                                  paperwidth - LYX_PAPER_MARGIN, offset,
                                  LColor::footnoteframe);
-
+                       
                        pain.text(LYX_PAPER_MARGIN,
-                                 offset + int(font.maxAscent()) + 1,
+                                 offset + int(lyxfont::maxAscent(font)) + 1,
                                  fs, font);
-
+                       
                        pain.line(LYX_PAPER_MARGIN, offset,
                                  LYX_PAPER_MARGIN,
-                                 offset + int(font.maxAscent()
-                                              + font.maxDescent()),
+                                 offset + int(lyxfont::maxAscent(font)
+                                              + lyxfont::maxDescent(font)),
                                  LColor::footnoteframe);
-
+                       
                        pain.line(LYX_PAPER_MARGIN,
-                                 offset + int(font.maxAscent()
-                                              + font.maxDescent()) + 1,
+                                 offset + int(lyxfont::maxAscent(font)
+                                              + lyxfont::maxDescent(font)) + 1,
                                  box_x,
-                                 offset + int(font.maxAscent()
-                                              + font.maxDescent()) + 1,
+                                 offset + int(lyxfont::maxAscent(font)
+                                              + lyxfont::maxDescent(font)) + 1,
                                  LColor::footnoteframe);
                        
                }
@@ -4245,29 +3837,29 @@ void LyXText::GetVisibleRow(int offset,
                pain.line(box_x, offset,
                          box_x, offset + row_ptr->height,
                          LColor::footnoteframe);
-
+               
                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);
-
-                       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);
-               }
+       } 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 += lyxfont::width(" wide-tab ", font);
+               
+               pain.line(box_x, offset,
+                         paperwidth - LYX_PAPER_MARGIN,
+                         offset, LColor::footnote);
        }
        
-       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
-                                          row_ptr->par->GetLayout());
+       LyXLayout const & layout =
+               textclasslist.Style(buffer->params.textclass,
+                                   row_ptr->par->GetLayout());
        firstpar = row_ptr->par->FirstPhysicalPar();
        
        y_top = 0;
@@ -4277,21 +3869,38 @@ void LyXText::GetVisibleRow(int offset,
        if (row_ptr->pos == 0
            && row_ptr->par == firstpar) {
                
-                /* start of appendix? */
+               /* start of appendix? */
                if (row_ptr->par->start_of_appendix){
-                       owner_->painter().line(1, offset,
-                                              paperwidth - 2, offset,
-                                              LColor::appendixline);
+                       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  */
-                       pain.line(0, offset + y_top + 2 * DefaultHeight(),
-                                 paperwidth, offset + y_top + 2 * DefaultHeight(),
-                                 LColor::pagebreak, Painter::line_onoffdash);
+                       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);
                        y_top += 3 * DefaultHeight();
                }
                
@@ -4315,33 +3924,33 @@ void LyXText::GetVisibleRow(int offset,
                }
                
                /* 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 == BufferParams::PARSEP_SKIP) {
+               if (buffer->params.paragraph_separation == BufferParams::PARSEP_SKIP) {
                        if (layout.latextype == LATEX_PARAGRAPH
                            && firstpar->GetDepth() == 0
                            && firstpar->Previous())
-                               y_top += parameters->getDefSkip().inPixels();
+                               y_top += buffer->params.getDefSkip().inPixels(owner_);
                        else if (firstpar->Previous()
-                                && textclasslist.Style(parameters->textclass,
-                                                  firstpar->Previous()->GetLayout()).latextype == LATEX_PARAGRAPH
+                                && textclasslist.Style(buffer->params.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 += buffer->params.getDefSkip().inPixels(owner_);
                }
                
                if (row_ptr->par->line_top) {      /* draw a top line  */
-                       y_top +=  GetFont(row_ptr->par, 0).ascent('x');
-
+                       y_top +=  lyxfont::ascent('x', GetFont(row_ptr->par, 0));
+                       
                        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');
+                       y_top +=  lyxfont::ascent('x', GetFont(row_ptr->par, 0));
                }
                
                /* should we print a label? */ 
@@ -4350,36 +3959,43 @@ void LyXText::GetVisibleRow(int offset,
                        || layout.latextype != LATEX_ENVIRONMENT
                        || row_ptr->par->IsFirstInSequence())) {
                        font = GetFont(row_ptr->par, -2);
-                       if (!row_ptr->par->GetLabestring().empty()) {
+                       if (!row_ptr->par->GetLabelstring().empty()) {
                                tmpx = x;
-                               string tmpstring = row_ptr->par->GetLabestring();
+                               string tmpstring = row_ptr->par->GetLabelstring();
                                
                                if (layout.labeltype == LABEL_COUNTER_CHAPTER) {
-                                       if (parameters->secnumdepth >= 0){
+                                       if (buffer->params.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())
+                                               float spacing_val = 1.0;
+                                               if (!row_ptr->par->spacing.isDefault()) {
+                                                       spacing_val = row_ptr->par->spacing.getValue();
+                                               } else {
+                                                       spacing_val = buffer->params.spacing.getValue();
+                                               }
+   
+                                               maxdesc = int(lyxfont::maxDescent(font) * layout.spacing.getValue() * spacing_val)
                                                        + int(layout.parsep) * DefaultHeight();
-                                               if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                                               if (is_rtl)
                                                        tmpx = paperwidth - LeftMargin(row_ptr) - 
-                                                               font.stringWidth(tmpstring);
+                                                               lyxfont::width(tmpstring, font);
                                                pain.text(int(tmpx),
                                                          offset + row_ptr->baseline - row_ptr->ascent_of_text - maxdesc,
                                                          tmpstring, font);
                                        }
                                } else {
-                                       if (direction == LYX_DIR_LEFT_TO_RIGHT)
-                                               tmpx = x - font.stringWidth(layout.labelsep)
-                                                       - font.stringWidth(tmpstring);
-                                       else {
+                                       if (is_rtl) {
                                                tmpx = paperwidth - LeftMargin(row_ptr)
-                                                       + font.stringWidth(layout.labelsep);
+                                                       + lyxfont::width(layout.labelsep, font);
                                                if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)  {
                                                        LyXFont font(LyXFont::ALL_SANE);
                                                        font.setSize(LyXFont::SIZE_SMALL);
-                                                       tmpx += font.textWidth("Mwide-figM", 10);
+                                                       tmpx += lyxfont::width("Mwide-fixM", font);
                                                }
-                                       }
+                                       } else
+                                               tmpx = x - lyxfont::width(layout.labelsep, font)
+                                                       - lyxfont::width(tmpstring, font);
+
                                        /* draw it! */
                                        pain.text(int(tmpx),
                                                  offset + row_ptr->baseline,
@@ -4392,21 +4008,26 @@ void LyXText::GetVisibleRow(int offset,
                           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()));
+                               if (!row_ptr->par->GetLabelstring().empty()) {
+                                       string tmpstring = row_ptr->par->GetLabelstring();
+                                       float spacing_val = 1.0;
+                                       if (!row_ptr->par->spacing.isDefault()) {
+                                               spacing_val = row_ptr->par->spacing.getValue();
+                                       } else {
+                                               spacing_val = buffer->params.spacing.getValue();
+                                       }
+   
+                                       maxdesc = int(lyxfont::maxDescent(font) * layout.spacing.getValue() * spacing_val
+                                                     + (layout.labelbottomsep * DefaultHeight()));
                                        
                                        tmpx = x;
                                        if (layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT){
-                                               tmpx = ( ((direction == LYX_DIR_LEFT_TO_RIGHT)
-                                                         ? x : LeftMargin(row_ptr) )
+                                               tmpx = ( (is_rtl ? LeftMargin(row_ptr) : x)
                                                         + paperwidth - RightMargin(row_ptr) ) / 2; 
-                                               tmpx -= (font.stringWidth(tmpstring)/2);
-                                       } else if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                                               tmpx -= lyxfont::width(tmpstring, font) / 2;
+                                       } else if (is_rtl)
                                                tmpx = paperwidth - LeftMargin(row_ptr) - 
-                                                       font.stringWidth(tmpstring);
+                                                       lyxfont::width(tmpstring, font);
                                        pain.text(int(tmpx),
                                                  offset + row_ptr->baseline
                                                  - row_ptr->ascent_of_text
@@ -4415,26 +4036,24 @@ void LyXText::GetVisibleRow(int offset,
                                }
                        }
                }
-               if (layout.labeltype == LABEL_BIBLIO) { // ale970302
-                       if (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);
-                       }
-               } 
+               if (layout.labeltype == LABEL_BIBLIO && row_ptr->par->bibkey) {
+                       font = GetFont(row_ptr->par, -1);
+                       if (is_rtl)
+                               tmpx = paperwidth - LeftMargin(row_ptr)
+                                       + lyxfont::width(layout.labelsep, font);
+                       else
+                               tmpx = x - lyxfont::width(layout.labelsep, font)
+                                       - row_ptr->par->bibkey->width(owner_->painter(), font);
+                       row_ptr->par->bibkey->draw(pain,
+                                                  font,
+                                                  offset + row_ptr->baseline, 
+                                                  tmpx);
+               }
        }
        
        /* is it a last row? */
        par = row_ptr->par->LastPhysicalPar();
-       if (row_ptr->par->ParFromPos(RowLast(row_ptr) + 1) == par
+       if (row_ptr->par->ParFromPos(last + 1) == par
            && (!row_ptr->next || row_ptr->next->par != row_ptr->par)) {     
                
                /* think about the margins */ 
@@ -4443,10 +4062,27 @@ void LyXText::GetVisibleRow(int offset,
                
                /* draw a bottom pagebreak */ 
                if (firstpar->pagebreak_bottom) {
-                       pain.line(0, offset + y_bottom - 2 * DefaultHeight(),
-                                 paperwidth,
+                       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);
+                                 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);
                        y_bottom -= 3 * DefaultHeight();
                }
                
@@ -4469,21 +4105,52 @@ void LyXText::GetVisibleRow(int offset,
                }
                
                /* 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');
+                       y_bottom -= lyxfont::ascent('x', GetFont(par, par->Last() - 1));
                        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');
+                       y_bottom -= lyxfont::ascent('x', GetFont(par, par->Last() - 1));
+               }
+
+               // 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, last);
+                       int size = int(0.75 * lyxfont::maxAscent(font));
+                       int y = (offset + row_ptr->baseline) - size;
+                       int x = is_rtl ? LYX_PAPER_MARGIN 
+                               : paperwidth - LYX_PAPER_MARGIN - size;
+                       if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)
+                               if (is_rtl) {
+                                       LyXFont font(LyXFont::ALL_SANE);
+                                       font.setSize(LyXFont::SIZE_SMALL);
+                                       x += lyxfont::width("Mwide-figM", font);
+                               } else
+                                       x -= LYX_PAPER_MARGIN/2;
+                       if (row_ptr->fill <= size)
+                               x += (size - row_ptr->fill + 1) * (is_rtl ? -1 : 1);
+                       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);
        
        vpos = row_ptr->pos;
        /* table stuff -- begin*/
@@ -4493,7 +4160,7 @@ void LyXText::GetVisibleRow(int offset,
                float x_old = x;
                x += row_ptr->par->table->GetBeginningOfTextInCell(cell);
                
-               while (vpos <= pos_end)  {
+               while (vpos <= last)  {
                        pos = vis2log(vpos);
                        if (row_ptr->par->IsNewline(pos)) {
                                
@@ -4505,40 +4172,42 @@ void LyXText::GetVisibleRow(int offset,
                                    !row_ptr->par->table->IsContRow(cell))
                                        pain.line(int(x_old),
                                                  offset + row_ptr->baseline - row_ptr->ascent_of_text,
-                                                 int(x - x_old),
+                                                 int(x),
                                                  offset + row_ptr->baseline - row_ptr->ascent_of_text,
-                                                 LColor::tableline);
+                                                 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))
-
+                                       
                                        pain.line(int(x_old),
                                                  offset + y_bottom - 1,
-                                                 int(x - x_old),
+                                                 int(x),
                                                  offset + y_bottom - 1,
-                                                 LColor::tableline);
-
+                                                 LColor::tableline,
+                                                 on_off ? Painter::line_onoffdash : Painter::line_solid);
+                               
                                on_off = !row_ptr->par->table->LeftLine(cell);
-
+                               
                                pain.line(int(x_old),
                                          offset + row_ptr->baseline - row_ptr->ascent_of_text,
                                          int(x_old),
-                                         offset + y_bottom,
+                                         offset + y_bottom - 1,
                                          LColor::tableline,
-                                         Painter::line_onoffdash);
+                                         on_off ? Painter::line_onoffdash : Painter::line_solid);
                                
                                on_off = !row_ptr->par->table->RightLine(cell);
-
+                               
                                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,
-                                         Painter::line_onoffdash);
+                                         on_off ? Painter::line_onoffdash : Painter::line_solid);
                                
                                x_old = x;
-                /* take care about the alignment and other spaces */
+                               /* take care about the alignment and other spaces */
                                ++cell;
                                x += row_ptr->par->table->GetBeginningOfTextInCell(cell);
                                if (row_ptr->par->table->IsFirstCell(cell))
@@ -4546,7 +4215,7 @@ void LyXText::GetVisibleRow(int offset,
                                ++vpos;
                        } else if (row_ptr->par->IsHfill(pos)) {
                                x += 1;
-
+                               
                                pain.line(int(x),
                                          offset + row_ptr->baseline - DefaultHeight() / 2,
                                          int(x),
@@ -4555,45 +4224,12 @@ void LyXText::GetVisibleRow(int offset,
                                
                                x += 2;
                                ++vpos;
-                       } 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) == 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 - tmpx - 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);
-                                               }
-                                       }
-                                       ++vpos;
-                               } else
-                                       draw(row_ptr, vpos, offset, x);
-                       }
+                       } else if (row_ptr->par->IsSeparator(pos)) {
+                               tmpx = x;
+                               x+= SingleWidth(row_ptr->par, pos);
+                               ++vpos;
+                       } else
+                               draw(row_ptr, vpos, offset, x);
                }
                
                /* do not forget the very last cell. This has no NEWLINE so 
@@ -4604,59 +4240,59 @@ void LyXText::GetVisibleRow(int offset,
                        if ((!on_off ||
                             !row_ptr->par->table->TopAlreadyDrawed(cell)) &&
                            !row_ptr->par->table->IsContRow(cell))
-
+                               
                                pain.line(int(x_old),
                                          offset + row_ptr->baseline - row_ptr->ascent_of_text,
-                                         int(x - x_old),
+                                         int(x),
                                          offset + row_ptr->baseline - row_ptr->ascent_of_text,
                                          LColor::tableline,
-                                         Painter::line_onoffdash);
+                                         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))
-
+                               
                                pain.line(int(x_old),
                                          offset + y_bottom - 1,
-                                         int(x - x_old),
+                                         int(x),
                                          offset + y_bottom - 1,
                                          LColor::tableline,
-                                         Painter::line_onoffdash);
+                                         on_off ? Painter::line_onoffdash : Painter::line_solid);
                        
                        on_off = !row_ptr->par->table->LeftLine(cell);
-
+                       
                        pain.line(int(x_old),
                                  offset + row_ptr->baseline - row_ptr->ascent_of_text,
                                  int(x_old),
                                  offset + y_bottom - 1,
                                  LColor::tableline,
-                                 Painter::line_onoffdash);
+                                 on_off ? Painter::line_onoffdash : Painter::line_solid);
                        
                        on_off = !row_ptr->par->table->RightLine(cell);
-
+                       
                        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,
-                                 Painter::line_onoffdash);
+                                 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 || 
+                   (main_body-1 > last || 
                     !row_ptr->par->IsLineSeparator(main_body-1)))
                        main_body = 0;
-
-               while (vpos <= pos_end)  {
+               
+               while (vpos <= last)  {
                        pos = vis2log(vpos);
                        if (main_body > 0 && pos == main_body-1) {
                                x += fill_label_hfill
-                                       + GetFont(row_ptr->par, -2).stringWidth(layout.labelsep)
+                                       + lyxfont::width(layout.labelsep, GetFont(row_ptr->par, -2))
                                        - SingleWidth(row_ptr->par, main_body-1);
                        }
-
+                       
                        if (row_ptr->par->IsHfill(pos)) {
                                x += 1;
                                pain.line(int(x),
@@ -4669,21 +4305,21 @@ void LyXText::GetVisibleRow(int offset,
                                        if (pos >= main_body) {
                                                pain.line(int(x),
                                                          offset + row_ptr->baseline - DefaultHeight() / 4,
-                                                         int(fill_hfill),
+                                                         int(x + fill_hfill),
                                                          offset + row_ptr->baseline - DefaultHeight() / 4,
                                                          LColor::vfillline,
                                                          Painter::line_onoffdash);
                                                x += fill_hfill;
-                    } else {
-                           pain.line(int(x),
-                                     offset + row_ptr->baseline - DefaultHeight() / 4,
-                                     int(fill_label_hfill),
-                                     offset + row_ptr->baseline - DefaultHeight() / 4,
-                                     LColor::vfillline,
-                                     Painter::line_onoffdash);
-                           
-                           x += fill_label_hfill;
-                    }
+                                       } 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),
@@ -4692,718 +4328,44 @@ void LyXText::GetVisibleRow(int offset,
                                }
                                x += 2;
                                ++vpos;
-                       } 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) == 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(tmpx),
-                                                         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);
-                                               }
-                                       }
-                                       ++vpos;
-                               } else
-                                       draw(row_ptr, vpos, offset, x);
-                       }
-               }
-       }
-#if 0
-       // 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);
-                               
-                       }
+                       } else if (row_ptr->par->IsSeparator(pos)) {
+                               x += SingleWidth(row_ptr->par, pos);
+                               if (pos >= main_body)
+                                       x += fill_separator;
+                               ++vpos;
+                       } else
+                               draw(row_ptr, vpos, offset, x);
                }
        }
-// end of FAST SELECTION code
-       /* thats it */
-#endif
 }
-#else
-void LyXText::GetVisibleRow(LyXScreen & scr, int offset, 
-                           Row * row_ptr, long y)
+
+
+int LyXText::DefaultHeight() const
 {
-       /* returns a printed row */
-       LyXDirection direction = row_ptr->par->getParDirection();
-       LyXParagraph::size_type vpos, pos, pos_end;
-       float x, tmpx;
-       int y_top, y_bottom;
+       LyXFont font(LyXFont::ALL_SANE);
+       return int(lyxfont::maxAscent(font) + lyxfont::maxDescent(font) * 1.5);
+}
+
+   
+/* returns the column near the specified x-coordinate of the row 
+* x is set to the real beginning of this column  */ 
+int LyXText::GetColumnNearX(Row * row, int & x) const
+{
+       float tmpx = 0.0;
        float fill_separator, fill_hfill, fill_label_hfill;
-       LyXParagraph * par, * firstpar;
-       LyXFont font;
-       int maxdesc;
-       if (row_ptr->height <= 0) {
-               lyxerr << "LYX_ERROR: row.height: " << row_ptr->height << endl;
-               return;
-       }
-       PrepareToPrint(row_ptr, x, fill_separator,
+   
+       PrepareToPrint(row, tmpx, fill_separator,
                       fill_hfill, fill_label_hfill);
 
-       /* initialize the pixmap */
-       
-       scr.fillRectangle(gc_clear,
-                         0, offset, paperwidth, row_ptr->height);
-       // check for NOT FAST SELECTION
-       if (!fast_selection && !mono_video && selection) {
-               /* selection code */ 
-               if (sel_start_cursor.row == row_ptr &&
-                   sel_end_cursor.row == row_ptr) {
-                       if (sel_start_cursor.x < sel_end_cursor.x)
-                         scr.fillRectangle(gc_selection, sel_start_cursor.x,
-                                         offset,
-                                         sel_end_cursor.x - sel_start_cursor.x,
-                                         row_ptr->height);
-                       else
-                         scr.fillRectangle(gc_selection, sel_end_cursor.x,
-                                         offset,
-                                         sel_start_cursor.x - sel_end_cursor.x,
-                                         row_ptr->height);
-               }
-               else if (sel_start_cursor.row == row_ptr) {
-                    if (direction == LYX_DIR_LEFT_TO_RIGHT)
-                       scr.fillRectangle(gc_selection, sel_start_cursor.x,
-                                         offset,
-                                         paperwidth - sel_start_cursor.x,
-                                         row_ptr->height);
-                    else
-                       scr.fillRectangle(gc_selection, 0, offset,
-                                         sel_start_cursor.x, row_ptr->height);
-               } else if (sel_end_cursor.row == row_ptr) {
-                    if (direction == LYX_DIR_LEFT_TO_RIGHT)
-                       scr.fillRectangle(gc_selection, 0, offset,
-                                         sel_end_cursor.x, row_ptr->height);
-                    else
-                       scr.fillRectangle(gc_selection, sel_end_cursor.x,
-                                         offset,
-                                         paperwidth - 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);
-                       
-               }
-       } // 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);
-       }
-
-       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);
-       }       
-       if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
-               LyXFont font(LyXFont::ALL_SANE);
-               font.setSize(LyXFont::SIZE_FOOTNOTE);
-#ifdef USE_PAINTER
-               font.setColor(LColor::footnote);
-#else
-               font.setColor(LyXFont::RED);
-#endif
-               
-               int box_x = LYX_PAPER_MARGIN;
-               box_x += font.textWidth(" wide-tab ", 10);
-               if (row_ptr->previous && 
-                   row_ptr->previous->par->footnoteflag != LyXParagraph::OPEN_FOOTNOTE){
-                       string fs;
-                       switch (row_ptr->par->footnotekind) {
-                       case LyXParagraph::MARGIN:
-                               fs = " margin";
-                               break;
-                       case LyXParagraph::FIG:
-                               fs = " fig";
-                               break;
-                       case LyXParagraph::TAB:
-                               fs = " tab";
-                               break;
-                       case LyXParagraph::WIDE_FIG:
-                               fs = " wide-fig";
-                               break;
-                       case LyXParagraph::WIDE_TAB:
-                               fs = " wide-tab";
-                               break;
-                       case LyXParagraph::ALGORITHM:
-                               fs = " alg";
-                               break;
-                       case LyXParagraph::FOOTNOTE:
-                               fs = " foot";
-                               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()));
-                       
-                       scr.drawLine(gc_foot,
-                                    offset,
-                                    LYX_PAPER_MARGIN,
-                                    paperwidth - 2*LYX_PAPER_MARGIN);
-                       
-                       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()));
-                       
-                       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);
-               
-               scr.drawVerticalLine(gc_foot,
-                                    paperwidth - LYX_PAPER_MARGIN,
-                                    offset,
-                                    offset + row_ptr->height);
-                                       
-       } 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);
-               }
-       }
-       
-       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
-                                          row_ptr->par->GetLayout());
-       firstpar = row_ptr->par->FirstPhysicalPar();
-       
-       y_top = 0;
-       y_bottom = row_ptr->height;
-       
-       /* is it a first row? */ 
-       if (row_ptr->pos == 0
-           && row_ptr->par == firstpar) {
-               
-                /* start of appendix? */
-               if (row_ptr->par->start_of_appendix){
-                 scr.drawLine(gc_math, 
-                              offset,
-                              1, paperwidth-2);
-               }
-
-               /* 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);
-                       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());
-                       
-                       y_top += 3 * DefaultHeight();
-               }
-               
-               /* think about user added space */ 
-               y_top += int(row_ptr->par->added_space_top.inPixels());
-               
-               /* think about the parskip */ 
-               /* some parskips VERY EASY IMPLEMENTATION */ 
-               if (parameters->paragraph_separation == BufferParams::PARSEP_SKIP) {
-                       if (layout.latextype == LATEX_PARAGRAPH
-                           && firstpar->GetDepth() == 0
-                           && firstpar->Previous())
-                               y_top += parameters->getDefSkip().inPixels();
-                       else if (firstpar->Previous()
-                                && 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();
-               }
-               
-               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);
-                       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
-                       || 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){
-                                               /* 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();
-                                               if (direction == LYX_DIR_RIGHT_TO_LEFT)
-                                                       tmpx = paperwidth - LeftMargin(row_ptr) - 
-                                                               font.stringWidth(tmpstring);
-                                               scr.drawString(font, tmpstring,
-                                                              offset + row_ptr->baseline
-                                                              - row_ptr->ascent_of_text - maxdesc,
-                                                              int(tmpx));
-                                       }
-                               } else {
-                                       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(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) {
-                       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()));
-                                       
-                                       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);
-
-                                       scr.drawString(font, tmpstring,
-                                                      offset + row_ptr->baseline
-                                                      - row_ptr->ascent_of_text - maxdesc,  
-                                                      int(tmpx));                  
-                               }
-                       }
-               }
-               if (layout.labeltype == LABEL_BIBLIO) { // ale970302
-                       if (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(font);
-                               else
-                                       tmpx = paperwidth - LeftMargin(row_ptr)
-                                               + font.stringWidth(layout.labelsep);
-                               row_ptr->par->bibkey->Draw(font, scr,
-                                                          offset + row_ptr->baseline, 
-                                                          tmpx);
-                       }
-               } 
-       }
-       
-       /* is it a last row? */
-       par = row_ptr->par->LastPhysicalPar();
-       if (row_ptr->par->ParFromPos(RowLast(row_ptr) + 1) == par
-           && (!row_ptr->next || row_ptr->next->par != row_ptr->par)) {     
-               
-               /* think about the margins */ 
-               if (!row_ptr->next)
-                       y_bottom -= LYX_PAPER_MARGIN;
-               
-               /* draw a bottom pagebreak */ 
-               if (firstpar->pagebreak_bottom) {
-                       scr.drawOnOffLine(offset + y_bottom - 2 *
-                                         DefaultHeight(),
-                                         0, paperwidth);
-                       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
-                               );          
-                       y_bottom -= 3* DefaultHeight();
-               }
-               
-               /* think about user added space */ 
-               y_bottom -= int(firstpar->added_space_bottom.inPixels());
-               
-               if (firstpar->line_bottom) {
-                       /* draw a bottom line */
-                       y_bottom -= GetFont(par, par->Last() - 1).ascent('x');
-
-                       scr.drawThickLine(offset + y_bottom,
-                                         0, paperwidth);           
-                       y_bottom -= GetFont(par, par->Last() - 1).ascent('x');
-               }
-       }
-       
-       /* draw the text in the pixmap */  
-       pos_end = RowLast(row_ptr);
-       
-       vpos = row_ptr->pos;
-       /* table stuff -- begin*/
-       if (row_ptr->par->table) {
-               bool on_off;
-               int cell = NumberOfCell(row_ptr->par, row_ptr->pos);
-               float x_old = x;
-               x += row_ptr->par->table->GetBeginningOfTextInCell(cell);
-               
-               while (vpos <= pos_end)  {
-                       pos = vis2log(vpos);
-                       if (row_ptr->par->IsNewline(pos)) {
-                               
-                               x = x_old + row_ptr->par->table->WidthOfColumn(cell);
-                               /* draw the table lines, still very simple */
-                               on_off = !row_ptr->par->table->TopLine(cell);
-                               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);
-                               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);
-                               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);
-                               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);
-                               x_old = x;
-                /* 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
-                               ++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);               
-                               x += 2;
-                               ++vpos;
-                       } 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) == LyXParagraph::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
-                                       Draw(row_ptr, vpos, scr, offset, x);
-                       }
-               }
-               
-               /* do not forget the very last cell. This has no NEWLINE so 
-                * ignored by the code above*/ 
-               if (cell == row_ptr->par->table->GetNumberOfCells()-1){
-                       x = x_old + row_ptr->par->table->WidthOfColumn(cell);
-                       on_off = !row_ptr->par->table->TopLine(cell);
-                       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);      
-                       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);      
-                       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);          
-                       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);          
-               }
-       } 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 (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)) {
-                                       if (pos >= main_body) {
-                                               scr.drawOnOffLine(offset + row_ptr->baseline -
-                                                                 DefaultHeight()/4,
-                                                                 int(x),
-                                                                 int(fill_hfill));                     
-                                               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);
-                               }
-                               x += 2;
-                               ++vpos;
-                       } 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) == LyXParagraph::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
-                                       Draw(row_ptr, vpos, scr, offset, x);
-                       }
-               }
-       }
-       // 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);
-                               
-                       }
-               }
-       }
-// end of FAST SELECTION code
-       /* thats it */ 
-}
-#endif
-
-int LyXText::DefaultHeight() const
-{
-       LyXFont font(LyXFont::ALL_SANE);
-       return int(font.maxAscent() + font.maxDescent() * 1.5);
-}
-
-   
-/* 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) const
-{
-       float tmpx = 0.0;
-       float fill_separator, fill_hfill, fill_label_hfill;
-   
-       PrepareToPrint(row, tmpx, fill_separator,
-                      fill_hfill, fill_label_hfill);
-
-       LyXDirection direction = row->par->getParDirection();
        LyXParagraph::size_type vc = row->pos;
-       LyXParagraph::size_type last = RowLast(row);
-       LyXParagraph::size_type c;
-
-       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
-                                          row->par->GetLayout());
+       LyXParagraph::size_type last = RowLastPrintable(row);
+       LyXParagraph::size_type c = 0;
+       LyXLayout const & layout = textclasslist.Style(buffer->params.textclass,
+                                                      row->par->GetLayout());
        /* table stuff -- begin */
        if (row->par->table) {
-               if (row->next && row->next->par == row->par //the last row doesn't need a newline at the end
+               //the last row doesn't need a newline at the end
+               if (row->next && row->next->par == row->par
                    && row->par->IsNewline(last))
                        last--;
                int cell = NumberOfCell(row->par, row->pos);
@@ -5443,22 +4405,25 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
                        last_tmpx = tmpx;
                        if (main_body > 0 && c == main_body-1) {
                                tmpx += fill_label_hfill +
-                                       GetFont(row->par, -2).stringWidth(layout.labelsep);
+                                       lyxfont::width(layout.labelsep,
+                                              GetFont(row->par, -2));
                                if (row->par->IsLineSeparator(main_body-1))
                                        tmpx -= SingleWidth(row->par, main_body-1);
                        }
             
-                       tmpx += SingleWidth(row->par, c);
                        if (HfillExpansion(row, c)) {
+                               x += SingleWidth(row->par, c);
                                if (c >= main_body)
                                        tmpx += fill_hfill;
                                else
                                        tmpx += fill_label_hfill;
                        }
-                       else if (c >= main_body
-                                && row->par->IsSeparator(c)) {
-                               tmpx+= fill_separator;  
-                       }
+                       else if (row->par->IsSeparator(c)) {
+                               tmpx += SingleWidth(row->par, c);
+                               if (c >= main_body)
+                                       tmpx+= fill_separator;
+                       } else
+                               tmpx += SingleWidth(row->par, c);
                        ++vc;
                }
 
@@ -5467,39 +4432,29 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
                        tmpx = last_tmpx;
                }
        }
-       /* make sure that a last space in a row doesnt count */
-       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 (vc > last + 1)  // This shouldn't happen.
+               vc = last+1;
 
        if (row->pos > last)  // Row is empty?
                c = row->pos;
-       else if (vc <= last) {
-               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)
+       else if (vc > last ||
+                (vc - 1 >= row->pos &&
+                 ( (row->par->IsSeparator(vis2log(vc)) && vis2log(vc) != last)
+                   || (row->par->table && row->par->IsNewline(vc) )
+                  ))) {
+               c = vis2log(vc - 1);
+               if (bidi_level(c) % 2 == 0)
                        ++c;
        } else {
-               c = vis2log(last)+1;
-               if (row->par->getLetterDirection(c - 1) == LYX_DIR_RIGHT_TO_LEFT)
-                       --c;            
+               c = vis2log(vc);
+               if (bidi_level(c) % 2 == 1)
+                       ++c;
        }
 
        if (!row->par->table && row->pos <= last && c > last
            && row->par->IsNewline(last)) {
-               if (row->par->getLetterDirection(last) == LYX_DIR_LEFT_TO_RIGHT)
+               if (bidi_level(last) % 2 == 0)
                        tmpx -= SingleWidth(row->par, last);
                else
                        tmpx += SingleWidth(row->par, last);
@@ -5614,11 +4569,17 @@ void LyXText::InsertFootnoteEnvironment(LyXParagraph::footnote_kind kind)
                || kind == LyXParagraph::WIDE_TAB
               || kind == LyXParagraph::WIDE_FIG 
                || kind == LyXParagraph::ALGORITHM) {
-                  int lay = textclasslist.NumberOfLayout(parameters->textclass,
-                                                    "Caption").second;
-                  if (lay == -1) // layout not found
-                          // use default layout "Standard" (0)
-                          lay = 0;
+                  pair<bool, LyXTextClass::size_type> lres =
+                          textclasslist.NumberOfLayout(buffer->params.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);
           }
    }
@@ -5653,58 +4614,23 @@ void LyXText::InsertFootnoteEnvironment(LyXParagraph::footnote_kind kind)
 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;
-               }
-               
-               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;
+       Row * tmprow = firstrow;
        y = 0;
+       
        // find the first row of the specified paragraph
-       while (tmprow->next && (tmprow->par != par)) {
+       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) {
+       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;
 }