]> git.lyx.org Git - lyx.git/blobdiff - src/rowpainter.C
Add GTK bibitem dialog
[lyx.git] / src / rowpainter.C
index 3f9994d10110da8f5a8915fba9c1dcd24adaa962..b992b00143a71425bccc3eff85218e728ef80add 100644 (file)
@@ -40,6 +40,8 @@
 
 #include "support/textutils.h"
 
+#include <boost/crc.hpp>
+
 using lyx::pos_type;
 using lyx::pit_type;
 
@@ -58,7 +60,7 @@ class RowPainter {
 public:
        /// initialise and run painter
        RowPainter(PainterInfo & pi, LyXText const & text,
-               pit_type pit, Row & row, int x, int y);
+               pit_type pit, Row const & row, int x, int y);
 
        // paint various parts
        void paintAppendix();
@@ -69,27 +71,21 @@ public:
        void paintText();
 
 private:
-       void paintForeignMark(double orig_x, LyXFont const & orig_font);
-       void paintHebrewComposeChar(lyx::pos_type & vpos);
-       void paintArabicComposeChar(lyx::pos_type & vpos);
-       void paintChars(lyx::pos_type & vpos, bool hebrew, bool arabic);
+       void paintForeignMark(double orig_x, LyXFont const & font);
+       void paintHebrewComposeChar(lyx::pos_type & vpos, LyXFont const & font);
+       void paintArabicComposeChar(lyx::pos_type & vpos, LyXFont const & font);
+       void paintChars(lyx::pos_type & vpos, LyXFont font, 
+                       bool hebrew, bool arabic);
        int paintAppendixStart(int y);
        void paintFromPos(lyx::pos_type & vpos);
-       void paintInset(lyx::pos_type const pos);
+       void paintInset(lyx::pos_type const pos, LyXFont const & font);
 
        /// return left margin
        int leftMargin() const;
 
-       /// return the font at the given pos
-       LyXFont const getFont(lyx::pos_type pos) const;
-
        /// return the label font for this row
        LyXFont const getLabelFont() const;
 
-       /// return pixel width for the given pos
-       int singleWidth(lyx::pos_type pos) const;
-       int singleWidth(lyx::pos_type pos, char c) const;
-
        /// bufferview to paint on
        BufferView const & bv_;
 
@@ -98,15 +94,18 @@ private:
 
        /// LyXText for the row
        LyXText const & text_;
-       ParagraphList & pars_;
+       ParagraphList const & pars_;
 
        /// The row to paint
-       Row & row_;
+       Row const & row_;
 
        /// Row's paragraph
        pit_type const pit_;
        Paragraph const & par_;
 
+       /// is row erased? (change tracking)
+       bool erased_;
+
        // Looks ugly - is
        double const xo_;
        int const yo_;    // current baseline
@@ -119,9 +118,10 @@ private:
 
 
 RowPainter::RowPainter(PainterInfo & pi,
-       LyXText const & text, pit_type pit, Row & row, int x, int y)
+       LyXText const & text, pit_type pit, Row const & row, int x, int y)
        : bv_(*pi.base.bv), pain_(pi.pain), text_(text), pars_(text.paragraphs()),
          row_(row), pit_(pit), par_(text.paragraphs()[pit]),
+         erased_(pi.erased_),
          xo_(x), yo_(y), width_(text_.width())
 {
        RowMetrics m = text_.computeRowMetrics(pit, row_);
@@ -139,26 +139,6 @@ RowPainter::RowPainter(PainterInfo & pi,
 }
 
 
-/// "temporary"
-LyXFont const RowPainter::getFont(pos_type pos) const
-{
-       return text_.getFont(par_, pos);
-}
-
-
-int RowPainter::singleWidth(lyx::pos_type pos) const
-{
-       return text_.singleWidth(par_, pos);
-}
-
-
-int RowPainter::singleWidth(lyx::pos_type pos, char c) const
-{
-       LyXFont const & font = text_.getFont(par_, pos);
-       return text_.singleWidth(par_, pos, c, font);
-}
-
-
 LyXFont const RowPainter::getLabelFont() const
 {
        return text_.getLabelFont(par_);
@@ -171,21 +151,26 @@ int RowPainter::leftMargin() const
 }
 
 
-void RowPainter::paintInset(pos_type const pos)
+void RowPainter::paintInset(pos_type const pos, LyXFont const & font)
 {
        InsetBase const * inset = par_.getInset(pos);
        BOOST_ASSERT(inset);
        PainterInfo pi(const_cast<BufferView *>(&bv_), pain_);
-       pi.base.font = getFont(pos);
+       // FIXME: We should always use font, see documentation of
+       // noFontChange() in insetbase.h.
+       pi.base.font = inset->noFontChange() ?
+               bv_.buffer()->params().getLyXTextClass().defaultfont() :
+               font;
        pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0);
-       theCoords.insets_.add(inset, int(x_), yo_);
+       pi.erased_ = erased_ || isDeletedText(par_, pos);
+       theCoords.insets().add(inset, int(x_), yo_);
        inset->drawSelection(pi, int(x_), yo_);
        inset->draw(pi, int(x_), yo_);
        x_ += inset->width();
 }
 
 
-void RowPainter::paintHebrewComposeChar(pos_type & vpos)
+void RowPainter::paintHebrewComposeChar(pos_type & vpos, LyXFont const & font)
 {
        pos_type pos = text_.bidi.vis2log(vpos);
 
@@ -196,7 +181,6 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos)
        str += c;
        ++vpos;
 
-       LyXFont const & font = getFont(pos);
        int const width = font_metrics::width(c, font);
        int dx = 0;
 
@@ -204,7 +188,8 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos)
                c = par_.getChar(i);
                if (!Encodings::IsComposeChar_hebrew(c)) {
                        if (IsPrintableNonspace(c)) {
-                               int const width2 = singleWidth(i, c);
+                               int const width2 =
+                                       text_.singleWidth(par_, i, c, text_.getFont(par_, i));
                                // dalet / resh
                                dx = (c == 'ø' || c == 'ã')
                                        ? width2 - width
@@ -219,7 +204,7 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos)
 }
 
 
-void RowPainter::paintArabicComposeChar(pos_type & vpos)
+void RowPainter::paintArabicComposeChar(pos_type & vpos, LyXFont const & font)
 {
        pos_type pos = text_.bidi.vis2log(vpos);
        string str;
@@ -230,7 +215,6 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos)
        str += c;
        ++vpos;
 
-       LyXFont const & font = getFont(pos);
        int const width = font_metrics::width(c, font);
        int dx = 0;
 
@@ -238,7 +222,8 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos)
                c = par_.getChar(i);
                if (!Encodings::IsComposeChar_arabic(c)) {
                        if (IsPrintableNonspace(c)) {
-                               int const width2 = singleWidth(i, c);
+                               int const width2 = 
+                                       text_.singleWidth(par_, i, c, text_.getFont(par_, i));
                                dx = (width2 - width) / 2;
                        }
                        break;
@@ -249,11 +234,13 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos)
 }
 
 
-void RowPainter::paintChars(pos_type & vpos, bool hebrew, bool arabic)
+void RowPainter::paintChars(pos_type & vpos, LyXFont font, 
+                           bool hebrew, bool arabic)
 {
        pos_type pos = text_.bidi.vis2log(vpos);
        pos_type const end = row_.endpos();
-       LyXFont orig_font = getFont(pos);
+       FontSpan const font_span = par_.fontSpan(pos);
+       Change::Type const prev_change = par_.lookupChange(pos);
 
        // first character
        string str;
@@ -263,20 +250,18 @@ void RowPainter::paintChars(pos_type & vpos, bool hebrew, bool arabic)
                str[0] = par_.transformChar(c, pos);
        }
 
-       bool prev_struckout = isDeletedText(par_, pos);
-       bool prev_newtext = isInsertedText(par_, pos);
-
        // collect as much similar chars as we can
-       for (++vpos; vpos < end && (pos = text_.bidi.vis2log(vpos)) >= 0; ++vpos) {
-               char c = par_.getChar(pos);
-
-               if (!IsPrintableNonspace(c))
+       for (++vpos ; vpos < end ; ++vpos) {
+               pos = text_.bidi.vis2log(vpos);
+               if (pos < font_span.first || pos > font_span.last)
                        break;
 
-               if (prev_struckout != isDeletedText(par_, pos))
+               if (prev_change != par_.lookupChange(pos))
                        break;
 
-               if (prev_newtext != isInsertedText(par_, pos))
+               char c = par_.getChar(pos);
+
+               if (!IsPrintableNonspace(c))
                        break;
 
                if (arabic && Encodings::IsComposeChar_arabic(c))
@@ -285,34 +270,31 @@ void RowPainter::paintChars(pos_type & vpos, bool hebrew, bool arabic)
                if (hebrew && Encodings::IsComposeChar_hebrew(c))
                        break;
 
-               if (orig_font != getFont(pos))
-                       break;
-
                if (arabic)
                        c = par_.transformChar(c, pos);
 
                str += c;
        }
 
-       if (prev_struckout)
-               orig_font.setColor(LColor::strikeout);
-       else if (prev_newtext)
-               orig_font.setColor(LColor::newtext);
+       if (prev_change == Change::DELETED)
+               font.setColor(LColor::strikeout);
+       else if (prev_change == Change::INSERTED)
+               font.setColor(LColor::newtext);
 
        // Draw text and set the new x position
        //lyxerr << "paint row: yo_ " << yo_ << "\n";
-       pain_.text(int(x_), yo_, str, orig_font);
-       x_ += font_metrics::width(str, orig_font);
+       pain_.text(int(x_), yo_, str, font);
+       x_ += font_metrics::width(str, font);
 }
 
 
-void RowPainter::paintForeignMark(double orig_x, LyXFont const & orig_font)
+void RowPainter::paintForeignMark(double orig_x, LyXFont const & font)
 {
        if (!lyxrc.mark_foreign_language)
                return;
-       if (orig_font.language() == latex_language)
+       if (font.language() == latex_language)
                return;
-       if (orig_font.language() == bv_.buffer()->params().language)
+       if (font.language() == bv_.buffer()->params().language)
                return;
 
        int const y = yo_ + 1;
@@ -323,26 +305,25 @@ void RowPainter::paintForeignMark(double orig_x, LyXFont const & orig_font)
 void RowPainter::paintFromPos(pos_type & vpos)
 {
        pos_type const pos = text_.bidi.vis2log(vpos);
-
-       LyXFont const & orig_font = getFont(pos);
+       LyXFont orig_font = text_.getFont(par_, pos);
+       text_.applyOuterFont(orig_font);
 
        double const orig_x = x_;
 
-       char const c = par_.getChar(pos);
-
-       if (c == Paragraph::META_INSET) {
-               paintInset(pos);
+       if (par_.isInset(pos)) {
+               paintInset(pos, orig_font);
                ++vpos;
                paintForeignMark(orig_x, orig_font);
                return;
        }
 
        // usual characters, no insets
+       char const c = par_.getChar(pos);
 
        // special case languages
-       bool const hebrew = (orig_font.language()->lang() == "hebrew");
-       bool const arabic =
-               orig_font.language()->lang() == "arabic" &&
+       std::string const & lang = orig_font.language()->lang();
+       bool const hebrew = lang == "hebrew";
+       bool const arabic = lang == "arabic" &&
                (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 ||
                lyxrc.font_norm_type == LyXRC::ISO_10646_1);
 
@@ -350,11 +331,11 @@ void RowPainter::paintFromPos(pos_type & vpos)
        if ((!hebrew && !arabic)
                || (hebrew && !Encodings::IsComposeChar_hebrew(c))
                || (arabic && !Encodings::IsComposeChar_arabic(c))) {
-               paintChars(vpos, hebrew, arabic);
+               paintChars(vpos, orig_font, hebrew, arabic);
        } else if (hebrew) {
-               paintHebrewComposeChar(vpos);
+               paintHebrewComposeChar(vpos, orig_font);
        } else if (arabic) {
-               paintArabicComposeChar(vpos);
+               paintArabicComposeChar(vpos, orig_font);
        }
 
        paintForeignMark(orig_x, orig_font);
@@ -467,7 +448,7 @@ void RowPainter::paintFirst()
 
        // start of appendix?
        if (parparams.startOfAppendix())
-               y_top += paintAppendixStart(yo_ + y_top + 2 * defaultRowHeight());
+               y_top += paintAppendixStart(yo_ - row_.ascent() + 2 * defaultRowHeight());
 
        Buffer const & buffer = *bv_.buffer();
 
@@ -499,35 +480,33 @@ void RowPainter::paintFirst()
                      || layout->latextype != LATEX_ENVIRONMENT
                      || is_seq)) {
 
-               LyXFont font = getLabelFont();
-               if (!par_.getLabelstring().empty()) {
+               LyXFont const font = getLabelFont();
+               string const str = par_.getLabelstring();
+               if (!str.empty()) {
                        double x = x_;
-                       string const str = par_.getLabelstring();
 
                        // this is special code for the chapter layout. This is
                        // printed in an extra row and has a pagebreak at
                        // the top.
                        if (layout->counter == "chapter") {
-                               if (buffer.params().secnumdepth >= 0) {
-                                       double spacing_val = 1.0;
-                                       if (!parparams.spacing().isDefault()) {
-                                               spacing_val = parparams.spacing().getValue();
-                                       } else {
-                                               spacing_val = buffer.params().spacing().getValue();
-                                       }
-#warning Look is this correct?                                 
-                                       int const labeladdon = int(font_metrics::maxHeight(font) * layout->spacing.getValue() * spacing_val);
-
-                                       int const maxdesc = int(font_metrics::maxDescent(font) * layout->spacing.getValue() * spacing_val)
-                                               + int(layout->parsep) * defaultRowHeight();
-
-                                       if (is_rtl) {
-                                               x = width_ - leftMargin() -
-                                                       font_metrics::width(str, font);
-                                       }
-
-                                       pain_.text(int(x), yo_ - maxdesc - labeladdon, str, font);
+                               double spacing_val = 1.0;
+                               if (!parparams.spacing().isDefault()) {
+                                       spacing_val = parparams.spacing().getValue();
+                               } else {
+                                       spacing_val = buffer.params().spacing().getValue();
                                }
+
+                               int const labeladdon = int(font_metrics::maxHeight(font) * layout->spacing.getValue() * spacing_val);
+
+                               int const maxdesc = int(font_metrics::maxDescent(font) * layout->spacing.getValue() * spacing_val)
+                                       + int(layout->parsep) * defaultRowHeight();
+
+                               if (is_rtl) {
+                                       x = width_ - leftMargin() -
+                                               font_metrics::width(str, font);
+                               }
+
+                               pain_.text(int(x), yo_ - maxdesc - labeladdon, str, font);
                        } else {
                                if (is_rtl) {
                                        x = width_ - leftMargin()
@@ -551,11 +530,12 @@ void RowPainter::paintFirst()
                if (!par_.getLabelstring().empty()) {
                        string const str = par_.getLabelstring();
                        double spacing_val = 1.0;
-                       if (!parparams.spacing().isDefault()) {
+                       if (!parparams.spacing().isDefault())
                                spacing_val = parparams.spacing().getValue();
-                       } else {
+                       else
                                spacing_val = buffer.params().spacing().getValue();
-                       }
+
+                       int const labeladdon = int(font_metrics::maxHeight(font) * layout->spacing.getValue() * spacing_val);
 
                        int maxdesc =
                                int(font_metrics::maxDescent(font) * layout->spacing.getValue() * spacing_val
@@ -563,14 +543,15 @@ void RowPainter::paintFirst()
 
                        double x = x_;
                        if (layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) {
-                               x = ((is_rtl ? leftMargin() : x_)
-                                        + width_ - text_.rightMargin(par_)) / 2;
+                               if (is_rtl)
+                                       x = leftMargin();
+                               x += (width_ - text_.rightMargin(par_) - leftMargin()) / 2;
                                x -= font_metrics::width(str, font) / 2;
                        } else if (is_rtl) {
                                x = width_ - leftMargin() -
                                        font_metrics::width(str, font);
                        }
-                       pain_.text(int(x), yo_ - maxdesc, str, font);
+                       pain_.text(int(x), yo_ - maxdesc - labeladdon, str, font);
                }
        }
 }
@@ -631,6 +612,10 @@ void RowPainter::paintText()
        bool is_struckout = false;
        int last_strikeout_x = 0;
 
+       // Use font span to speed things up, see below 
+       FontSpan font_span;
+       LyXFont font;
+
        for (pos_type vpos = row_.pos(); vpos < end; ) {
                if (x_ > bv_.workWidth())
                        break;
@@ -642,7 +627,15 @@ void RowPainter::paintText()
                        continue;
                }
 
-               const int width_pos = singleWidth(pos);
+               // Use font span to speed things up, see above
+               if (vpos < font_span.first || vpos > font_span.last) {
+                       font_span = par_.fontSpan(vpos);
+                       font = text_.getFont(par_, vpos);
+               }
+
+               const int width_pos =
+                       text_.singleWidth(par_, pos, par_.getChar(pos), font);
+
                if (x_ + width_pos < 0) {
                        x_ += width_pos;
                        ++vpos;
@@ -659,13 +652,12 @@ void RowPainter::paintText()
                bool const highly_editable_inset = par_.isInset(pos)
                        && isHighlyEditableInset(par_.getInset(pos));
 
-               // if we reach the end of a struck out range, paint it
-               // we also don't paint across things like tables
+               // If we reach the end of a struck out range, paint it.
+               // We also don't paint across things like tables
                if (running_strikeout && (highly_editable_inset || !is_struckout)) {
-                       // FIXME this should take real text height into account, not 
-                       // the whole row including padding whitespace
-                       //int const middle = yo_ + (- row_.ascent() + row_.top_of_text()) / 2;
-                       int const middle = yo_ - row_.ascent() / 2;
+                       // Calculate 1/3 height of the buffer's default font
+                       int const middle =
+                               yo_ - font_metrics::maxAscent(text_.defaultfont_) / 3;
                        pain_.line(last_strikeout_x, middle, int(x_), middle,
                                LColor::strikeout, Painter::line_solid, Painter::line_thin);
                        running_strikeout = false;
@@ -716,9 +708,9 @@ void RowPainter::paintText()
 
        // if we reach the end of a struck out range, paint it
        if (running_strikeout) {
-               //top_of_text = font_metrics::maxAscent(font);
-               //int const middle = yo_ - top_of_text() / 2;
-               int const middle = yo_ - row_.ascent() / 2;
+               // calculate 1/3 height of the buffer's default font
+               int const middle =
+                       yo_ - font_metrics::maxAscent(text_.defaultfont_) / 3;
                pain_.line(last_strikeout_x, middle, int(x_), middle,
                        LColor::strikeout, Painter::line_solid, Painter::line_thin);
                running_strikeout = false;
@@ -726,37 +718,88 @@ void RowPainter::paintText()
 }
 
 
+lyx::size_type calculateRowSignature(Row const & row, Paragraph const & par)
+{
+       boost::crc_32_type crc;
+       for (lyx::pos_type i = row.pos(); i < row.endpos(); ++i) {
+               const unsigned char b[] = { par.getChar(i) };
+               crc.process_bytes(b, 1);
+       }
+       return crc.checksum();
+}
+
+
+bool isCursorOnRow(PainterInfo & pi, pit_type pit, RowList::const_iterator rit)
+{
+       LCursor & cur = pi.base.bv->cursor();
+       for (lyx::size_type d = 0; d < cur.depth(); d++)
+               if (cur[d].pit() == pit
+                   && cur[d].pos() >= rit->pos()
+                   && cur[d].pos() <= rit->endpos())
+                       return true;
+       return false;
+}
+
+
 void paintPar
-       (PainterInfo & pi, LyXText const & text, pit_type pit, int x, int y)
+       (PainterInfo & pi, LyXText const & text, pit_type pit, int x, int y,
+        bool repaintAll)
 {
 //     lyxerr << "  paintPar: pit: " << pit << " at y: " << y << endl;
        static NullPainter nop;
        static PainterInfo nullpi(pi.base.bv, nop);
        int const ww = pi.base.bv->workHeight();
-       
-       Paragraph & par = text.paragraphs()[pit];
 
-       RowList::iterator const rb = par.rows().begin();
-       RowList::iterator const re = par.rows().end();
-       theCoords.pars_[&text][pit] = Point(x, y);
+       Paragraph const & par = text.paragraphs()[pit];
+
+       RowList::const_iterator const rb = par.rows().begin();
+       RowList::const_iterator const re = par.rows().end();
+       theCoords.parPos()[&text][pit] = Point(x, y);
 
        y -= rb->ascent();
-       for (RowList::iterator rit = rb; rit != re; ++rit) {
+       lyx::size_type rowno(0);
+       for (RowList::const_iterator rit = rb; rit != re; ++rit, ++rowno) {
                y += rit->ascent();
-               bool const inside = (y + rit->descent() >= 0
+
+               // Row signature; has row changed since last paint?
+               lyx::size_type const row_sig = calculateRowSignature(*rit, par);
+
+               bool cursor_on_row = isCursorOnRow(pi, pit, rit);
+               
+               // If selection is on, the current row signature differs from
+               // from cache, or cursor is inside an inset _on this row_, 
+               // then paint the row
+               if (repaintAll || par.rowSignature()[rowno] != row_sig
+                           || cursor_on_row) {
+                       // Add to row signature cache
+                       par.rowSignature()[rowno] = row_sig;
+
+                       bool const inside = (y + rit->descent() >= 0
                                       && y - rit->ascent() < ww);
-               RowPainter rp(inside ? pi : nullpi, text, pit, *rit, x, y);
+                       RowPainter rp(inside ? pi : nullpi, text, pit, *rit, x, y);
+                       // Clear background of this row 
+                       // (if paragraph background was not cleared)
+                       if (!repaintAll) {
+                               pi.pain.fillRectangle(x, y - rit->ascent(), 
+                                   pi.base.bv->workWidth(), rit->height(),
+                                   text.backgroundColor());
+                       }
                        
+                       // Instrumentation for testing row cache (see also
+                       // 12 lines lower):
+                       //lyxerr << "#";
+                       rp.paintAppendix();
+                       rp.paintDepthBar();
+                       rp.paintChangeBar();
+                       if (rit == rb)
+                               rp.paintFirst();
+                       if (rit + 1 == re)
+                               rp.paintLast();
+                       rp.paintText();
+               }
                y += rit->descent();
-               rp.paintAppendix();
-               rp.paintDepthBar();
-               rp.paintChangeBar();
-               if (rit == rb)
-                       rp.paintFirst();
-               if (rit + 1 == re)
-                       rp.paintLast();
-               rp.paintText();
        }
+       //lyxerr << "." << endl;
 }
 
 } // namespace anon
@@ -766,46 +809,51 @@ void paintText(BufferView const & bv, ViewMetricsInfo const & vi)
 {
        Painter & pain = bv.painter();
        LyXText * const text = bv.text();
+       bool const select = bv.cursor().selection();
 
-       // clear background
-       pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1,
-                          LColor::background);
-
-       // draw selection
        PainterInfo pi(const_cast<BufferView *>(&bv), pain);
-
-       text->drawSelection(pi, 0, 0);
+       if (select || !vi.singlepar) {
+               // Clear background (Delegated to rows if no selection)
+               pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1,
+                       text->backgroundColor());
+       }
+       if (select) {
+               text->drawSelection(pi, 0, 0);
+       }
 
        int yy = vi.y1;
        // draw contents
        for (pit_type pit = vi.p1; pit <= vi.p2; ++pit) {
-               yy += text->getPar(pit).ascent();
-               paintPar(pi, *bv.text(), pit, 0, yy);
-               yy += text->getPar(pit).descent();
+               Paragraph const & par = text->getPar(pit);
+               yy += par.ascent();
+               paintPar(pi, *bv.text(), pit, 0, yy, select || !vi.singlepar);
+               yy += par.descent();
        }
-       
 
-       // paint one paragraph above and one below
+       // Cache one paragraph above and one below
+       // Note MV: this cannot be suppressed even for singlepar.
+       // Try viewing the User Guide Mobius figure
+
        if (vi.p1 > 0) {
                text->redoParagraph(vi.p1 - 1);
-               paintPar(pi, *bv.text(), vi.p1 - 1, 0,
-                        vi.y1 -  text->getPar(vi.p1 - 1).descent());
+               theCoords.parPos()[bv.text()][vi.p1 - 1] = 
+                       Point(0, vi.y1 - text->getPar(vi.p1 - 1).descent());
        }
 
-       if (vi.p2 < text->paragraphs().size() - 1) {
+       if (vi.p2 < lyx::pit_type(text->paragraphs().size()) - 1) {
                text->redoParagraph(vi.p2 + 1);
-               paintPar(pi, *bv.text(), vi.p2 + 1, 0,
-                        vi.y2 + text->getPar(vi.p2 + 1).ascent());
+               theCoords.parPos()[bv.text()][vi.p2 + 1] = 
+                       Point(0, vi.y2 + text->getPar(vi.p2 + 1).ascent());
        }
 
        // and grey out above (should not happen later)
-       lyxerr << "par ascent: " << text->getPar(vi.p1).ascent() << endl;
-       if (vi.y1 > 0)
+//     lyxerr << "par ascent: " << text->getPar(vi.p1).ascent() << endl;
+       if (vi.y1 > 0 && !vi.singlepar)
                pain.fillRectangle(0, 0, bv.workWidth(), vi.y1, LColor::bottomarea);
 
        // and possibly grey out below
-       lyxerr << "par descent: " << text->getPar(vi.p1).ascent() << endl;
-       if (vi.y2 < bv.workHeight())
+//     lyxerr << "par descent: " << text->getPar(vi.p1).ascent() << endl;
+       if (vi.y2 < bv.workHeight() && !vi.singlepar)
                pain.fillRectangle(0, vi.y2, bv.workWidth(), bv.workHeight() - vi.y2, LColor::bottomarea);
 }
 
@@ -817,7 +865,7 @@ void paintTextInset(LyXText const & text, PainterInfo & pi, int x, int y)
        y -= text.getPar(0).ascent();
        for (int pit = 0; pit < int(text.paragraphs().size()); ++pit) {
                y += text.getPar(pit).ascent();
-               paintPar(pi, text, pit, x, y);
+               paintPar(pi, text, pit, x, y, true);
                y += text.getPar(pit).descent();
        }
 }