]> git.lyx.org Git - lyx.git/blobdiff - src/rowpainter.cpp
SCons: msvc does not need this /TP option any more after we rename .C => .cpp. Also...
[lyx.git] / src / rowpainter.cpp
index 748658f093d83381622ce2c3e29aa9c80e89d902..ca3a07ef4bd05560a41f902f41ce0f22d6a23b98 100644 (file)
@@ -145,7 +145,7 @@ RowPainter::RowPainter(PainterInfo & pi,
          xo_(x), yo_(y), width_(text_metrics_.width())
 {
        RowMetrics m = text_metrics_.computeRowMetrics(pit_, row_);
-       bidi_.computeTables(par_, *bv_.buffer(), row_);
+       bidi_.computeTables(par_, bv_.buffer(), row_);
        x_ = m.x + xo_;
 
        //lyxerr << "RowPainter: x: " << x_ << " xo: " << xo_ << " yo: " << yo_ << endl;
@@ -162,13 +162,13 @@ RowPainter::RowPainter(PainterInfo & pi,
 
 Font const RowPainter::getLabelFont() const
 {
-       return text_.getLabelFont(*bv_.buffer(), par_);
+       return text_.getLabelFont(bv_.buffer(), par_);
 }
 
 
 int RowPainter::leftMargin() const
 {
-       return text_.leftMargin(*bv_.buffer(), max_width_, pit_, row_.pos());
+       return text_.leftMargin(bv_.buffer(), max_width_, pit_, row_.pos());
 }
 
 
@@ -185,7 +185,7 @@ void RowPainter::paintInset(pos_type const pos, Font const & font)
        // FIXME: We should always use font, see documentation of
        // noFontChange() in Inset.h.
        pi.base.font = inset->noFontChange() ?
-               bv_.buffer()->params().getFont() :
+               bv_.buffer().params().getFont() :
                font;
        pi.ltr_pos = (bidi_.level(pos) % 2 == 0);
        pi.erased_ = erased_ || par_.isDeleted(pos);
@@ -256,8 +256,8 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos, Font const & font)
                c = par_.getChar(i);
                if (!Encodings::isComposeChar_hebrew(c)) {
                        if (isPrintableNonspace(c)) {
-                               int const width2 = text_.singleWidth(par_, i, c,
-                                       text_.getFont(*bv_.buffer(), par_, i));
+                               int const width2 = pm_.singleWidth(i,
+                                       text_.getFont(bv_.buffer(), par_, i));
                                dx = (c == 0x05e8 || // resh
                                      c == 0x05d3)   // dalet
                                        ? width2 - width
@@ -290,8 +290,8 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos, Font const & font)
                c = par_.getChar(i);
                if (!Encodings::isComposeChar_arabic(c)) {
                        if (isPrintableNonspace(c)) {
-                               int const width2 = text_.singleWidth(par_, i, c,
-                                               text_.getFont(*bv_.buffer(), par_, i));
+                               int const width2 = pm_.singleWidth(i,
+                                               text_.getFont(bv_.buffer(), par_, i));
                                dx = (width2 - width) / 2;
                        }
                        break;
@@ -400,7 +400,7 @@ void RowPainter::paintForeignMark(double orig_x, Font const & font, int desc)
                return;
        if (font.language() == latex_language)
                return;
-       if (font.language() == bv_.buffer()->params().language)
+       if (font.language() == bv_.buffer().params().language)
                return;
 
        int const y = yo_ + 1 + desc;
@@ -411,7 +411,7 @@ void RowPainter::paintForeignMark(double orig_x, Font const & font, int desc)
 void RowPainter::paintFromPos(pos_type & vpos)
 {
        pos_type const pos = bidi_.vis2log(vpos);
-       Font orig_font = text_.getFont(*bv_.buffer(), par_, pos);
+       Font orig_font = text_.getFont(bv_.buffer(), par_, pos);
 
        double const orig_x = x_;
 
@@ -429,7 +429,8 @@ void RowPainter::paintFromPos(pos_type & vpos)
        // special case languages
        std::string const & lang = orig_font.language()->lang();
        bool const hebrew = lang == "hebrew";
-       bool const arabic = lang == "arabic" || lang == "farsi";        
+       bool const arabic = lang == "arabic_arabtex" || lang == "arabic_arabi" || 
+                                               lang == "farsi";
 
        // draw as many chars as we can
        if ((!hebrew && !arabic)
@@ -470,7 +471,8 @@ void RowPainter::paintChangeBar()
 
 void RowPainter::paintAppendix()
 {
-       if (!par_.params().appendix())
+       // only draw the appendix frame once (for the main text)
+       if (!par_.params().appendix() || !text_.isMainText(bv_.buffer()))
                return;
 
        int y = yo_ - row_.ascent();
@@ -510,7 +512,7 @@ void RowPainter::paintDepthBar()
                int const w = nestMargin() / 5;
                int x = int(xo_) + w * i;
                // only consider the changebar space if we're drawing outermost text
-               if (text_.isMainText(*bv_.buffer()))
+               if (text_.isMainText(bv_.buffer()))
                        x += changebarMargin();
 
                int const starty = yo_ - row_.ascent();
@@ -561,7 +563,7 @@ void RowPainter::paintFirst()
        if (parparams.startOfAppendix())
                y_top += paintAppendixStart(yo_ - row_.ascent() + 2 * defaultRowHeight());
 
-       Buffer const & buffer = *bv_.buffer();
+       Buffer const & buffer = bv_.buffer();
 
        Layout_ptr const & layout = par_.layout();
 
@@ -621,13 +623,11 @@ void RowPainter::paintFirst()
 
                                pain_.text(int(x), yo_ - maxdesc - labeladdon, str, font);
                        } else {
-                               // FIXME UNICODE
-                               docstring lab = from_utf8(layout->labelsep);
                                if (is_rtl) {
                                        x = width_ - leftMargin()
-                                               + fm.width(lab);
+                                               + fm.width(layout->labelsep);
                                } else {
-                                       x = x_ - fm.width(lab)
+                                       x = x_ - fm.width(layout->labelsep)
                                                - fm.width(str);
                                }
 
@@ -676,13 +676,13 @@ void RowPainter::paintFirst()
 
 void RowPainter::paintLast()
 {
-       bool const is_rtl = text_.isRTL(*bv_.buffer(), par_);
+       bool const is_rtl = text_.isRTL(bv_.buffer(), par_);
        int const endlabel = getEndLabel(pit_, text_.paragraphs());
 
        // paint imaginary end-of-paragraph character
 
        if (par_.isInserted(par_.size()) || par_.isDeleted(par_.size())) {
-               FontMetrics const & fm = theFontMetrics(bv_.buffer()->params().getFont());
+               FontMetrics const & fm = theFontMetrics(bv_.buffer().params().getFont());
                int const length = fm.maxAscent() / 2;
                Color::color col = par_.isInserted(par_.size()) ? Color::addedtext : Color::deletedtext;
 
@@ -733,6 +733,12 @@ void RowPainter::paintLast()
 void RowPainter::paintText()
 {
        pos_type const end = row_.endpos();
+       // Spaces at logical line breaks in bidi text must be skipped during 
+       // painting. However, they may appear visually in the middle
+       // of a row; they must be skipped, wherever they are...
+       // * logically "abc_[HEBREW_\nHEBREW]"
+       // * visually "abc_[_WERBEH\nWERBEH]"
+       pos_type skipped_sep_vpos = -1;
        pos_type body_pos = par_.beginOfBody();
        if (body_pos > 0 &&
                (body_pos > end || !par_.isLineSeparator(body_pos - 1))) {
@@ -748,12 +754,23 @@ void RowPainter::paintText()
        // Use font span to speed things up, see below
        FontSpan font_span;
        Font font;
-       Buffer const & buffer = *bv_.buffer();
+       Buffer const & buffer = bv_.buffer();
 
+       // If the last logical character is a separator, don't paint it, unless
+       // it's in the last row of a paragraph; see skipped_sep_vpos declaration
+       if (end > 0 && end < par_.size() && par_.isSeparator(end - 1))
+               skipped_sep_vpos = bidi_.log2vis(end - 1);
+       
        for (pos_type vpos = row_.pos(); vpos < end; ) {
                if (x_ > bv_.workWidth())
                        break;
 
+               // Skip the separator at the logical end of the row
+               if (vpos == skipped_sep_vpos) {
+                       ++vpos;
+                       continue;
+               }
+
                pos_type const pos = bidi_.vis2log(vpos);
 
                if (pos >= par_.size()) {
@@ -767,8 +784,7 @@ void RowPainter::paintText()
                        font = text_.getFont(buffer, par_, vpos);
                }
 
-               const int width_pos =
-                       text_.singleWidth(par_, pos, par_.getChar(pos), font);
+               const int width_pos = pm_.singleWidth(pos, font);
 
                if (x_ + width_pos < 0) {
                        x_ += width_pos;
@@ -791,7 +807,7 @@ void RowPainter::paintText()
                if (running_strikeout && (highly_editable_inset || !is_struckout)) {
                        // Calculate 1/3 height of the buffer's default font
                        FontMetrics const & fm
-                               = theFontMetrics(bv_.buffer()->params().getFont());
+                               = theFontMetrics(bv_.buffer().params().getFont());
                        int const middle = yo_ - fm.maxAscent() / 3;
                        pain_.line(last_strikeout_x, middle, int(x_), middle,
                                Color::deletedtext, Painter::line_solid, Painter::line_thin);
@@ -799,9 +815,8 @@ void RowPainter::paintText()
                }
 
                if (body_pos > 0 && pos == body_pos - 1) {
-                       // FIXME UNICODE
                        int const lwidth = theFontMetrics(getLabelFont())
-                               .width(from_utf8(layout->labelsep));
+                               .width(layout->labelsep);
 
                        x_ += label_hfill_ + lwidth - width_pos;
                }
@@ -833,7 +848,7 @@ void RowPainter::paintText()
                        x_ += 2;
                        ++vpos;
                } else if (par_.isSeparator(pos)) {
-                       Font orig_font = text_.getFont(*bv_.buffer(), par_, pos);
+                       Font orig_font = text_.getFont(bv_.buffer(), par_, pos);
                        double const orig_x = x_;
                        x_ += width_pos;
                        if (pos >= body_pos)
@@ -849,7 +864,7 @@ void RowPainter::paintText()
        if (running_strikeout) {
                // calculate 1/3 height of the buffer's default font
                FontMetrics const & fm
-                       = theFontMetrics(bv_.buffer()->params().getFont());
+                       = theFontMetrics(bv_.buffer().params().getFont());
                int const middle = yo_ - fm.maxAscent() / 3;
                pain_.line(last_strikeout_x, middle, int(x_), middle,
                        Color::deletedtext, Painter::line_solid, Painter::line_thin);
@@ -899,13 +914,21 @@ bool inNarrowInset(PainterInfo & pi)
 {
        // check whether the current inset is nested in a non-wide inset
        Cursor & cur = pi.base.bv->cursor();
-       for (int i = cur.depth() - 1; --i >= 0; ) {
+       Inset const * cur_in = &cur.inset();
+       // check all higher nested insets
+       for (size_type i = 1; i < cur.depth(); ++i) {
                Inset * const in = &cur[i].inset();
-               if (in) {
+               if (in == cur_in)
+                       // we reached the level of the current inset, so stop
+                       return false;
+               else if (in) {
+                       if (in->hasFixedWidth())
+                               return true;
                        InsetText * t =
                                const_cast<InsetText *>(in->asTextInset());
-                       if (t)
-                               return !t->wide();
+                       if (t && !t->wide())
+                               // OK, we are in a non-wide() inset
+                               return true;
                }
        }
        return false;
@@ -981,7 +1004,7 @@ void paintPar
                        // Clear background of this row
                        // (if paragraph background was not cleared)
                        if (!repaintAll &&
-                           (!(in_inset_alone_on_row && leftEdgeFixed)
+                           (!(in_inset_alone_on_row && leftEdgeFixed && !inNarrowIns)
                                || row_has_changed)) {
                                pi.pain.fillRectangle(x, y - rit->ascent(),
                                    rp.maxWidth(), rit->height(),
@@ -995,7 +1018,7 @@ void paintPar
                        // Instrumentation for testing row cache (see also
                        // 12 lines lower):
                        if (lyxerr.debugging(Debug::PAINTING)) {
-                               if (text.isMainText(*pi.base.bv->buffer()))
+                               if (text.isMainText(pi.base.bv->buffer()))
                                        LYXERR(Debug::PAINTING) << "#";
                                else
                                        LYXERR(Debug::PAINTING) << "[" <<
@@ -1027,8 +1050,7 @@ void paintPar
 void paintText(BufferView & bv,
               Painter & pain)
 {
-       BOOST_ASSERT(bv.buffer());
-       Buffer const & buffer = *bv.buffer();
+       Buffer const & buffer = bv.buffer();
        Text & text = buffer.text();
        bool const select = bv.cursor().selection();
        ViewMetricsInfo const & vi = bv.viewMetricsInfo();