diff options
Diffstat (limited to 'libraries/rainbow/src/rainbow.cpp')
-rw-r--r-- | libraries/rainbow/src/rainbow.cpp | 187 |
1 files changed, 61 insertions, 126 deletions
diff --git a/libraries/rainbow/src/rainbow.cpp b/libraries/rainbow/src/rainbow.cpp index 9054d71d..5ef19652 100644 --- a/libraries/rainbow/src/rainbow.cpp +++ b/libraries/rainbow/src/rainbow.cpp @@ -25,11 +25,11 @@ #include <QColor> #include <QImage> -#include <QtNumeric> // qIsNaN +#include <QtNumeric> // qIsNaN #include <math.h> -//BEGIN internal helper functions +// BEGIN internal helper functions static inline qreal wrap(qreal a, qreal d = 1.0) { @@ -44,23 +44,21 @@ static inline qreal normalize(qreal a) return (a < 1.0 ? (a > 0.0 ? a : 0.0) : 1.0); } - /////////////////////////////////////////////////////////////////////////////// // HCY color space -#define HCY_REC 709 // use 709 for now +#define HCY_REC 709 // use 709 for now #if HCY_REC == 601 -static const qreal yc[3] = {0.299, 0.587, 0.114}; +static const qreal yc[3] = { 0.299, 0.587, 0.114 }; #elif HCY_REC == 709 -static const qreal yc[3] = {0.2126, 0.7152, 0.0722}; -#else // use Qt values -static const qreal yc[3] = {0.34375, 0.5, 0.15625}; +static const qreal yc[3] = { 0.2126, 0.7152, 0.0722 }; +#else // use Qt values +static const qreal yc[3] = { 0.34375, 0.5, 0.15625 }; #endif -class KHCY -{ -public: - explicit KHCY(const QColor &color) +class KHCY { + public: + explicit KHCY(const QColor& color) { qreal r = gamma(color.redF()); qreal g = gamma(color.greenF()); @@ -74,30 +72,20 @@ public: qreal p = qMax(qMax(r, g), b); qreal n = qMin(qMin(r, g), b); qreal d = 6.0 * (p - n); - if (n == p) - { + if (n == p) { h = 0.0; - } - else if (r == p) - { + } else if (r == p) { h = ((g - b) / d); - } - else if (g == p) - { + } else if (g == p) { h = ((b - r) / d) + (1.0 / 3.0); - } - else - { + } else { h = ((r - g) / d) + (2.0 / 3.0); } // chroma component - if (r == g && g == b) - { + if (r == g && g == b) { c = 0.0; - } - else - { + } else { c = qMax((y - n) / y, (p - y) / (1 - y)); } } @@ -118,145 +106,103 @@ public: // calculate some needed variables qreal _hs = _h * 6.0, th, tm; - if (_hs < 1.0) - { + if (_hs < 1.0) { th = _hs; tm = yc[0] + yc[1] * th; - } - else if (_hs < 2.0) - { + } else if (_hs < 2.0) { th = 2.0 - _hs; tm = yc[1] + yc[0] * th; - } - else if (_hs < 3.0) - { + } else if (_hs < 3.0) { th = _hs - 2.0; tm = yc[1] + yc[2] * th; - } - else if (_hs < 4.0) - { + } else if (_hs < 4.0) { th = 4.0 - _hs; tm = yc[2] + yc[1] * th; - } - else if (_hs < 5.0) - { + } else if (_hs < 5.0) { th = _hs - 4.0; tm = yc[2] + yc[0] * th; - } - else - { + } else { th = 6.0 - _hs; tm = yc[0] + yc[2] * th; } // calculate RGB channels in sorted order qreal tn, to, tp; - if (tm >= _y) - { + if (tm >= _y) { tp = _y + _y * _c * (1.0 - tm) / tm; to = _y + _y * _c * (th - tm) / tm; tn = _y - (_y * _c); - } - else - { + } 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) - { + if (_hs < 1.0) { return QColor::fromRgbF(igamma(tp), igamma(to), igamma(tn), a); - } - else if (_hs < 2.0) - { + } else if (_hs < 2.0) { return QColor::fromRgbF(igamma(to), igamma(tp), igamma(tn), a); - } - else if (_hs < 3.0) - { + } else if (_hs < 3.0) { return QColor::fromRgbF(igamma(tn), igamma(tp), igamma(to), a); - } - else if (_hs < 4.0) - { + } else if (_hs < 4.0) { return QColor::fromRgbF(igamma(tn), igamma(to), igamma(tp), a); - } - else if (_hs < 5.0) - { + } else if (_hs < 5.0) { return QColor::fromRgbF(igamma(to), igamma(tn), igamma(tp), a); - } - else - { + } 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())); - } + 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]; - } + 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 inline qreal mixQreal(qreal a, qreal b, qreal bias) { return a + (b - a) * bias; } -//END internal helper functions +// END internal helper functions -qreal Rainbow::luma(const QColor &color) +qreal Rainbow::luma(const QColor& color) { return KHCY::luma(color); } -void Rainbow::getHcy(const QColor &color, qreal *h, qreal *c, qreal *y, qreal *a) +void Rainbow::getHcy(const QColor& color, qreal* h, qreal* c, qreal* y, qreal* a) { - if (!c || !h || !y) - { + if (!c || !h || !y) { return; } KHCY khcy(color); *c = khcy.c; *h = khcy.h; *y = khcy.y; - if (a) - { + if (a) { *a = khcy.a; } } static qreal contrastRatioForLuma(qreal y1, qreal y2) { - if (y1 > y2) - { + if (y1 > y2) { return (y1 + 0.05) / (y2 + 0.05); - } - else - { + } else { return (y2 + 0.05) / (y1 + 0.05); } } -qreal Rainbow::contrastRatio(const QColor &c1, const QColor &c2) +qreal Rainbow::contrastRatio(const QColor& c1, const QColor& c2) { return contrastRatioForLuma(luma(c1), luma(c2)); } -QColor Rainbow::lighten(const QColor &color, qreal ky, qreal kc) +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)); @@ -264,7 +210,7 @@ QColor Rainbow::lighten(const QColor &color, qreal ky, qreal kc) return c.qColor(); } -QColor Rainbow::darken(const QColor &color, qreal ky, qreal kc) +QColor Rainbow::darken(const QColor& color, qreal ky, qreal kc) { KHCY c(color); c.y = normalize(c.y * (1.0 - ky)); @@ -272,7 +218,7 @@ QColor Rainbow::darken(const QColor &color, qreal ky, qreal kc) return c.qColor(); } -QColor Rainbow::shade(const QColor &color, qreal ky, qreal kc) +QColor Rainbow::shade(const QColor& color, qreal ky, qreal kc) { KHCY c(color); c.y = normalize(c.y + ky); @@ -280,7 +226,7 @@ QColor Rainbow::shade(const QColor &color, qreal ky, qreal kc) return c.qColor(); } -static QColor tintHelper(const QColor &base, qreal baseLuma, const QColor &color, qreal amount) +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); @@ -288,55 +234,45 @@ static QColor tintHelper(const QColor &base, qreal baseLuma, const QColor &color return result.qColor(); } -QColor Rainbow::tint(const QColor &base, const QColor &color, qreal amount) +QColor Rainbow::tint(const QColor& base, const QColor& color, qreal amount) { - if (amount <= 0.0) - { + if (amount <= 0.0) { return base; } - if (amount >= 1.0) - { + if (amount >= 1.0) { return color; } - if (qIsNaN(amount)) - { + if (qIsNaN(amount)) { return base; } - qreal baseLuma = luma(base); // cache value because luma call is expensive + 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) - { + 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) - { + if (ra > rg) { u = a; - } - else - { + } else { l = a; } } return result; } -QColor Rainbow::mix(const QColor &c1, const QColor &c2, qreal bias) +QColor Rainbow::mix(const QColor& c1, const QColor& c2, qreal bias) { - if (bias <= 0.0) - { + if (bias <= 0.0) { return c1; } - if (bias >= 1.0) - { + if (bias >= 1.0) { return c2; } - if (qIsNaN(bias)) - { + if (qIsNaN(bias)) { return c1; } @@ -348,15 +284,14 @@ QColor Rainbow::mix(const QColor &c1, const QColor &c2, qreal bias) return QColor::fromRgbF(r, g, b, a); } -QColor Rainbow::overlayColors(const QColor &base, const QColor &paint, - QPainter::CompositionMode comp) +QColor Rainbow::overlayColors(const QColor& base, const QColor& paint, 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 + start.setAlpha(255); // opaque p.fillRect(0, 0, 1, 1, start); p.setCompositionMode(comp); p.fillRect(0, 0, 1, 1, paint); |