18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Color.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include "HashTools.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h> 312bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/HexNumber.h> 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/MathExtras.h> 332bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/text/StringBuilder.h> 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if !COMPILER(MSVC) 40635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectconst RGBA32 Color::black; 41635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectconst RGBA32 Color::white; 42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectconst RGBA32 Color::darkGray; 43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectconst RGBA32 Color::gray; 44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectconst RGBA32 Color::lightGray; 45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectconst RGBA32 Color::transparent; 46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 47635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 48635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic const RGBA32 lightenedBlack = 0xFF545454; 49635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic const RGBA32 darkenedWhite = 0xFFABABAB; 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRGBA32 makeRGB(int r, int g, int b) 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0xFF000000 | max(0, min(r, 255)) << 16 | max(0, min(g, 255)) << 8 | max(0, min(b, 255)); 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRGBA32 makeRGBA(int r, int g, int b, int a) 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return max(0, min(a, 255)) << 24 | max(0, min(r, 255)) << 16 | max(0, min(g, 255)) << 8 | max(0, min(b, 255)); 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 61635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic int colorFloatToRGBAByte(float f) 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We use lroundf and 255 instead of nextafterf(256, 0) to match CG's rounding 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return max(0, min(static_cast<int>(lroundf(255.0f * f)), 255)); 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRGBA32 makeRGBA32FromFloats(float r, float g, float b, float a) 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return colorFloatToRGBAByte(a) << 24 | colorFloatToRGBAByte(r) << 16 | colorFloatToRGBAByte(g) << 8 | colorFloatToRGBAByte(b); 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRGBA32 colorWithOverrideAlpha(RGBA32 color, float overrideAlpha) 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RGBA32 rgbOnly = color & 0x00FFFFFF; 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RGBA32 rgba = rgbOnly | colorFloatToRGBAByte(overrideAlpha) << 24; 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return rgba; 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic double calcHue(double temp1, double temp2, double hueVal) 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hueVal < 0.0) 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hueVal++; 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (hueVal > 1.0) 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hueVal--; 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hueVal * 6.0 < 1.0) 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return temp1 + (temp2 - temp1) * hueVal * 6.0; 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hueVal * 2.0 < 1.0) 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return temp2; 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hueVal * 3.0 < 2.0) 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return temp1 + (temp2 - temp1) * (2.0 / 3.0 - hueVal) * 6.0; 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return temp1; 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Explanation of this algorithm can be found in the CSS3 Color Module 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// specification at http://www.w3.org/TR/css3-color/#hsl-color with further 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// explanation available at http://en.wikipedia.org/wiki/HSL_color_space 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// all values are in the range of 0 to 1.0 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRGBA32 makeRGBAFromHSLA(double hue, double saturation, double lightness, double alpha) 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const double scaleFactor = nextafter(256.0, 0.0); 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!saturation) { 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int greyValue = static_cast<int>(lightness * scaleFactor); 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return makeRGBA(greyValue, greyValue, greyValue, static_cast<int>(alpha * scaleFactor)); 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project double temp2 = lightness < 0.5 ? lightness * (1.0 + saturation) : lightness + saturation - lightness * saturation; 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project double temp1 = 2.0 * lightness - temp2; 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return makeRGBA(static_cast<int>(calcHue(temp1, temp2, hue + 1.0 / 3.0) * scaleFactor), 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static_cast<int>(calcHue(temp1, temp2, hue) * scaleFactor), 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static_cast<int>(calcHue(temp1, temp2, hue - 1.0 / 3.0) * scaleFactor), 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static_cast<int>(alpha * scaleFactor)); 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRGBA32 makeRGBAFromCMYKA(float c, float m, float y, float k, float a) 1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double colors = 1 - k; 1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int r = static_cast<int>(nextafter(256, 0) * (colors * (1 - c))); 1218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int g = static_cast<int>(nextafter(256, 0) * (colors * (1 - m))); 1228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int b = static_cast<int>(nextafter(256, 0) * (colors * (1 - y))); 1238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return makeRGBA(r, g, b, static_cast<float>(nextafter(256, 0) * a)); 1248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 1258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// originally moved here from the CSS parser 127e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool Color::parseHexColor(const UChar* name, unsigned length, RGBA32& rgb) 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (length != 3 && length != 6) 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned value = 0; 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i < length; ++i) { 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!isASCIIHexDigit(name[i])) 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value <<= 4; 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value |= toASCIIHexValue(name[i]); 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (length == 6) { 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rgb = 0xFF000000 | value; 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // #abc converts to #aabbcc 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rgb = 0xFF000000 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | (value & 0xF00) << 12 | (value & 0xF00) << 8 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | (value & 0xF0) << 8 | (value & 0xF0) << 4 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | (value & 0xF) << 4 | (value & 0xF); 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 150e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool Color::parseHexColor(const String& name, RGBA32& rgb) 151e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 152e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return parseHexColor(name.characters(), name.length(), rgb); 153e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 154e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint differenceSquared(const Color& c1, const Color& c2) 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dR = c1.red() - c2.red(); 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dG = c1.green() - c2.green(); 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dB = c1.blue() - c2.blue(); 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dR * dR + dG * dG + dB * dB; 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectColor::Color(const String& name) 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 165e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (name[0] == '#') 166e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_valid = parseHexColor(name.characters() + 1, name.length() - 1, m_color); 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setNamedColor(name); 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectColor::Color(const char* name) 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (name[0] == '#') 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_valid = parseHexColor(&name[1], m_color); 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const NamedColor* foundColor = findColor(name, strlen(name)); 177a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_color = foundColor ? foundColor->ARGBValue : 0; 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_valid = foundColor; 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 182e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockString Color::serialized() const 183e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{ 18481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch DEFINE_STATIC_LOCAL(const String, commaSpace, (", ")); 18581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch DEFINE_STATIC_LOCAL(const String, rgbaParen, ("rgba(")); 18681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch DEFINE_STATIC_LOCAL(const String, zeroPointZero, ("0.0")); 18781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 18881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!hasAlpha()) { 1892bde8e466a4451c7319e3a072d118917957d6554Steve Block StringBuilder builder; 1902bde8e466a4451c7319e3a072d118917957d6554Steve Block builder.reserveCapacity(7); 1912bde8e466a4451c7319e3a072d118917957d6554Steve Block builder.append('#'); 1922bde8e466a4451c7319e3a072d118917957d6554Steve Block appendByteAsHex(red(), builder, Lowercase); 1932bde8e466a4451c7319e3a072d118917957d6554Steve Block appendByteAsHex(green(), builder, Lowercase); 1942bde8e466a4451c7319e3a072d118917957d6554Steve Block appendByteAsHex(blue(), builder, Lowercase); 1952bde8e466a4451c7319e3a072d118917957d6554Steve Block return builder.toString(); 19681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 19781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 19881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Vector<UChar> result; 19981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch result.reserveInitialCapacity(28); 20081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 20181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch append(result, rgbaParen); 20281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch appendNumber(result, red()); 20381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch append(result, commaSpace); 20481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch appendNumber(result, green()); 20581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch append(result, commaSpace); 20681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch appendNumber(result, blue()); 20781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch append(result, commaSpace); 208e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 209e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // Match Gecko ("0.0" for zero, 5 decimals for anything else) 210e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (!alpha()) 21181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch append(result, zeroPointZero); 21281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch else 21381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch append(result, String::format("%.5f", alpha() / 255.0f)); 214e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 21581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch result.append(')'); 21681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return String::adopt(result); 217e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} 218e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 21981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochString Color::nameForRenderTreeAsText() const 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (alpha() < 0xFF) 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return String::format("#%02X%02X%02X%02X", red(), green(), blue(), alpha()); 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return String::format("#%02X%02X%02X", red(), green(), blue()); 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline const NamedColor* findNamedColor(const String& name) 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char buffer[64]; // easily big enough for the longest color name 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned length = name.length(); 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (length > sizeof(buffer) - 1) 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i < length; ++i) { 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar c = name[i]; 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!c || c > 0x7F) 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project buffer[i] = toASCIILower(static_cast<char>(c)); 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project buffer[length] = '\0'; 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return findColor(buffer, length); 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Color::setNamedColor(const String& name) 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const NamedColor* foundColor = findNamedColor(name); 245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_color = foundColor ? foundColor->ARGBValue : 0; 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_valid = foundColor; 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectColor Color::light() const 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Hardcode this common case for speed. 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_color == black) 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return lightenedBlack; 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const float scaleFactor = nextafterf(256.0f, 0.0f); 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float r, g, b, a; 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project getRGBA(r, g, b, a); 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float v = max(r, max(g, b)); 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (v == 0.0f) 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Lightened black with alpha. 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Color(0x54, 0x54, 0x54, alpha()); 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float multiplier = min(1.0f, v + 0.33f) / v; 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Color(static_cast<int>(multiplier * r * scaleFactor), 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static_cast<int>(multiplier * g * scaleFactor), 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static_cast<int>(multiplier * b * scaleFactor), 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project alpha()); 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectColor Color::dark() const 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Hardcode this common case for speed. 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_color == white) 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return darkenedWhite; 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const float scaleFactor = nextafterf(256.0f, 0.0f); 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float r, g, b, a; 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project getRGBA(r, g, b, a); 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float v = max(r, max(g, b)); 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float multiplier = max(0.0f, (v - 0.33f) / v); 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Color(static_cast<int>(multiplier * r * scaleFactor), 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static_cast<int>(multiplier * g * scaleFactor), 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static_cast<int>(multiplier * b * scaleFactor), 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project alpha()); 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int blendComponent(int c, int a) 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We use white. 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float alpha = a / 255.0f; 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int whiteBlend = 255 - a; 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project c -= whiteBlend; 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return static_cast<int>(c / alpha); 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int cStartAlpha = 153; // 60% 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int cEndAlpha = 204; // 80%; 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int cAlphaIncrement = 17; // Increments in between. 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectColor Color::blend(const Color& source) const 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!alpha() || !source.hasAlpha()) 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return source; 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!source.alpha()) 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return *this; 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int d = 255 * (alpha() + source.alpha()) - alpha() * source.alpha(); 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int a = d / 255; 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int r = (red() * alpha() * (255 - source.alpha()) + 255 * source.alpha() * source.red()) / d; 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int g = (green() * alpha() * (255 - source.alpha()) + 255 * source.alpha() * source.green()) / d; 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int b = (blue() * alpha() * (255 - source.alpha()) + 255 * source.alpha() * source.blue()) / d; 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Color(r, g, b, a); 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectColor Color::blendWithWhite() const 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the color contains alpha already, we leave it alone. 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasAlpha()) 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return *this; 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Color newColor; 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int alpha = cStartAlpha; alpha <= cEndAlpha; alpha += cAlphaIncrement) { 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have a solid color. Convert to an equivalent color that looks the same when blended with white 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // at the current alpha. Try using less transparency if the numbers end up being negative. 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int r = blendComponent(red(), alpha); 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int g = blendComponent(green(), alpha); 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int b = blendComponent(blue(), alpha); 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newColor = Color(r, g, b, alpha); 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (r >= 0 && g >= 0 && b >= 0) 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return newColor; 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Color::getRGBA(float& r, float& g, float& b, float& a) const 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r = red() / 255.0f; 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project g = green() / 255.0f; 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project b = blue() / 255.0f; 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project a = alpha() / 255.0f; 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Color::getRGBA(double& r, double& g, double& b, double& a) const 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r = red() / 255.0; 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project g = green() / 255.0; 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project b = blue() / 255.0; 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project a = alpha() / 255.0; 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid Color::getHSL(double& hue, double& saturation, double& lightness) const 3625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 3635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // http://en.wikipedia.org/wiki/HSL_color_space. This is a direct copy of 3645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // the algorithm therein, although it's 360^o based and we end up wanting 3655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // [0...1) based. It's clearer if we stick to 360^o until the end. 3665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian double r = static_cast<double>(red()) / 255.0; 3675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian double g = static_cast<double>(green()) / 255.0; 3685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian double b = static_cast<double>(blue()) / 255.0; 3695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian double max = std::max(std::max(r, g), b); 3705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian double min = std::min(std::min(r, g), b); 3715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (max == min) 3735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian hue = 0.0; 3745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else if (max == r) 3755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian hue = (60.0 * ((g - b) / (max - min))) + 360.0; 3765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else if (max == g) 3775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian hue = (60.0 * ((b - r) / (max - min))) + 120.0; 3785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 3795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian hue = (60.0 * ((r - g) / (max - min))) + 240.0; 3805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (hue >= 360.0) 3825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian hue -= 360.0; 3835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // makeRGBAFromHSLA assumes that hue is in [0...1). 3855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian hue /= 360.0; 3865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian lightness = 0.5 * (max + min); 3885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (max == min) 3895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian saturation = 0.0; 3905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else if (lightness <= 0.5) 3915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian saturation = ((max - min) / (max + min)); 3925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 3935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian saturation = ((max - min) / (2.0 - (max + min))); 3945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 3955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianColor colorFromPremultipliedARGB(unsigned pixelColor) 3978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 3988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RGBA32 rgba; 3998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (unsigned alpha = (pixelColor & 0xFF000000) >> 24) { 4018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian rgba = makeRGBA(((pixelColor & 0x00FF0000) >> 16) * 255 / alpha, 4028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ((pixelColor & 0x0000FF00) >> 8) * 255 / alpha, 4038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian (pixelColor & 0x000000FF) * 255 / alpha, 4048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian alpha); 4058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else 4068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian rgba = pixelColor; 4078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return Color(rgba); 4098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 4108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianunsigned premultipliedARGBFromColor(const Color& color) 4128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 4138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian unsigned pixelColor; 4148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (unsigned alpha = color.alpha()) { 4168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian pixelColor = alpha << 24 | 4178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ((color.red() * alpha + 254) / 255) << 16 | 4188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ((color.green() * alpha + 254) / 255) << 8 | 4198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ((color.blue() * alpha + 254) / 255); 4208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else 4218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian pixelColor = color.rgb(); 4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return pixelColor; 4248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 4258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 427