]> git.lyx.org Git - lyx.git/blobdiff - src/rowpainter.C
explain why ownsClipbiard() does not work on Windows and OS X
[lyx.git] / src / rowpainter.C
index 9cfae9d44aa6c963f28958abbb9b9d5dc42629ac..af58063cc79256960c9e75f82bd0c29bde3e0941 100644 (file)
@@ -191,9 +191,7 @@ void RowPainter::paintInset(pos_type const pos, LyXFont const & font)
        bool tmp = refreshInside;
        if (!in || !in->wide()) {
                refreshInside = true;
-               if (lyxerr.debugging(Debug::PAINTING)) { 
-                       lyxerr << endl << "Paint inset fully" << endl;
-               }
+               LYXERR(Debug::PAINTING) << endl << "Paint inset fully" << endl;
        }
        if (refreshInside)
                inset->drawSelection(pi, int(x_), yo_);
@@ -253,12 +251,8 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos, LyXFont const & font)
                        if (isPrintableNonspace(c)) {
                                int const width2 = text_.singleWidth(par_, i, c,
                                        text_.getFont(*bv_.buffer(), par_, i));
-                               // FIXME UNICODE
-                               // This does not work anymore, and non-ascii
-                               // characters in source files are forbidden
-                               // anyway.
-                               // dalet / resh
-                               dx = (c == 'ø' || c == 'ã')
+                               dx = (c == 0x05e8 || // resh
+                                     c == 0x05d3)   // dalet
                                        ? width2 - width
                                        : (width2 - width) / 2;
                        }
@@ -267,7 +261,6 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos, LyXFont const & font)
        }
 
        // Draw nikud
-       // FIXME UNICODE
        pain_.text(int(x_) + dx, yo_, str, font);
 }
 
@@ -301,6 +294,7 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos, LyXFont const & font)
        pain_.text(int(x_) + dx, yo_, str, font);
 }
 
+
 void RowPainter::paintChars(pos_type & vpos, LyXFont const & font,
                            bool hebrew, bool arabic)
 {
@@ -334,18 +328,43 @@ void RowPainter::paintChars(pos_type & vpos, LyXFont const & font,
                if (!isPrintableNonspace(c))
                        break;
 
+               /* Because we do our own bidi, at this point the strings are
+                * already in visual order. However, Qt also applies its own
+                * bidi algorithm to strings that it paints to the screen.
+                * Therefore, if we were to paint Hebrew/Arabic words as a
+                * single string, the letters in the words would get reversed
+                * again. In order to avoid that, we don't collect Hebrew/
+                * Arabic characters, but rather paint them one at a time.
+                * See also http://thread.gmane.org/gmane.editors.lyx.devel/79740
+                */
+               if (hebrew) 
+                       break;
+
+               /* FIXME: these checks are irrelevant, since 'arabic' and
+                * 'hebrew' alone are already going to trigger a break.
+                * However, this should not be removed completely, because
+                * if an alternative solution is found which allows grouping
+                * of arabic and hebrew characters, then these breaks may have
+                * to be re-applied.
+
                if (arabic && Encodings::isComposeChar_arabic(c))
                        break;
 
                if (hebrew && Encodings::isComposeChar_hebrew(c))
                        break;
+               */
 
-               if (arabic)
+               if (arabic) {
                        c = par_.transformChar(c, pos);
+                       /* see comment in hebrew, explaining why we break */
+                       break;
+               }
 
                str.push_back(c);
        }
 
+       docstring s(&str[0], str.size());
+
        if (prev_change != Change::UNCHANGED) {
                LyXFont copy(font);
                if (prev_change == Change::DELETED) {
@@ -353,9 +372,9 @@ void RowPainter::paintChars(pos_type & vpos, LyXFont const & font,
                } else if (prev_change == Change::INSERTED) {
                        copy.setColor(LColor::newtext);
                }
-               x_ += pain_.text(int(x_), yo_, &str[0], str.size(), copy);
+               x_ += pain_.text(int(x_), yo_, s, copy);
        } else {
-               x_ += pain_.text(int(x_), yo_, &str[0], str.size(), font);
+               x_ += pain_.text(int(x_), yo_, s, font);
        }
 }
 
@@ -395,9 +414,7 @@ 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" &&
-               (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 ||
-               lyxrc.font_norm_type == LyXRC::ISO_10646_1);
+       bool const arabic = lang == "arabic";
 
        // draw as many chars as we can
        if ((!hebrew && !arabic)
@@ -823,20 +840,6 @@ void RowPainter::paintText()
 }
 
 
-size_type calculateRowSignature(Row const & row, Paragraph const & par,
-       int x, int y)
-{
-       boost::crc_32_type crc;
-       for (pos_type i = row.pos(); i < row.endpos(); ++i) {
-               char_type const b[] = { par.getChar(i) };
-               crc.process_bytes(b, 1);
-       }
-       char_type const b[] = { x, y, row.width() };
-       crc.process_bytes(b, 3);
-       return crc.checksum();
-}
-
-
 bool CursorOnRow(PainterInfo & pi, pit_type const pit,
        RowList::const_iterator rit, LyXText const & text)
 {
@@ -899,8 +902,7 @@ void paintPar
                bool tmp = refreshInside;
 
                // Row signature; has row changed since last paint?
-               size_type const row_sig = calculateRowSignature(*rit, par, x, y);
-               bool row_has_changed = pm.rowSignature()[rowno] != row_sig;
+               bool row_has_changed = pm.rowChangeStatus()[rowno];
 
                bool cursor_on_row = CursorOnRow(pi, pit, rit, text);
                bool in_inset_alone_on_row = innerCursorOnRow(pi, pit, rit,
@@ -928,9 +930,6 @@ void paintPar
                // from cache, or cursor is inside an inset _on this row_,
                // then paint the row
                if (repaintAll || row_has_changed || cursor_on_row) {
-                       // Add to row signature cache
-                       pm.rowSignature()[rowno] = row_sig;
-                       
                        bool const inside = (y + rit->descent() >= 0
                                && y - rit->ascent() < ww);
                        // it is not needed to draw on screen if we are not inside.
@@ -954,9 +953,9 @@ void paintPar
                        // 12 lines lower):
                        if (lyxerr.debugging(Debug::PAINTING)) {
                                if (text.isMainText(*pi.base.bv->buffer()))
-                                       lyxerr[Debug::PAINTING] << "#";
+                                       LYXERR(Debug::PAINTING) << "#";
                                else
-                                       lyxerr[Debug::PAINTING] << "[" <<
+                                       LYXERR(Debug::PAINTING) << "[" <<
                                                repaintAll << row_has_changed <<
                                                cursor_on_row << "]";
                        }
@@ -976,9 +975,7 @@ void paintPar
        // Re-enable screen drawing for future use of the painter.
        pi.pain.setDrawingEnabled(true);
 
-       if (lyxerr.debugging(Debug::PAINTING)) {
-               lyxerr[Debug::PAINTING] << "." << endl;
-       }
+       LYXERR(Debug::PAINTING) << "." << endl;
 }
 
 } // namespace anon
@@ -995,7 +992,10 @@ void paintText(BufferView & bv,
        
        PainterInfo pi(const_cast<BufferView *>(&bv), pain);
        // Should the whole screen, including insets, be refreshed?
-       bool repaintAll = select || !vi.singlepar;
+       // FIXME: We should also distinguish DecorationUpdate to avoid text
+       // drawing if possible. This is not possible to do easily right now
+       // because of the single backing pixmap.
+       bool repaintAll = select || vi.update_strategy != SingleParUpdate;
 
        if (repaintAll) {
                // Clear background (if not delegated to rows)
@@ -1018,12 +1018,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.singlepar)
+       if (vi.y1 > 0 && vi.update_strategy != SingleParUpdate)
                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() && !vi.singlepar)
+       if (vi.y2 < bv.workHeight() && vi.update_strategy != SingleParUpdate)
                pain.fillRectangle(0, vi.y2, bv.workWidth(), bv.workHeight() - vi.y2, LColor::bottomarea);
 }