]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiPainter.cpp
On Linux show in crash message box the backtrace
[lyx.git] / src / frontends / qt4 / GuiPainter.cpp
index f4bd49587c5445aad8c4d0c85f08dcb8bf6b0e8d..ca639668fb962b118de2e90b65fa43f812230975 100644 (file)
@@ -44,6 +44,8 @@ using namespace std;
 
 namespace lyx {
 namespace frontend {
+  
+const float Painter::thin_line = 0.0;
 
 GuiPainter::GuiPainter(QPaintDevice * device)
        : QPainter(device), Painter(),
@@ -52,7 +54,7 @@ GuiPainter::GuiPainter(QPaintDevice * device)
        // new QPainter has default QPen:
        current_color_ = guiApp->colorCache().get(Color_black);
        current_ls_ = line_solid;
-       current_lw_ = line_thin;
+       current_lw_ = thin_line;
 }
 
 
@@ -64,7 +66,7 @@ GuiPainter::~GuiPainter()
 
 
 void GuiPainter::setQPainterPen(QColor const & col,
-       Painter::line_style ls, Painter::line_width lw)
+       Painter::line_style ls, float lw)
 {
        if (col == current_color_ && ls == current_ls_ && lw == current_lw_)
                return;
@@ -81,10 +83,7 @@ void GuiPainter::setQPainterPen(QColor const & col,
                case line_onoffdash: pen.setStyle(Qt::DotLine); break;
        }
 
-       switch (lw) {
-               case line_thin: pen.setWidth(0); break;
-               case line_thick: pen.setWidth(3); break;
-       }
+       pen.setWidthF(lw);
 
        setPen(pen);
 }
@@ -97,7 +96,9 @@ QString GuiPainter::generateStringSignature(QString const & str, FontInfo const
        sig.append(QChar(static_cast<short>(f.series())));
        sig.append(QChar(static_cast<short>(f.realShape())));
        sig.append(QChar(static_cast<short>(f.size())));
-       sig.append(QChar(static_cast<short>(f.color())));
+       Color const & color = f.realColor();
+       sig.append(QChar(static_cast<short>(color.baseColor)));
+       sig.append(QChar(static_cast<short>(color.mergeColor)));
        if (!monochrome_min_.empty()) {
                QColor const & min = monochrome_min_.top();
                QColor const & max = monochrome_max_.top();
@@ -155,7 +156,7 @@ void GuiPainter::enterMonochromeMode(Color const & min, Color const & max)
 
 void GuiPainter::leaveMonochromeMode()
 {
-       LASSERT(!monochrome_min_.empty(), /**/);
+       LASSERT(!monochrome_min_.empty(), return);
        monochrome_min_.pop();
        monochrome_max_.pop();
 }
@@ -174,7 +175,7 @@ void GuiPainter::point(int x, int y, Color col)
 void GuiPainter::line(int x1, int y1, int x2, int y2,
        Color col,
        line_style ls,
-       line_width lw)
+       float lw)
 {
        if (!isDrawingEnabled())
                return;
@@ -191,12 +192,13 @@ void GuiPainter::line(int x1, int y1, int x2, int y2,
 void GuiPainter::lines(int const * xp, int const * yp, int np,
        Color col,
        line_style ls,
-       line_width lw)
+       float lw)
 {
        if (!isDrawingEnabled())
                return;
 
        // double the size if needed
+       // FIXME THREAD
        static QVector<QPoint> points(32);
        if (np > points.size())
                points.resize(2 * np);
@@ -219,7 +221,7 @@ void GuiPainter::lines(int const * xp, int const * yp, int np,
 void GuiPainter::rectangle(int x, int y, int w, int h,
        Color col,
        line_style ls,
-       line_width lw)
+       float lw)
 {
        if (!isDrawingEnabled())
                return;
@@ -274,33 +276,6 @@ int GuiPainter::text(int x, int y, char_type c, FontInfo const & f)
 }
 
 
-int GuiPainter::smallCapsText(int x, int y,
-       QString const & s, FontInfo const & f)
-{
-       FontInfo smallfont(f);
-       smallfont.decSize().decSize().setShape(UP_SHAPE);
-
-       QFont const & qfont = getFont(f);
-       QFont const & qsmallfont = getFont(smallfont);
-
-       setQPainterPen(computeColor(f.realColor()));
-       int textwidth = 0;
-       size_t const ls = s.length();
-       for (unsigned int i = 0; i < ls; ++i) {
-               QChar const c = s[i].toUpper();
-               if (c != s.at(i)) {
-                       setFont(qsmallfont);
-               } else {
-                       setFont(qfont);
-               }
-               if (isDrawingEnabled())
-                       drawText(x + textwidth, y, c);
-               textwidth += fontMetrics().width(c);
-       }
-       return textwidth;
-}
-
-
 int GuiPainter::text(int x, int y, docstring const & s,
                FontInfo const & f)
 {
@@ -332,19 +307,11 @@ int GuiPainter::text(int x, int y, docstring const & s,
 
        int textwidth;
 
-       if (f.realShape() == SMALLCAPS_SHAPE) {
-               textwidth = smallCapsText(x, y, str, f);
-               if (f.underbar() == FONT_ON)
-                       underline(f, x, y, textwidth);
-               return textwidth;
-       }
-
        // Here we use the font width cache instead of
        //   textwidth = fontMetrics().width(str);
        // because the above is awfully expensive on MacOSX
        textwidth = fm.width(s);
-       if (f.underbar() == FONT_ON)
-               underline(f, x, y, textwidth);
+       textDecoration(f, x, y, textwidth);
 
        if (!isDrawingEnabled())
                return textwidth;
@@ -353,6 +320,12 @@ int GuiPainter::text(int x, int y, docstring const & s,
        // same as that of a soft-hyphen (0x00ad), unless it
        // occurs at a line-break. As a kludge, we force Qt to
        // render this glyph using a one-column line.
+       // This is needed for some math glyphs.
+       // FIXME In texted, this behaves differently depending
+       // on lyxrc.force_paint_single_char status.
+       // Should the soft hyphen char be displayed at all?
+       // I don't think so (i.e., Qt is correct as far as
+       // texted is concerned). /spitz
        if (s.size() == 1 && str[0].unicode() == 0x00ad) {
                setQPainterPen(computeColor(f.realColor()));
                QTextLayout adsymbol(str);
@@ -427,6 +400,20 @@ int GuiPainter::text(int x, int y, docstring const & s,
 }
 
 
+void GuiPainter::textDecoration(FontInfo const & f, int x, int y, int width)
+{
+       if (f.underbar() == FONT_ON)
+               underline(f, x, y, width);
+       if (f.strikeout() == FONT_ON)
+               strikeoutLine(f, x, y, width);
+       if (f.uuline() == FONT_ON)
+               doubleUnderline(f, x, y, width);
+       if (f.uwave() == FONT_ON)
+               // f.color() doesn't work on some circumstances
+               wavyHorizontalLine(x, y, width,  f.realColor().baseColor);
+}
+
+
 static int max(int a, int b) { return a > b ? a : b; }
 
 
@@ -520,6 +507,17 @@ int GuiPainter::preeditText(int x, int y, char_type c,
 }
 
 
+void GuiPainter::doubleUnderline(FontInfo const & f, int x, int y, int width)
+{
+       FontMetrics const & fm = theFontMetrics(f);
+
+       int const below = max(fm.maxDescent() / 2, 2);
+
+       line(x, y + below, x + width, y + below, f.realColor());
+       line(x, y + below - 2, x + width, y + below - 2, f.realColor());
+}
+
+
 void GuiPainter::underline(FontInfo const & f, int x, int y, int width)
 {
        FontMetrics const & fm = theFontMetrics(f);
@@ -534,6 +532,20 @@ void GuiPainter::underline(FontInfo const & f, int x, int y, int width)
 }
 
 
+void GuiPainter::strikeoutLine(FontInfo const & f, int x, int y, int width)
+{
+       FontMetrics const & fm = theFontMetrics(f);
+
+       int const middle = max((fm.maxHeight() / 4), 1);
+       int const height =  middle/3;
+
+       if (height < 2)
+               line(x, y - middle, x + width, y - middle, f.realColor());
+       else
+               fillRectangle(x, y - middle, width, height, f.realColor());
+}
+
+
 void GuiPainter::dashedUnderline(FontInfo const & f, int x, int y, int width)
 {
        FontMetrics const & fm = theFontMetrics(f);
@@ -548,5 +560,24 @@ void GuiPainter::dashedUnderline(FontInfo const & f, int x, int y, int width)
                line(x, y + below + n, x + width, y + below + n, f.realColor(), line_onoffdash);
 }
 
+
+void GuiPainter::wavyHorizontalLine(int x, int y, int width, ColorCode col)
+{
+       setQPainterPen(computeColor(col));
+       int const step = 2;
+       int const xend = x + width;
+       int height = 1;
+       //FIXME: I am not sure if Antialiasing gives the best effect.
+       //setRenderHint(Antialiasing, true);
+       while (x < xend) {
+               height = - height;
+               drawLine(x, y - height, x + step, y + height);
+               x += step;
+               drawLine(x, y + height, x + step/2, y + height);
+               x += step/2;
+       }
+       //setRenderHint(Antialiasing, false);
+}
+
 } // namespace frontend
 } // namespace lyx