commit 51ee267c6e8336727b3d94db424a8efd1cfc4a1e
Author: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date:   Tue May 31 09:13:18 2016 +0200

    Allow automatic text direction in Painter::text()
    
    It is wrong to assume that direction is left-to-right when no indication 
exist.
    
    Add a new enum with values LtR, RtL and Auto to be used as argument of
    the private text() methods. When direction is Auto, let Qt decide how
    the string shall be layed out.
    
    Fixes bug #10169.

diff --git a/src/frontends/qt4/GuiPainter.cpp b/src/frontends/qt4/GuiPainter.cpp
index a622940..725320b 100644
--- a/src/frontends/qt4/GuiPainter.cpp
+++ b/src/frontends/qt4/GuiPainter.cpp
@@ -335,11 +335,13 @@ void GuiPainter::text(int x, int y, char_type c, FontInfo 
const & f)
 
 void GuiPainter::text(int x, int y, docstring const & s, FontInfo const & f)
 {
-       text(x, y, s, f, false, 0.0, 0.0);
+       text(x, y, s, f, Auto, 0.0, 0.0);
 }
 
 
-void GuiPainter::do_drawText(int x, int y, QString str, bool rtl, FontInfo 
const & f, QFont ff)
+void GuiPainter::do_drawText(int x, int y, QString str,
+                             GuiPainter::Direction const dir,
+                             FontInfo const & f, QFont ff)
 {
        setQPainterPen(computeColor(f.realColor()));
        if (font() != ff)
@@ -352,10 +354,10 @@ void GuiPainter::do_drawText(int x, int y, QString str, 
bool rtl, FontInfo const
        /* Use unicode override characters to enforce drawing direction
         * Source: http://www.iamcal.com/understanding-bidirectional-text/
         */
-       if (rtl)
+       if (dir == RtL)
                // Right-to-left override: forces to draw text right-to-left
                str = QChar(0x202E) + str;
-       else
+       else if (dir == LtR)
                // Left-to-right override: forces to draw text left-to-right
                str =  QChar(0x202D) + str;
        drawText(x, y, str);
@@ -366,8 +368,12 @@ void GuiPainter::do_drawText(int x, int y, QString str, 
bool rtl, FontInfo const
         * Keep it here for now, in case it can be helpful
         */
        //This is much stronger than setLayoutDirection.
-       int flag = rtl ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight;
-       drawText(x + (rtl ? textwidth : 0), y - fm.maxAscent(), 0, 0,
+       int flag = 0;
+       if (dir == RtL)
+               flag = Qt::TextForceRightToLeft;
+       else if (dir == LtR)
+               flag = Qt::TextForceLeftToRight;
+       drawText(x + ((dir == RtL) ? textwidth : 0), y - fm.maxAscent(), 0, 0,
                 flag | Qt::TextDontClip,
                 str);
 #endif
@@ -375,7 +381,7 @@ void GuiPainter::do_drawText(int x, int y, QString str, 
bool rtl, FontInfo const
 
 
 void GuiPainter::text(int x, int y, docstring const & s,
-                      FontInfo const & f, bool const rtl,
+                      FontInfo const & f, Direction const dir,
                       double const wordspacing, double const tw)
 {
        //LYXERR0("text: x=" << x << ", s=" << s);
@@ -450,7 +456,7 @@ void GuiPainter::text(int x, int y, docstring const & s,
 #endif
                        pm.fill(Qt::transparent);
                        GuiPainter p(&pm, pixelRatio());
-                       p.do_drawText(-lb, mA, str, rtl, f, ff);
+                       p.do_drawText(-lb, mA, str, dir, f, ff);
                        QPixmapCache::insert(key, pm);
                        //LYXERR(Debug::PAINTING, "h=" << h << "  mA=" << mA << 
"  mD=" << mD
                        //      << "  w=" << w << "  lb=" << lb << "  tw=" << 
textwidth
@@ -464,7 +470,7 @@ void GuiPainter::text(int x, int y, docstring const & s,
        }
 
        // don't use the pixmap cache,
-       do_drawText(x, y, str, rtl, f, ff);
+       do_drawText(x, y, str, dir, f, ff);
        //LYXERR(Debug::PAINTING, "draw " << string(str.toUtf8())
        //      << " at " << x << "," << y);
 }
@@ -473,7 +479,8 @@ void GuiPainter::text(int x, int y, docstring const & s,
 void GuiPainter::text(int x, int y, docstring const & str, Font const & f,
                       double const wordspacing, double const tw)
 {
-       text(x, y, str, f.fontInfo(), f.isVisibleRightToLeft(), wordspacing, 
tw);
+       text(x, y, str, f.fontInfo(), f.isVisibleRightToLeft() ? RtL : LtR,
+            wordspacing, tw);
 }
 
 
@@ -483,13 +490,13 @@ void GuiPainter::text(int x, int y, docstring const & 
str, Font const & f,
 {
        GuiFontMetrics const & fm = getFontMetrics(f.fontInfo());
        FontInfo fi = f.fontInfo();
-       bool const rtl = f.isVisibleRightToLeft();
+       Direction const dir = f.isVisibleRightToLeft() ? RtL : LtR;
 
        // dimensions
        int const ascent = fm.maxAscent();
        int const height = fm.maxAscent() + fm.maxDescent();
-       int xmin = fm.pos2x(str, from, rtl, wordspacing);
-       int xmax = fm.pos2x(str, to, rtl, wordspacing);
+       int xmin = fm.pos2x(str, from, dir == RtL, wordspacing);
+       int xmax = fm.pos2x(str, to, dir == RtL, wordspacing);
        if (xmin > xmax)
                swap(xmin, xmax);
 
@@ -498,7 +505,7 @@ void GuiPainter::text(int x, int y, docstring const & str, 
Font const & f,
        fi.setPaintColor(other);
        QRegion const clip(x + xmin, y - ascent, xmax - xmin, height);
        setClipRegion(clip);
-       text(x, y, str, fi, rtl, wordspacing, tw);
+       text(x, y, str, fi, dir, wordspacing, tw);
 
        // Then the part in normal color
        // Note that in Qt5, it is not possible to use Qt::UniteClip,
@@ -506,7 +513,7 @@ void GuiPainter::text(int x, int y, docstring const & str, 
Font const & f,
        fi.setPaintColor(orig);
        QRegion region(viewport());
        setClipRegion(region - clip);
-       text(x, y, str, fi, rtl, wordspacing, tw);
+       text(x, y, str, fi, dir, wordspacing, tw);
        setClipping(false);
 }
 
diff --git a/src/frontends/qt4/GuiPainter.h b/src/frontends/qt4/GuiPainter.h
index 10d3070..cb09107 100644
--- a/src/frontends/qt4/GuiPainter.h
+++ b/src/frontends/qt4/GuiPainter.h
@@ -180,12 +180,15 @@ private:
        void setQPainterPen(QColor const & col,
                line_style ls = line_solid, int lw = thin_line);
 
+       // Direction for painting text
+       enum Direction { LtR, RtL, Auto };
+
        // Helper for text() method
-       void do_drawText(int x, int y, QString str, bool rtl, FontInfo const & 
f, QFont ff);
+       void do_drawText(int x, int y, QString str, Direction dir, FontInfo 
const & f, QFont ff);
 
        // Real text() method
        void text(int x, int y, docstring const & s,
-              FontInfo const & f, bool const rtl,
+              FontInfo const & f, Direction const dir,
               double const wordspacing, double tw);
 
        QColor current_color_;

Reply via email to