00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <kcolorutils.h>
00022 #include "kcolorspaces.h"
00023 #include "kcolorhelpers_p.h"
00024
00025 #include <QColor>
00026 #include <QImage>
00027
00028 #include <math.h>
00029
00030
00031 static inline qreal mixQreal(qreal a, qreal b, qreal bias)
00032 {
00033 return a + (b - a) * bias;
00034 }
00035
00036
00037 qreal KColorUtils::luma(const QColor &color)
00038 {
00039 return KColorSpaces::KHCY::luma(color);
00040 }
00041
00042 qreal KColorUtils::contrastRatio(const QColor &c1, const QColor &c2)
00043 {
00044 qreal y1 = luma(c1), y2 = luma(c2);
00045 if (y1 > y2)
00046 return (y1 + 0.05) / (y2 + 0.05);
00047 else
00048 return (y2 + 0.05) / (y1 + 0.05);
00049 }
00050
00051 QColor KColorUtils::lighten(const QColor &color, qreal ky, qreal kc)
00052 {
00053 KColorSpaces::KHCY c(color);
00054 c.y = 1.0 - normalize((1.0 - c.y) * (1.0 - ky));
00055 c.c = 1.0 - normalize((1.0 - c.c) * kc);
00056 return c.qColor();
00057 }
00058
00059 QColor KColorUtils::darken(const QColor &color, qreal ky, qreal kc)
00060 {
00061 KColorSpaces::KHCY c(color);
00062 c.y = normalize(c.y * (1.0 - ky));
00063 c.c = normalize(c.c * kc);
00064 return c.qColor();
00065 }
00066
00067 QColor KColorUtils::shade(const QColor &color, qreal ky, qreal kc)
00068 {
00069 KColorSpaces::KHCY c(color);
00070 c.y = normalize(c.y + ky);
00071 c.c = normalize(c.c + kc);
00072 return c.qColor();
00073 }
00074
00075 QColor tintHelper(const QColor &base, const QColor &color, qreal amount)
00076 {
00077 KColorSpaces::KHCY result(KColorUtils::mix(base, color, pow(amount, 0.3)));
00078 result.y = mixQreal(KColorUtils::luma(base), result.y, amount);
00079
00080 return result.qColor();
00081 }
00082
00083 QColor KColorUtils::tint(const QColor &base, const QColor &color, qreal amount)
00084 {
00085 if (amount <= 0.0) return base;
00086 if (amount >= 1.0) return color;
00087 if (isnan(amount)) return base;
00088
00089 double ri = contrastRatio(base, color);
00090 double rg = 1.0 + ((ri + 1.0) * amount * amount * amount);
00091 double u = 1.0, l = 0.0;
00092 QColor result;
00093 for (int i = 12 ; i ; --i) {
00094 double a = 0.5 * (l+u);
00095 result = tintHelper(base, color, a);
00096 double ra = contrastRatio(base, result);
00097 if (ra > rg)
00098 u = a;
00099 else
00100 l = a;
00101 }
00102 return result;
00103 }
00104
00105 QColor KColorUtils::mix(const QColor &c1, const QColor &c2, qreal bias)
00106 {
00107 if (bias <= 0.0) return c1;
00108 if (bias >= 1.0) return c2;
00109 if (isnan(bias)) return c1;
00110
00111 qreal r = mixQreal(c1.redF(), c2.redF(), bias);
00112 qreal g = mixQreal(c1.greenF(), c2.greenF(), bias);
00113 qreal b = mixQreal(c1.blueF(), c2.blueF(), bias);
00114 qreal a = mixQreal(c1.alphaF(), c2.alphaF(), bias);
00115
00116 return QColor::fromRgbF(r, g, b, a);
00117 }
00118
00119 QColor KColorUtils::overlayColors(const QColor &base, const QColor &paint,
00120 QPainter::CompositionMode comp)
00121 {
00122
00123
00124 QImage img(1, 1, QImage::Format_ARGB32_Premultiplied);
00125 QPainter p(&img);
00126 QColor start = base;
00127 start.setAlpha(255);
00128 p.fillRect(0, 0, 1, 1, start);
00129 p.setCompositionMode(comp);
00130 p.fillRect(0, 0, 1, 1, paint);
00131 p.end();
00132 return img.pixel(0, 0);
00133 }
00134