]> git.lyx.org Git - lyx.git/blobdiff - src/rowpainter.cpp
Possibly fix this bug:
[lyx.git] / src / rowpainter.cpp
index 5f0f6c53306b793f3aac67cb71227d99c3e131eb..e3dfefba8f9acd60db54af12817cf2100183e8f5 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "rowpainter.h"
 
+#include "Bidi.h"
 #include "Buffer.h"
 #include "CoordCache.h"
 #include "Cursor.h"
@@ -66,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();
@@ -113,6 +114,11 @@ private:
        ParagraphMetrics const & pm_;
        int max_width_;
 
+       /// 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_;
 
@@ -128,17 +134,18 @@ private:
 
 
 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_);
+       bidi_.computeTables(par_, *bv_.buffer(), row_);
        x_ = m.x + xo_;
 
        //lyxerr << "RowPainter: x: " << x_ << " xo: " << xo_ << " yo: " << yo_ << endl;
@@ -180,7 +187,7 @@ void RowPainter::paintInset(pos_type const pos, Font const & font)
        pi.base.font = inset->noFontChange() ?
                bv_.buffer()->params().getFont() :
                font;
-       pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0);
+       pi.ltr_pos = (bidi_.level(pos) % 2 == 0);
        pi.erased_ = erased_ || par_.isDeleted(pos);
 #ifdef DEBUG_METRICS
        int const x1 = int(x_);
@@ -233,7 +240,7 @@ void RowPainter::paintInset(pos_type const pos, Font const & font)
 
 void RowPainter::paintHebrewComposeChar(pos_type & vpos, Font const & font)
 {
-       pos_type pos = text_.bidi.vis2log(vpos);
+       pos_type pos = bidi_.vis2log(vpos);
 
        docstring str;
 
@@ -267,7 +274,7 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos, Font const & font)
 
 void RowPainter::paintArabicComposeChar(pos_type & vpos, Font const & font)
 {
-       pos_type pos = text_.bidi.vis2log(vpos);
+       pos_type pos = bidi_.vis2log(vpos);
        docstring str;
 
        // first char
@@ -299,7 +306,7 @@ void RowPainter::paintChars(pos_type & vpos, Font const & font,
                            bool hebrew, bool arabic)
 {
        // This method takes up 70% of time when typing
-       pos_type pos = text_.bidi.vis2log(vpos);
+       pos_type pos = bidi_.vis2log(vpos);
        pos_type const end = row_.endpos();
        FontSpan const font_span = par_.fontSpan(pos);
        Change::Type const prev_change = par_.lookupChange(pos).type;
@@ -311,12 +318,16 @@ void RowPainter::paintChars(pos_type & vpos, Font const & font,
 
        if (arabic) {
                char_type c = str[0];
+               if (c == '(')
+                       c = ')';
+               else if (c == ')')
+                       c = '(';
                str[0] = par_.transformChar(c, pos);
        }
 
        // collect as much similar chars as we can
        for (++vpos ; vpos < end ; ++vpos) {
-               pos = text_.bidi.vis2log(vpos);
+               pos = bidi_.vis2log(vpos);
                if (pos < font_span.first || pos > font_span.last)
                        break;
 
@@ -355,6 +366,10 @@ void RowPainter::paintChars(pos_type & vpos, Font const & font,
                */
 
                if (arabic) {
+                       if (c == '(')
+                               c = ')';
+                       else if (c == ')')
+                               c = '(';
                        c = par_.transformChar(c, pos);
                        /* see comment in hebrew, explaining why we break */
                        break;
@@ -395,7 +410,7 @@ void RowPainter::paintForeignMark(double orig_x, Font const & font, int desc)
 
 void RowPainter::paintFromPos(pos_type & vpos)
 {
-       pos_type const pos = text_.bidi.vis2log(vpos);
+       pos_type const pos = bidi_.vis2log(vpos);
        Font orig_font = text_.getFont(*bv_.buffer(), par_, pos);
 
        double const orig_x = x_;
@@ -414,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";
+       bool const arabic = lang == "arabic_arabtex" || lang == "arabic_arabi" || 
+                                               lang == "farsi";
 
        // draw as many chars as we can
        if ((!hebrew && !arabic)
@@ -739,7 +755,7 @@ void RowPainter::paintText()
                if (x_ > bv_.workWidth())
                        break;
 
-               pos_type const pos = text_.bidi.vis2log(vpos);
+               pos_type const pos = bidi_.vis2log(vpos);
 
                if (pos >= par_.size()) {
                        ++vpos;
@@ -914,6 +930,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) {
@@ -960,7 +978,7 @@ 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 &&
@@ -1044,12 +1062,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);
 }