NOISSUE tabs -> spaces
This commit is contained in:
@ -16,7 +16,7 @@ target_link_libraries(MultiMC_rainbow Qt5::Core Qt5::Gui)
|
||||
|
||||
# Install it
|
||||
install(
|
||||
TARGETS MultiMC_rainbow
|
||||
RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
|
||||
LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
|
||||
TARGETS MultiMC_rainbow
|
||||
RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
|
||||
LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
|
||||
)
|
||||
|
@ -50,7 +50,7 @@ RAINBOW_EXPORT qreal luma(const QColor &);
|
||||
* @since 5.0
|
||||
*/
|
||||
RAINBOW_EXPORT void getHcy(const QColor &, qreal *hue, qreal *chroma, qreal *luma,
|
||||
qreal *alpha = 0);
|
||||
qreal *alpha = 0);
|
||||
|
||||
/**
|
||||
* Calculate the contrast ratio between two colors, according to the
|
||||
@ -132,7 +132,7 @@ RAINBOW_EXPORT QColor tint(const QColor &base, const QColor &color, qreal amount
|
||||
/**
|
||||
* Blend two colors into a new color by linear combination.
|
||||
* @code
|
||||
QColor lighter = Rainbow::mix(myColor, Qt::white)
|
||||
QColor lighter = Rainbow::mix(myColor, Qt::white)
|
||||
* @endcode
|
||||
* @param c1 first color.
|
||||
* @param c2 second color.
|
||||
@ -146,9 +146,9 @@ RAINBOW_EXPORT QColor mix(const QColor &c1, const QColor &c2, qreal bias = 0.5);
|
||||
* Blend two colors into a new color by painting the second color over the
|
||||
* first using the specified composition mode.
|
||||
* @code
|
||||
QColor white(Qt::white);
|
||||
white.setAlphaF(0.5);
|
||||
QColor lighter = Rainbow::overlayColors(myColor, white);
|
||||
QColor white(Qt::white);
|
||||
white.setAlphaF(0.5);
|
||||
QColor lighter = Rainbow::overlayColors(myColor, white);
|
||||
@endcode
|
||||
* @param base the base color (alpha channel is ignored).
|
||||
* @param paint the color to be overlayed onto the base color.
|
||||
@ -156,5 +156,5 @@ RAINBOW_EXPORT QColor mix(const QColor &c1, const QColor &c2, qreal bias = 0.5);
|
||||
*/
|
||||
RAINBOW_EXPORT QColor
|
||||
overlayColors(const QColor &base, const QColor &paint,
|
||||
QPainter::CompositionMode comp = QPainter::CompositionMode_SourceOver);
|
||||
QPainter::CompositionMode comp = QPainter::CompositionMode_SourceOver);
|
||||
}
|
||||
|
@ -16,11 +16,11 @@
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#ifdef RAINBOW_STATIC
|
||||
#define RAINBOW_EXPORT
|
||||
#define RAINBOW_EXPORT
|
||||
#else
|
||||
#ifdef RAINBOW_LIBRARY
|
||||
#define RAINBOW_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
#define RAINBOW_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
#ifdef RAINBOW_LIBRARY
|
||||
#define RAINBOW_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
#define RAINBOW_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
@ -33,8 +33,8 @@
|
||||
|
||||
static inline qreal wrap(qreal a, qreal d = 1.0)
|
||||
{
|
||||
qreal r = fmod(a, d);
|
||||
return (r < 0.0 ? d + r : (r > 0.0 ? r : 0.0));
|
||||
qreal r = fmod(a, d);
|
||||
return (r < 0.0 ? d + r : (r > 0.0 ? r : 0.0));
|
||||
}
|
||||
|
||||
// normalize: like qBound(a, 0.0, 1.0) but without needing the args and with
|
||||
@ -60,306 +60,306 @@ static const qreal yc[3] = {0.34375, 0.5, 0.15625};
|
||||
class KHCY
|
||||
{
|
||||
public:
|
||||
explicit KHCY(const QColor &color)
|
||||
{
|
||||
qreal r = gamma(color.redF());
|
||||
qreal g = gamma(color.greenF());
|
||||
qreal b = gamma(color.blueF());
|
||||
a = color.alphaF();
|
||||
explicit KHCY(const QColor &color)
|
||||
{
|
||||
qreal r = gamma(color.redF());
|
||||
qreal g = gamma(color.greenF());
|
||||
qreal b = gamma(color.blueF());
|
||||
a = color.alphaF();
|
||||
|
||||
// luma component
|
||||
y = lumag(r, g, b);
|
||||
// luma component
|
||||
y = lumag(r, g, b);
|
||||
|
||||
// hue component
|
||||
qreal p = qMax(qMax(r, g), b);
|
||||
qreal n = qMin(qMin(r, g), b);
|
||||
qreal d = 6.0 * (p - n);
|
||||
if (n == p)
|
||||
{
|
||||
h = 0.0;
|
||||
}
|
||||
else if (r == p)
|
||||
{
|
||||
h = ((g - b) / d);
|
||||
}
|
||||
else if (g == p)
|
||||
{
|
||||
h = ((b - r) / d) + (1.0 / 3.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
h = ((r - g) / d) + (2.0 / 3.0);
|
||||
}
|
||||
// hue component
|
||||
qreal p = qMax(qMax(r, g), b);
|
||||
qreal n = qMin(qMin(r, g), b);
|
||||
qreal d = 6.0 * (p - n);
|
||||
if (n == p)
|
||||
{
|
||||
h = 0.0;
|
||||
}
|
||||
else if (r == p)
|
||||
{
|
||||
h = ((g - b) / d);
|
||||
}
|
||||
else if (g == p)
|
||||
{
|
||||
h = ((b - r) / d) + (1.0 / 3.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
h = ((r - g) / d) + (2.0 / 3.0);
|
||||
}
|
||||
|
||||
// chroma component
|
||||
if (r == g && g == b)
|
||||
{
|
||||
c = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = qMax((y - n) / y, (p - y) / (1 - y));
|
||||
}
|
||||
}
|
||||
explicit KHCY(qreal h_, qreal c_, qreal y_, qreal a_ = 1.0)
|
||||
{
|
||||
h = h_;
|
||||
c = c_;
|
||||
y = y_;
|
||||
a = a_;
|
||||
}
|
||||
// chroma component
|
||||
if (r == g && g == b)
|
||||
{
|
||||
c = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = qMax((y - n) / y, (p - y) / (1 - y));
|
||||
}
|
||||
}
|
||||
explicit KHCY(qreal h_, qreal c_, qreal y_, qreal a_ = 1.0)
|
||||
{
|
||||
h = h_;
|
||||
c = c_;
|
||||
y = y_;
|
||||
a = a_;
|
||||
}
|
||||
|
||||
QColor qColor() const
|
||||
{
|
||||
// start with sane component values
|
||||
qreal _h = wrap(h);
|
||||
qreal _c = normalize(c);
|
||||
qreal _y = normalize(y);
|
||||
QColor qColor() const
|
||||
{
|
||||
// start with sane component values
|
||||
qreal _h = wrap(h);
|
||||
qreal _c = normalize(c);
|
||||
qreal _y = normalize(y);
|
||||
|
||||
// calculate some needed variables
|
||||
qreal _hs = _h * 6.0, th, tm;
|
||||
if (_hs < 1.0)
|
||||
{
|
||||
th = _hs;
|
||||
tm = yc[0] + yc[1] * th;
|
||||
}
|
||||
else if (_hs < 2.0)
|
||||
{
|
||||
th = 2.0 - _hs;
|
||||
tm = yc[1] + yc[0] * th;
|
||||
}
|
||||
else if (_hs < 3.0)
|
||||
{
|
||||
th = _hs - 2.0;
|
||||
tm = yc[1] + yc[2] * th;
|
||||
}
|
||||
else if (_hs < 4.0)
|
||||
{
|
||||
th = 4.0 - _hs;
|
||||
tm = yc[2] + yc[1] * th;
|
||||
}
|
||||
else if (_hs < 5.0)
|
||||
{
|
||||
th = _hs - 4.0;
|
||||
tm = yc[2] + yc[0] * th;
|
||||
}
|
||||
else
|
||||
{
|
||||
th = 6.0 - _hs;
|
||||
tm = yc[0] + yc[2] * th;
|
||||
}
|
||||
// calculate some needed variables
|
||||
qreal _hs = _h * 6.0, th, tm;
|
||||
if (_hs < 1.0)
|
||||
{
|
||||
th = _hs;
|
||||
tm = yc[0] + yc[1] * th;
|
||||
}
|
||||
else if (_hs < 2.0)
|
||||
{
|
||||
th = 2.0 - _hs;
|
||||
tm = yc[1] + yc[0] * th;
|
||||
}
|
||||
else if (_hs < 3.0)
|
||||
{
|
||||
th = _hs - 2.0;
|
||||
tm = yc[1] + yc[2] * th;
|
||||
}
|
||||
else if (_hs < 4.0)
|
||||
{
|
||||
th = 4.0 - _hs;
|
||||
tm = yc[2] + yc[1] * th;
|
||||
}
|
||||
else if (_hs < 5.0)
|
||||
{
|
||||
th = _hs - 4.0;
|
||||
tm = yc[2] + yc[0] * th;
|
||||
}
|
||||
else
|
||||
{
|
||||
th = 6.0 - _hs;
|
||||
tm = yc[0] + yc[2] * th;
|
||||
}
|
||||
|
||||
// calculate RGB channels in sorted order
|
||||
qreal tn, to, tp;
|
||||
if (tm >= _y)
|
||||
{
|
||||
tp = _y + _y * _c * (1.0 - tm) / tm;
|
||||
to = _y + _y * _c * (th - tm) / tm;
|
||||
tn = _y - (_y * _c);
|
||||
}
|
||||
else
|
||||
{
|
||||
tp = _y + (1.0 - _y) * _c;
|
||||
to = _y + (1.0 - _y) * _c * (th - tm) / (1.0 - tm);
|
||||
tn = _y - (1.0 - _y) * _c * tm / (1.0 - tm);
|
||||
}
|
||||
// calculate RGB channels in sorted order
|
||||
qreal tn, to, tp;
|
||||
if (tm >= _y)
|
||||
{
|
||||
tp = _y + _y * _c * (1.0 - tm) / tm;
|
||||
to = _y + _y * _c * (th - tm) / tm;
|
||||
tn = _y - (_y * _c);
|
||||
}
|
||||
else
|
||||
{
|
||||
tp = _y + (1.0 - _y) * _c;
|
||||
to = _y + (1.0 - _y) * _c * (th - tm) / (1.0 - tm);
|
||||
tn = _y - (1.0 - _y) * _c * tm / (1.0 - tm);
|
||||
}
|
||||
|
||||
// return RGB channels in appropriate order
|
||||
if (_hs < 1.0)
|
||||
{
|
||||
return QColor::fromRgbF(igamma(tp), igamma(to), igamma(tn), a);
|
||||
}
|
||||
else if (_hs < 2.0)
|
||||
{
|
||||
return QColor::fromRgbF(igamma(to), igamma(tp), igamma(tn), a);
|
||||
}
|
||||
else if (_hs < 3.0)
|
||||
{
|
||||
return QColor::fromRgbF(igamma(tn), igamma(tp), igamma(to), a);
|
||||
}
|
||||
else if (_hs < 4.0)
|
||||
{
|
||||
return QColor::fromRgbF(igamma(tn), igamma(to), igamma(tp), a);
|
||||
}
|
||||
else if (_hs < 5.0)
|
||||
{
|
||||
return QColor::fromRgbF(igamma(to), igamma(tn), igamma(tp), a);
|
||||
}
|
||||
else
|
||||
{
|
||||
return QColor::fromRgbF(igamma(tp), igamma(tn), igamma(to), a);
|
||||
}
|
||||
}
|
||||
// return RGB channels in appropriate order
|
||||
if (_hs < 1.0)
|
||||
{
|
||||
return QColor::fromRgbF(igamma(tp), igamma(to), igamma(tn), a);
|
||||
}
|
||||
else if (_hs < 2.0)
|
||||
{
|
||||
return QColor::fromRgbF(igamma(to), igamma(tp), igamma(tn), a);
|
||||
}
|
||||
else if (_hs < 3.0)
|
||||
{
|
||||
return QColor::fromRgbF(igamma(tn), igamma(tp), igamma(to), a);
|
||||
}
|
||||
else if (_hs < 4.0)
|
||||
{
|
||||
return QColor::fromRgbF(igamma(tn), igamma(to), igamma(tp), a);
|
||||
}
|
||||
else if (_hs < 5.0)
|
||||
{
|
||||
return QColor::fromRgbF(igamma(to), igamma(tn), igamma(tp), a);
|
||||
}
|
||||
else
|
||||
{
|
||||
return QColor::fromRgbF(igamma(tp), igamma(tn), igamma(to), a);
|
||||
}
|
||||
}
|
||||
|
||||
qreal h, c, y, a;
|
||||
static qreal luma(const QColor &color)
|
||||
{
|
||||
return lumag(gamma(color.redF()), gamma(color.greenF()), gamma(color.blueF()));
|
||||
}
|
||||
qreal h, c, y, a;
|
||||
static qreal luma(const QColor &color)
|
||||
{
|
||||
return lumag(gamma(color.redF()), gamma(color.greenF()), gamma(color.blueF()));
|
||||
}
|
||||
|
||||
private:
|
||||
static qreal gamma(qreal n)
|
||||
{
|
||||
return pow(normalize(n), 2.2);
|
||||
}
|
||||
static qreal igamma(qreal n)
|
||||
{
|
||||
return pow(normalize(n), 1.0 / 2.2);
|
||||
}
|
||||
static qreal lumag(qreal r, qreal g, qreal b)
|
||||
{
|
||||
return r * yc[0] + g * yc[1] + b * yc[2];
|
||||
}
|
||||
static qreal gamma(qreal n)
|
||||
{
|
||||
return pow(normalize(n), 2.2);
|
||||
}
|
||||
static qreal igamma(qreal n)
|
||||
{
|
||||
return pow(normalize(n), 1.0 / 2.2);
|
||||
}
|
||||
static qreal lumag(qreal r, qreal g, qreal b)
|
||||
{
|
||||
return r * yc[0] + g * yc[1] + b * yc[2];
|
||||
}
|
||||
};
|
||||
|
||||
static inline qreal mixQreal(qreal a, qreal b, qreal bias)
|
||||
{
|
||||
return a + (b - a) * bias;
|
||||
return a + (b - a) * bias;
|
||||
}
|
||||
//END internal helper functions
|
||||
|
||||
qreal Rainbow::luma(const QColor &color)
|
||||
{
|
||||
return KHCY::luma(color);
|
||||
return KHCY::luma(color);
|
||||
}
|
||||
|
||||
void Rainbow::getHcy(const QColor &color, qreal *h, qreal *c, qreal *y, qreal *a)
|
||||
{
|
||||
if (!c || !h || !y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
KHCY khcy(color);
|
||||
*c = khcy.c;
|
||||
*h = khcy.h;
|
||||
*y = khcy.y;
|
||||
if (a)
|
||||
{
|
||||
*a = khcy.a;
|
||||
}
|
||||
if (!c || !h || !y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
KHCY khcy(color);
|
||||
*c = khcy.c;
|
||||
*h = khcy.h;
|
||||
*y = khcy.y;
|
||||
if (a)
|
||||
{
|
||||
*a = khcy.a;
|
||||
}
|
||||
}
|
||||
|
||||
static qreal contrastRatioForLuma(qreal y1, qreal y2)
|
||||
{
|
||||
if (y1 > y2)
|
||||
{
|
||||
return (y1 + 0.05) / (y2 + 0.05);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (y2 + 0.05) / (y1 + 0.05);
|
||||
}
|
||||
if (y1 > y2)
|
||||
{
|
||||
return (y1 + 0.05) / (y2 + 0.05);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (y2 + 0.05) / (y1 + 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
qreal Rainbow::contrastRatio(const QColor &c1, const QColor &c2)
|
||||
{
|
||||
return contrastRatioForLuma(luma(c1), luma(c2));
|
||||
return contrastRatioForLuma(luma(c1), luma(c2));
|
||||
}
|
||||
|
||||
QColor Rainbow::lighten(const QColor &color, qreal ky, qreal kc)
|
||||
{
|
||||
KHCY c(color);
|
||||
c.y = 1.0 - normalize((1.0 - c.y) * (1.0 - ky));
|
||||
c.c = 1.0 - normalize((1.0 - c.c) * kc);
|
||||
return c.qColor();
|
||||
KHCY c(color);
|
||||
c.y = 1.0 - normalize((1.0 - c.y) * (1.0 - ky));
|
||||
c.c = 1.0 - normalize((1.0 - c.c) * kc);
|
||||
return c.qColor();
|
||||
}
|
||||
|
||||
QColor Rainbow::darken(const QColor &color, qreal ky, qreal kc)
|
||||
{
|
||||
KHCY c(color);
|
||||
c.y = normalize(c.y * (1.0 - ky));
|
||||
c.c = normalize(c.c * kc);
|
||||
return c.qColor();
|
||||
KHCY c(color);
|
||||
c.y = normalize(c.y * (1.0 - ky));
|
||||
c.c = normalize(c.c * kc);
|
||||
return c.qColor();
|
||||
}
|
||||
|
||||
QColor Rainbow::shade(const QColor &color, qreal ky, qreal kc)
|
||||
{
|
||||
KHCY c(color);
|
||||
c.y = normalize(c.y + ky);
|
||||
c.c = normalize(c.c + kc);
|
||||
return c.qColor();
|
||||
KHCY c(color);
|
||||
c.y = normalize(c.y + ky);
|
||||
c.c = normalize(c.c + kc);
|
||||
return c.qColor();
|
||||
}
|
||||
|
||||
static QColor tintHelper(const QColor &base, qreal baseLuma, const QColor &color, qreal amount)
|
||||
{
|
||||
KHCY result(Rainbow::mix(base, color, pow(amount, 0.3)));
|
||||
result.y = mixQreal(baseLuma, result.y, amount);
|
||||
KHCY result(Rainbow::mix(base, color, pow(amount, 0.3)));
|
||||
result.y = mixQreal(baseLuma, result.y, amount);
|
||||
|
||||
return result.qColor();
|
||||
return result.qColor();
|
||||
}
|
||||
|
||||
QColor Rainbow::tint(const QColor &base, const QColor &color, qreal amount)
|
||||
{
|
||||
if (amount <= 0.0)
|
||||
{
|
||||
return base;
|
||||
}
|
||||
if (amount >= 1.0)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
if (qIsNaN(amount))
|
||||
{
|
||||
return base;
|
||||
}
|
||||
if (amount <= 0.0)
|
||||
{
|
||||
return base;
|
||||
}
|
||||
if (amount >= 1.0)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
if (qIsNaN(amount))
|
||||
{
|
||||
return base;
|
||||
}
|
||||
|
||||
qreal baseLuma = luma(base); // cache value because luma call is expensive
|
||||
double ri = contrastRatioForLuma(baseLuma, luma(color));
|
||||
double rg = 1.0 + ((ri + 1.0) * amount * amount * amount);
|
||||
double u = 1.0, l = 0.0;
|
||||
QColor result;
|
||||
for (int i = 12; i; --i)
|
||||
{
|
||||
double a = 0.5 * (l + u);
|
||||
result = tintHelper(base, baseLuma, color, a);
|
||||
double ra = contrastRatioForLuma(baseLuma, luma(result));
|
||||
if (ra > rg)
|
||||
{
|
||||
u = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = a;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
qreal baseLuma = luma(base); // cache value because luma call is expensive
|
||||
double ri = contrastRatioForLuma(baseLuma, luma(color));
|
||||
double rg = 1.0 + ((ri + 1.0) * amount * amount * amount);
|
||||
double u = 1.0, l = 0.0;
|
||||
QColor result;
|
||||
for (int i = 12; i; --i)
|
||||
{
|
||||
double a = 0.5 * (l + u);
|
||||
result = tintHelper(base, baseLuma, color, a);
|
||||
double ra = contrastRatioForLuma(baseLuma, luma(result));
|
||||
if (ra > rg)
|
||||
{
|
||||
u = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = a;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QColor Rainbow::mix(const QColor &c1, const QColor &c2, qreal bias)
|
||||
{
|
||||
if (bias <= 0.0)
|
||||
{
|
||||
return c1;
|
||||
}
|
||||
if (bias >= 1.0)
|
||||
{
|
||||
return c2;
|
||||
}
|
||||
if (qIsNaN(bias))
|
||||
{
|
||||
return c1;
|
||||
}
|
||||
if (bias <= 0.0)
|
||||
{
|
||||
return c1;
|
||||
}
|
||||
if (bias >= 1.0)
|
||||
{
|
||||
return c2;
|
||||
}
|
||||
if (qIsNaN(bias))
|
||||
{
|
||||
return c1;
|
||||
}
|
||||
|
||||
qreal r = mixQreal(c1.redF(), c2.redF(), bias);
|
||||
qreal g = mixQreal(c1.greenF(), c2.greenF(), bias);
|
||||
qreal b = mixQreal(c1.blueF(), c2.blueF(), bias);
|
||||
qreal a = mixQreal(c1.alphaF(), c2.alphaF(), bias);
|
||||
qreal r = mixQreal(c1.redF(), c2.redF(), bias);
|
||||
qreal g = mixQreal(c1.greenF(), c2.greenF(), bias);
|
||||
qreal b = mixQreal(c1.blueF(), c2.blueF(), bias);
|
||||
qreal a = mixQreal(c1.alphaF(), c2.alphaF(), bias);
|
||||
|
||||
return QColor::fromRgbF(r, g, b, a);
|
||||
return QColor::fromRgbF(r, g, b, a);
|
||||
}
|
||||
|
||||
QColor Rainbow::overlayColors(const QColor &base, const QColor &paint,
|
||||
QPainter::CompositionMode comp)
|
||||
QPainter::CompositionMode comp)
|
||||
{
|
||||
// This isn't the fastest way, but should be "fast enough".
|
||||
// It's also the only safe way to use QPainter::CompositionMode
|
||||
QImage img(1, 1, QImage::Format_ARGB32_Premultiplied);
|
||||
QPainter p(&img);
|
||||
QColor start = base;
|
||||
start.setAlpha(255); // opaque
|
||||
p.fillRect(0, 0, 1, 1, start);
|
||||
p.setCompositionMode(comp);
|
||||
p.fillRect(0, 0, 1, 1, paint);
|
||||
p.end();
|
||||
return img.pixel(0, 0);
|
||||
// This isn't the fastest way, but should be "fast enough".
|
||||
// It's also the only safe way to use QPainter::CompositionMode
|
||||
QImage img(1, 1, QImage::Format_ARGB32_Premultiplied);
|
||||
QPainter p(&img);
|
||||
QColor start = base;
|
||||
start.setAlpha(255); // opaque
|
||||
p.fillRect(0, 0, 1, 1, start);
|
||||
p.setCompositionMode(comp);
|
||||
p.fillRect(0, 0, 1, 1, paint);
|
||||
p.end();
|
||||
return img.pixel(0, 0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user