Hi!For my dynamic macros I need an extension to the Painter for monochrome rendering. This is independent of my other patch, so I post it here first:
Basically all colors are mapped into an interval [min,max] of two colors. By this subformulas can be greyed out easily without touching the inset at all. All the needed logic is in GuiPainter::enterMonochromeMode and GuiPainter::leaveMonochromeMode and the GuiPainter::computeColor/filterColor methods.
Objections? Improvements? Stefan === src/frontends/qt4/GuiPainter.h ================================================================== --- src/frontends/qt4/GuiPainter.h (/mirror/lyx) (revision 15044) +++ src/frontends/qt4/GuiPainter.h (/lyx) (revision 15044) @@ -18,6 +18,7 @@ #include "Color.h" #include <QPainter> +#include <stack> class QString; @@ -95,6 +96,12 @@ /// draw a char at position x, y (y is the baseline) virtual int text(int x, int y, char_type c, Font const & f);+ /// start monochrome painting mode, i.e. map every color into [min,max]
+ virtual void enterMonochromeMode(Color_color const & min, + Color_color const & max); + /// leave monochrome painting mode + virtual void leaveMonochromeMode(); + private: /// draw small caps text /** @@ -104,13 +111,23 @@ QString const & str, Font const & f); /// set pen parameters - void setQPainterPen(Color_color col, + void setQPainterPen(QColor const & col, line_style ls = line_solid, line_width lw = line_thin); - Color::color current_color_; + QColor current_color_; Painter::line_style current_ls_; Painter::line_width current_lw_; + /// + std::stack<QColor> monochrome_min_; + /// + std::stack<QColor> monochrome_max_; + /// convert into Qt color, possibly applying the monochrome mode + QColor computeColor(Color_color col); + /// possibly apply monochrome mode + QColor filterColor(QColor const & col); + /// + QString generateStringSignature(QString const & str, Font const & f); }; } // namespace frontend === src/frontends/qt4/GuiPainter.cpp ================================================================== --- src/frontends/qt4/GuiPainter.cpp (/mirror/lyx) (revision 15044) +++ src/frontends/qt4/GuiPainter.cpp (/lyx) (revision 15044) @@ -47,24 +47,13 @@ bool const usePixmapCache = USE_PIXMAP_CACHE; -QString generateStringSignature(QString const & str, Font const & f) -{ - QString sig = str; - sig.append(QChar(static_cast<short>(f.family()))); - 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()))); - return sig; -} - } // anon namespace GuiPainter::GuiPainter(QPaintDevice * device) : QPainter(device), Painter() { // new QPainter has default QPen: - current_color_ = Color::black; + current_color_ = guiApp->colorCache().get(Color::black); current_ls_ = line_solid; current_lw_ = line_thin; } @@ -77,7 +66,7 @@ } -void GuiPainter::setQPainterPen(Color_color col, +void GuiPainter::setQPainterPen(QColor const & col, Painter::line_style ls, Painter::line_width lw) { if (col == current_color_ && ls == current_ls_ && lw == current_lw_) @@ -88,9 +77,8 @@ current_lw_ = lw; QPen pen = QPainter::pen(); + pen.setColor(col); - pen.setColor(guiApp->colorCache().get(col)); - switch (ls) { case line_solid: pen.setStyle(Qt::SolidLine); break; case line_onoffdash: pen.setStyle(Qt::DotLine); break; @@ -105,12 +93,78 @@ }+QString GuiPainter::generateStringSignature(QString const & str, Font const & f)
+{ + QString sig = str; + sig.append(QChar(static_cast<short>(f.family()))); + 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()))); + if (!monochrome_min_.empty()) { + QColor const & min = monochrome_min_.top(); + QColor const & max = monochrome_max_.top(); + sig.append(QChar(static_cast<short>(min.red()))); + sig.append(QChar(static_cast<short>(min.green()))); + sig.append(QChar(static_cast<short>(min.blue()))); + sig.append(QChar(static_cast<short>(max.red()))); + sig.append(QChar(static_cast<short>(max.green()))); + sig.append(QChar(static_cast<short>(max.blue()))); + } + return sig; +} + + +QColor GuiPainter::computeColor(Color_color col) +{ + return filterColor(guiApp->colorCache().get(col)); +} + + +QColor GuiPainter::filterColor(QColor const & col) +{ + if (monochrome_min_.empty()) + return col; + + // map into [min,max] interval + QColor const & min = monochrome_min_.top(); + QColor const & max = monochrome_max_.top(); + + qreal v = col.valueF(); + v = v * v; // make it a bit steeper (i.e. darker) + + qreal minr, ming, minb; + qreal maxr, maxg, maxb; + min.getRgbF(&minr, &ming, &minb); + max.getRgbF(&maxr, &maxg, &maxb); ++ return QColor(v*minr+(1-v)*maxr, v*ming+(1-v)*maxg, v*minb+(1-v) *maxb);
+} + ++void GuiPainter::enterMonochromeMode(Color_color const & min, Color_color const & max)
+{ + QColor qmin = filterColor(guiApp->colorCache().get(min)); + QColor qmax = filterColor(guiApp->colorCache().get(max)); + monochrome_min_.push(qmin); + monochrome_max_.push(qmax); +} + + +void GuiPainter::leaveMonochromeMode() +{ + BOOST_ASSERT(!monochrome_min_.empty()); + monochrome_min_.pop(); + monochrome_max_.pop(); +} + + void GuiPainter::point(int x, int y, Color_color col) { if (!isDrawingEnabled()) return; - setQPainterPen(col); + setQPainterPen(computeColor(col)); drawPoint(x, y); } @@ -123,7 +177,7 @@ if (!isDrawingEnabled()) return; - setQPainterPen(col, ls, lw); + setQPainterPen(computeColor(col), ls, lw); bool const do_antialiasing = renderHints() & TextAntialiasing && x1 != x2 && y1 != y2; setRenderHint(Antialiasing, do_antialiasing); @@ -152,7 +206,7 @@ if (i != 0) antialias |= xp[i-1] != xp[i] && yp[i-1] != yp[i]; } - setQPainterPen(col, ls, lw); + setQPainterPen(computeColor(col), ls, lw); bool const text_is_antialiased = renderHints() & TextAntialiasing; setRenderHint(Antialiasing, antialias && text_is_antialiased); drawPolyline(points.data(), np); @@ -168,7 +222,7 @@ if (!isDrawingEnabled()) return; - setQPainterPen(col, ls, lw); + setQPainterPen(computeColor(col), ls, lw); drawRect(x, y, w, h); } @@ -186,7 +240,7 @@ return; // LyX usings 1/64ths degree, Qt usings 1/16th - setQPainterPen(col); + setQPainterPen(computeColor(col)); bool const do_antialiasing = renderHints() & TextAntialiasing; setRenderHint(Antialiasing, do_antialiasing); drawArc(x, y, w, h, a1 / 4, a2 / 4); @@ -224,7 +278,7 @@ QFont const & qfont = guiApp->guiFontLoader().get(f); QFont const & qsmallfont = guiApp->guiFontLoader().get(smallfont); - setQPainterPen(f.realColor()); + setQPainterPen(computeColor(f.realColor())); int textwidth = 0; size_t const ls = s.length(); for (unsigned int i = 0; i < ls; ++i) { @@ -294,7 +348,7 @@ // occurs at a line-break. As a kludge, we force Qt to // render this glyph using a one-column line. if (s.size() == 1 && str[0].unicode() == 0x00ad) { - setQPainterPen(f.realColor()); + setQPainterPen(computeColor(f.realColor())); QTextLayout adsymbol(str); adsymbol.setFont(fi.font); adsymbol.beginLayout(); @@ -309,7 +363,7 @@ if (!usePixmapCache) { // don't use the pixmap cache, // draw directly onto the painting device - setQPainterPen(f.realColor()); + setQPainterPen(computeColor(f.realColor())); if (font() != fi.font) setFont(fi.font); // We need to draw the text as LTR as we use our own bidi code. @@ -343,7 +397,7 @@ pm = QPixmap(w, h); pm.fill(Qt::transparent); GuiPainter p(&pm); - p.setQPainterPen(f.realColor()); + p.setQPainterPen(computeColor(f.realColor())); if (p.font() != fi.font) p.setFont(fi.font); // We need to draw the text as LTR as we use our own bidi code. === src/frontends/Painter.h ================================================================== --- src/frontends/Painter.h (/mirror/lyx) (revision 15044) +++ src/frontends/Painter.h (/lyx) (revision 15044) @@ -169,6 +169,12 @@ int preeditText(int x, int y, char_type c, Font const & f, preedit_style style);+ /// start monochrome painting mode, i.e. map every color into [min,max]
+ virtual void enterMonochromeMode(Color_color const & min, + Color_color const & max) = 0; + /// leave monochrome painting mode + virtual void leaveMonochromeMode() = 0; + protected: /// check the font, and if set, draw an underline void underline(Font const & f,
monochrome.patch
Description: Binary data
PGP.sig
Description: Signierter Teil der Nachricht