00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027 #include "wtf/Platform.h"
00028 #include "Color.h"
00029
00030 #include "PlatformString.h"
00031 #include <math.h>
00032 #include <wtf/Assertions.h>
00033 #include <wtf/MathExtras.h>
00034
00035 #ifdef Q_CC_MSVC
00036 #include <float.h>
00037 #define nextafter(x,y) ((long double)_nextafter((double)(x), (double)(y)))
00038 #define nextafterf(x,y) _nextafter(x,y)
00039 #endif
00040
00041
00042
00043 using namespace std;
00044
00045
00046 #define min(a,b) (((a)<(b)?(a):(b)))
00047 #define max(a,b) (((a)>(b)?(a):(b)))
00048
00049 namespace WebCore {
00050
00051 const RGBA32 lightenedBlack = 0xFF545454;
00052 const RGBA32 darkenedWhite = 0xFFABABAB;
00053
00054 RGBA32 makeRGB(int r, int g, int b)
00055 {
00056 return 0xFF000000 | max(0, min(r, 255)) << 16 | max(0, min(g, 255)) << 8 | max(0, min(b, 255));
00057 }
00058
00059 RGBA32 makeRGBA(int r, int g, int b, int a)
00060 {
00061 return max(0, min(a, 255)) << 24 | max(0, min(r, 255)) << 16 | max(0, min(g, 255)) << 8 | max(0, min(b, 255));
00062 }
00063
00064 static double calcHue(double temp1, double temp2, double hueVal)
00065 {
00066 if (hueVal < 0.0)
00067 hueVal++;
00068 else if (hueVal > 1.0)
00069 hueVal--;
00070 if (hueVal * 6.0 < 1.0)
00071 return temp1 + (temp2 - temp1) * hueVal * 6.0;
00072 if (hueVal * 2.0 < 1.0)
00073 return temp2;
00074 if (hueVal * 3.0 < 2.0)
00075 return temp1 + (temp2 - temp1) * (2.0 / 3.0 - hueVal) * 6.0;
00076 return temp1;
00077 }
00078
00079
00080
00081
00082
00083
00084 RGBA32 makeRGBAFromHSLA(double hue, double saturation, double lightness, double alpha)
00085 {
00086 const double scaleFactor = nextafter(256.0, 0.0);
00087
00088 if (!saturation) {
00089 int greyValue = static_cast<int>(lightness * scaleFactor);
00090 return makeRGBA(greyValue, greyValue, greyValue, static_cast<int>(alpha * scaleFactor));
00091 }
00092
00093 double temp2 = lightness < 0.5 ? lightness * (1.0 + saturation) : lightness + saturation - lightness * saturation;
00094 double temp1 = 2.0 * lightness - temp2;
00095
00096 return makeRGBA(static_cast<int>(calcHue(temp1, temp2, hue + 1.0 / 3.0) * scaleFactor),
00097 static_cast<int>(calcHue(temp1, temp2, hue) * scaleFactor),
00098 static_cast<int>(calcHue(temp1, temp2, hue - 1.0 / 3.0) * scaleFactor),
00099 static_cast<int>(alpha * scaleFactor));
00100 }
00101
00102
00103 bool Color::parseHexColor(const String& name, RGBA32& rgb)
00104 {
00105 unsigned length = name.length();
00106 if (length != 3 && length != 6)
00107 return false;
00108 unsigned value = 0;
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 rgb = 0xFF000000
00121 | (value & 0xF00) << 12 | (value & 0xF00) << 8
00122 | (value & 0xF0) << 8 | (value & 0xF0) << 4
00123 | (value & 0xF) << 4 | (value & 0xF);
00124 return true;
00125 }
00126
00127 int differenceSquared(const Color& c1, const Color& c2)
00128 {
00129 int dR = c1.red() - c2.red();
00130 int dG = c1.green() - c2.green();
00131 int dB = c1.blue() - c2.blue();
00132 return dR * dR + dG * dG + dB * dB;
00133 }
00134
00135 Color::Color(const String& name)
00136 {
00137
00138
00139
00140 setNamedColor(name);
00141 }
00142
00143 Color::Color(const char* name)
00144 {
00145
00146
00147
00148
00149
00150
00151
00152
00153 }
00154
00155 String Color::name() const
00156 {
00157
00158
00159
00160 return "";
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 void Color::setNamedColor(const String& name)
00180 {
00181
00182
00183
00184
00185 }
00186
00187 Color Color::light() const
00188 {
00189
00190 if (m_color == black)
00191 return lightenedBlack;
00192
00193 const float scaleFactor = nextafterf(256.0f, 0.0f);
00194
00195 float r, g, b, a;
00196 getRGBA(r, g, b, a);
00197
00198 float v = max(r, max(g, b));
00199
00200 if (v == 0.0f)
00201
00202 return Color(0x54, 0x54, 0x54, alpha());
00203
00204 float multiplier = min(1.0f, v + 0.33f) / v;
00205
00206 return Color(static_cast<int>(multiplier * r * scaleFactor),
00207 static_cast<int>(multiplier * g * scaleFactor),
00208 static_cast<int>(multiplier * b * scaleFactor),
00209 alpha());
00210 }
00211
00212 Color Color::dark() const
00213 {
00214
00215 if (m_color == white)
00216 return darkenedWhite;
00217
00218 const float scaleFactor = nextafterf(256.0f, 0.0f);
00219
00220 float r, g, b, a;
00221 getRGBA(r, g, b, a);
00222
00223 float v = max(r, max(g, b));
00224 float multiplier = max(0.0f, (v - 0.33f) / v);
00225
00226 return Color(static_cast<int>(multiplier * r * scaleFactor),
00227 static_cast<int>(multiplier * g * scaleFactor),
00228 static_cast<int>(multiplier * b * scaleFactor),
00229 alpha());
00230 }
00231
00232 static int blendComponent(int c, int a)
00233 {
00234
00235 float alpha = a / 255.0f;
00236 int whiteBlend = 255 - a;
00237 c -= whiteBlend;
00238 return static_cast<int>(c / alpha);
00239 }
00240
00241 const int cStartAlpha = 153;
00242 const int cEndAlpha = 204;
00243 const int cAlphaIncrement = 17;
00244
00245 Color Color::blend(const Color& source) const
00246 {
00247 if (!alpha() || !source.hasAlpha())
00248 return source;
00249
00250 if (!source.alpha())
00251 return *this;
00252
00253 int d = 255 * (alpha() + source.alpha()) - alpha() * source.alpha();
00254 int a = d / 255;
00255 int r = (red() * alpha() * (255 - source.alpha()) + 255 * source.alpha() * source.red()) / d;
00256 int g = (green() * alpha() * (255 - source.alpha()) + 255 * source.alpha() * source.green()) / d;
00257 int b = (blue() * alpha() * (255 - source.alpha()) + 255 * source.alpha() * source.blue()) / d;
00258 return Color(r, g, b, a);
00259 }
00260
00261 Color Color::blendWithWhite() const
00262 {
00263
00264 if (hasAlpha())
00265 return *this;
00266
00267 Color newColor;
00268 for (int alpha = cStartAlpha; alpha <= cEndAlpha; alpha += cAlphaIncrement) {
00269
00270
00271 int r = blendComponent(red(), alpha);
00272 int g = blendComponent(green(), alpha);
00273 int b = blendComponent(blue(), alpha);
00274
00275 newColor = Color(r, g, b, alpha);
00276
00277 if (r >= 0 && g >= 0 && b >= 0)
00278 break;
00279 }
00280 return newColor;
00281 }
00282
00283 void Color::getRGBA(float& r, float& g, float& b, float& a) const
00284 {
00285 r = red() / 255.0f;
00286 g = green() / 255.0f;
00287 b = blue() / 255.0f;
00288 a = alpha() / 255.0f;
00289 }
00290
00291 void Color::getRGBA(double& r, double& g, double& b, double& a) const
00292 {
00293 r = red() / 255.0;
00294 g = green() / 255.0;
00295 b = blue() / 255.0;
00296 a = alpha() / 255.0;
00297 }
00298
00299 }