]> git.lyx.org Git - lyx.git/blobdiff - src/rowpainter.cpp
fix warning on possibly(?) unused precompiled headers due to different -fPic settings...
[lyx.git] / src / rowpainter.cpp
index a949f4d4df2a9c53051787eaaf0f9eecd1b7335f..d9e41253e62d56983d1f73525f8b93d3a5699c6d 100644 (file)
@@ -67,7 +67,7 @@ class RowPainter {
 public:
        /// initialise and run painter
        RowPainter(PainterInfo & pi, Text const & text,
-               pit_type pit, Row const & row, int x, int y);
+               pit_type pit, Row const & row, Bidi & bidi, int x, int y);
 
        // paint various parts
        void paintAppendix();
@@ -114,9 +114,10 @@ private:
        ParagraphMetrics const & pm_;
        int max_width_;
 
-       /// bidi cache, static to speed up rowpaint and reduce size. 
-       /// Only one rowpainter is used at a time anyway
-       static Bidi bidi_;
+       /// bidi cache, comes from outside the rowpainter because
+       /// rowpainters are normally created in a for loop and there only
+       /// one of them is active at a time.
+       Bidi & bidi_;
 
        /// is row erased? (change tracking)
        bool erased_;
@@ -132,18 +133,15 @@ private:
 };
 
 
-Bidi RowPainter::bidi_;
-
-
 RowPainter::RowPainter(PainterInfo & pi,
-       Text const & text, pit_type pit, Row const & row, int x, int y)
+       Text const & text, pit_type pit, Row const & row, Bidi & bidi, int x, int y)
        : bv_(*pi.base.bv), pain_(pi.pain), text_(text),
          text_metrics_(pi.base.bv->textMetrics(&text)),
          pars_(text.paragraphs()),
          row_(row), pit_(pit), par_(text.paragraphs()[pit]),
          pm_(text_metrics_.parMetrics(pit)),
          max_width_(bv_.workWidth()),
-               erased_(pi.erased_),
+               bidi_(bidi), erased_(pi.erased_),
          xo_(x), yo_(y), width_(text_metrics_.width())
 {
        RowMetrics m = text_metrics_.computeRowMetrics(pit_, row_);
@@ -431,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)
@@ -472,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();
@@ -735,6 +735,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))) {
@@ -752,10 +758,21 @@ void RowPainter::paintText()
        Font font;
        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()) {
@@ -901,13 +918,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;
@@ -931,6 +956,8 @@ void paintPar
        RowList::const_iterator const rb = pm.rows().begin();
        RowList::const_iterator const re = pm.rows().end();
 
+       Bidi bidi;
+
        y -= rb->ascent();
        size_type rowno = 0;
        for (RowList::const_iterator rit = rb; rit != re; ++rit, ++rowno) {
@@ -977,11 +1004,11 @@ void paintPar
                                && y - rit->ascent() < ww);
                        // it is not needed to draw on screen if we are not inside.
                        pi.pain.setDrawingEnabled(inside);
-                       RowPainter rp(pi, text, pit, *rit, x, y);
+                       RowPainter rp(pi, text, pit, *rit, bidi, x, y);
                        // 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(),
@@ -1061,12 +1088,12 @@ void paintText(BufferView & bv,
 
        // and grey out above (should not happen later)
 //     lyxerr << "par ascent: " << text.getPar(vi.p1).ascent() << endl;
-       if (vi.y1 > 0 && vi.update_strategy != SingleParUpdate)
+       if (vi.y1 > 0 && vi.update_strategy == FullScreenUpdate)
                pain.fillRectangle(0, 0, bv.workWidth(), vi.y1, Color::bottomarea);
 
        // and possibly grey out below
 //     lyxerr << "par descent: " << text.getPar(vi.p1).ascent() << endl;
-       if (vi.y2 < bv.workHeight() && vi.update_strategy != SingleParUpdate)
+       if (vi.y2 < bv.workHeight() && vi.update_strategy == FullScreenUpdate)
                pain.fillRectangle(0, vi.y2, bv.workWidth(), bv.workHeight() - vi.y2, Color::bottomarea);
 }