Fix and simplify computation of painter monochrome mode

The old code in GuiPainter::filterColor did not work. Tricks with
colors should take place in HSV space, not RGB IMO.

Replace the code with a simpler one which maps the grayscale value
of the original color on the blend color. It works nin the case where
original color is red, but might not work as well when blend color is
not black. Time will tell.

Fixes bug #11904.
This commit is contained in:
Jean-Marc Lasgouttes 2020-07-11 23:56:48 +02:00
parent df2234f18d
commit 77036f5434
6 changed files with 28 additions and 53 deletions

View File

@ -95,8 +95,8 @@ public:
int preeditText(int, int, char_type, FontInfo const &,
preedit_style) { return 0; }
/// start monochrome painting mode, i.e. map every color into [min,max]
void enterMonochromeMode(Color const &, Color const &) {}
/// start monochrome painting mode, i.e. map every color a shade of \c blend.
void enterMonochromeMode(Color const &) {}
/// leave monochrome painting mode
void leaveMonochromeMode() {}
/// draws a wavy line that can be used for underlining.

View File

@ -176,9 +176,8 @@ public:
virtual int preeditText(int x, int y,
char_type c, FontInfo const & f, preedit_style style) = 0;
/// start monochrome painting mode, i.e. map every color into [min,max]
virtual void enterMonochromeMode(Color const & min,
Color const & max) = 0;
/// start monochrome painting mode, i.e. map every color a shade of \c blend.
virtual void enterMonochromeMode(Color const & blend) = 0;
/// leave monochrome painting mode
virtual void leaveMonochromeMode() = 0;
/// draws a wavy line that can be used for underlining.

View File

@ -91,44 +91,25 @@ QColor GuiPainter::computeColor(Color col)
QColor GuiPainter::filterColor(QColor const & col)
{
if (monochrome_min_.empty())
if (monochrome_blend_.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; // 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);
QColor c;
c.setRgbF(
v * (minr - maxr) + maxr,
v * (ming - maxg) + maxg,
v * (minb - maxb) + maxb);
return c;
QColor const blend = monochrome_blend_.top();
return QColor::fromHsv(blend.hue(), blend.saturation(), qGray(col.rgb()));
}
void GuiPainter::enterMonochromeMode(Color const & min, Color const & max)
void GuiPainter::enterMonochromeMode(Color const & blend)
{
QColor qmin = filterColor(guiApp->colorCache().get(min));
QColor qmax = filterColor(guiApp->colorCache().get(max));
monochrome_min_.push(qmin);
monochrome_max_.push(qmax);
QColor qblend = filterColor(guiApp->colorCache().get(blend));
monochrome_blend_.push(qblend);
}
void GuiPainter::leaveMonochromeMode()
{
LASSERT(!monochrome_min_.empty(), return);
monochrome_min_.pop();
monochrome_max_.pop();
LASSERT(!monochrome_blend_.empty(), return);
monochrome_blend_.pop();
}

View File

@ -135,9 +135,8 @@ public:
virtual void buttonText(int x, int baseline, docstring const & s,
FontInfo const & font, Color back, Color frame, int offset);
/// start monochrome painting mode, i.e. map every color into [min,max]
virtual void enterMonochromeMode(Color const & min,
Color const & max);
/// start monochrome painting mode, i.e. map every color a shade of \c blend.
virtual void enterMonochromeMode(Color const & blend);
/// leave monochrome painting mode
virtual void leaveMonochromeMode();
@ -193,9 +192,7 @@ private:
Painter::line_style current_ls_;
int current_lw_;
///
std::stack<QColor> monochrome_min_;
///
std::stack<QColor> monochrome_max_;
std::stack<QColor> monochrome_blend_;
/// convert into Qt color, possibly applying the monochrome mode
QColor computeColor(Color col);
/// possibly apply monochrome mode

View File

@ -142,7 +142,7 @@ public:
void afterDraw(PainterInfo const & pi) const
{
if (mathMacro_->editMetrics(pi.base.bv))
pi.pain.enterMonochromeMode(Color_mathbg, Color_mathmacroblend);
pi.pain.enterMonochromeMode(Color_mathmacroblend);
}
///
void metrics(MetricsInfo &, Dimension &) const {
@ -386,7 +386,7 @@ void InsetMathMacro::afterMetrics() const
void InsetMathMacro::beforeDraw(PainterInfo const & pi) const
{
if (d->editing_[pi.base.bv])
pi.pain.enterMonochromeMode(Color_mathbg, Color_mathmacroblend);
pi.pain.enterMonochromeMode(Color_mathmacroblend);
}

View File

@ -286,9 +286,9 @@ void InsetMathWrapper::draw(PainterInfo & pi, int x, int y) const
class InsetColoredCell : public InsetMathNest {
public:
///
InsetColoredCell(Buffer * buf, ColorCode min, ColorCode max);
InsetColoredCell(Buffer * buf, ColorCode blend);
///
InsetColoredCell(Buffer * buf, ColorCode min, ColorCode max, MathAtom const & atom);
InsetColoredCell(Buffer * buf, ColorCode blend, MathAtom const & atom);
///
void draw(PainterInfo &, int x, int y) const;
///
@ -298,20 +298,18 @@ protected:
///
Inset * clone() const;
///
ColorCode min_;
///
ColorCode max_;
ColorCode blend_;
};
InsetColoredCell::InsetColoredCell(Buffer * buf, ColorCode min, ColorCode max)
: InsetMathNest(buf, 1), min_(min), max_(max)
InsetColoredCell::InsetColoredCell(Buffer * buf, ColorCode blend)
: InsetMathNest(buf, 1), blend_(blend)
{
}
InsetColoredCell::InsetColoredCell(Buffer * buf, ColorCode min, ColorCode max, MathAtom const & atom)
: InsetMathNest(buf, 1), min_(min), max_(max)
InsetColoredCell::InsetColoredCell(Buffer * buf, ColorCode blend, MathAtom const & atom)
: InsetMathNest(buf, 1), blend_(blend)
{
cell(0).insert(0, atom);
}
@ -331,7 +329,7 @@ void InsetColoredCell::metrics(MetricsInfo & mi, Dimension & dim) const
void InsetColoredCell::draw(PainterInfo & pi, int x, int y) const
{
pi.pain.enterMonochromeMode(min_, max_);
pi.pain.enterMonochromeMode(blend_);
cell(0).draw(pi, x, y);
pi.pain.leaveMonochromeMode();
}
@ -497,7 +495,7 @@ void InsetMathMacroTemplate::createLook(int args) const
// color it light grey, if it is to be removed when the cursor leaves
if (i == argsInLook_) {
optData->push_back(MathAtom(
new InsetColoredCell(buffer_, Color_mathbg, Color_mathmacrooldarg)));
new InsetColoredCell(buffer_, Color_mathmacrooldarg)));
optData = &(*optData)[optData->size() - 1].nucleus()->cell(0);
}
@ -513,7 +511,7 @@ void InsetMathMacroTemplate::createLook(int args) const
arg.push_back(MathAtom(new InsetMathMacroArgument(i + 1)));
if (i >= argsInLook_) {
look_.push_back(MathAtom(new InsetColoredCell(buffer_,
Color_mathbg, Color_mathmacrooldarg,
Color_mathmacrooldarg,
MathAtom(new InsetMathBrace(arg)))));
} else
look_.push_back(MathAtom(new InsetMathBrace(arg)));
@ -522,7 +520,7 @@ void InsetMathMacroTemplate::createLook(int args) const
MathData arg;
arg.push_back(MathAtom(new InsetMathMacroArgument(i + 1)));
look_.push_back(MathAtom(new InsetColoredCell(buffer_,
Color_mathbg, Color_mathmacronewarg,
Color_mathmacronewarg,
MathAtom(new InsetMathBrace(arg)))));
}