Bug 426214, automatically sync Firefox's blocklist.xml from AMO (running on egg like...
[mozilla-1.9.git] / gfx / src / nsColor.cpp
blob1e3c08ee64ddf32e79a0d52d628c8d2859490b26
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "plstr.h"
39 #include "nsColor.h"
40 #include "nsColorNames.h"
41 #include "nsString.h"
42 #include "nscore.h"
43 #include "nsCoord.h"
44 #include "nsCOMPtr.h"
45 #include "nsIServiceManager.h"
46 #include <math.h>
47 #include "prprf.h"
49 static int ComponentValue(const PRUnichar* aColorSpec, int aLen, int color, int dpc)
51 int component = 0;
52 int index = (color * dpc);
53 if (2 < dpc) {
54 dpc = 2;
56 while (--dpc >= 0) {
57 PRUnichar ch = ((index < aLen) ? aColorSpec[index++] : '0');
58 if (('0' <= ch) && (ch <= '9')) {
59 component = (component * 16) + (ch - '0');
60 } else if ((('a' <= ch) && (ch <= 'f')) ||
61 (('A' <= ch) && (ch <= 'F'))) {
62 // "ch&7" handles lower and uppercase hex alphabetics
63 component = (component * 16) + (ch & 7) + 9;
65 else { // not a hex digit, treat it like 0
66 component = (component * 16);
69 return component;
72 NS_GFX_(PRBool) NS_HexToRGB(const nsString& aColorSpec,
73 nscolor* aResult)
75 const PRUnichar* buffer = aColorSpec.get();
77 int nameLen = aColorSpec.Length();
78 if ((nameLen == 3) || (nameLen == 6)) {
79 // Make sure the digits are legal
80 for (int i = 0; i < nameLen; i++) {
81 PRUnichar ch = buffer[i];
82 if (((ch >= '0') && (ch <= '9')) ||
83 ((ch >= 'a') && (ch <= 'f')) ||
84 ((ch >= 'A') && (ch <= 'F'))) {
85 // Legal character
86 continue;
88 // Whoops. Illegal character.
89 return PR_FALSE;
92 // Convert the ascii to binary
93 int dpc = ((3 == nameLen) ? 1 : 2);
94 // Translate components from hex to binary
95 int r = ComponentValue(buffer, nameLen, 0, dpc);
96 int g = ComponentValue(buffer, nameLen, 1, dpc);
97 int b = ComponentValue(buffer, nameLen, 2, dpc);
98 if (dpc == 1) {
99 // Scale single digit component to an 8 bit value. Replicate the
100 // single digit to compute the new value.
101 r = (r << 4) | r;
102 g = (g << 4) | g;
103 b = (b << 4) | b;
105 NS_ASSERTION((r >= 0) && (r <= 255), "bad r");
106 NS_ASSERTION((g >= 0) && (g <= 255), "bad g");
107 NS_ASSERTION((b >= 0) && (b <= 255), "bad b");
108 if (nsnull != aResult) {
109 *aResult = NS_RGB(r, g, b);
111 return PR_TRUE;
114 // Improperly formatted color value
115 return PR_FALSE;
118 // compatible with legacy Nav behavior
119 NS_GFX_(PRBool) NS_LooseHexToRGB(const nsString& aColorSpec, nscolor* aResult)
121 int nameLen = aColorSpec.Length();
122 const PRUnichar* colorSpec = aColorSpec.get();
123 if ('#' == colorSpec[0]) {
124 ++colorSpec;
125 --nameLen;
128 if (3 < nameLen) {
129 // Convert the ascii to binary
130 int dpc = (nameLen / 3) + (((nameLen % 3) != 0) ? 1 : 0);
131 if (4 < dpc) {
132 dpc = 4;
135 // Translate components from hex to binary
136 int r = ComponentValue(colorSpec, nameLen, 0, dpc);
137 int g = ComponentValue(colorSpec, nameLen, 1, dpc);
138 int b = ComponentValue(colorSpec, nameLen, 2, dpc);
139 NS_ASSERTION((r >= 0) && (r <= 255), "bad r");
140 NS_ASSERTION((g >= 0) && (g <= 255), "bad g");
141 NS_ASSERTION((b >= 0) && (b <= 255), "bad b");
142 if (nsnull != aResult) {
143 *aResult = NS_RGB(r, g, b);
146 else {
147 if (nsnull != aResult) {
148 *aResult = NS_RGB(0, 0, 0);
151 return PR_TRUE;
154 NS_GFX_(void) NS_RGBToHex(nscolor aColor, nsAString& aResult)
156 char buf[10];
157 PR_snprintf(buf, sizeof(buf), "#%02x%02x%02x",
158 NS_GET_R(aColor), NS_GET_G(aColor), NS_GET_B(aColor));
159 CopyASCIItoUTF16(buf, aResult);
162 NS_GFX_(PRBool) NS_ColorNameToRGB(const nsAString& aColorName, nscolor* aResult)
164 nsColorName id = nsColorNames::LookupName(aColorName);
165 if (eColorName_UNKNOWN < id) {
166 NS_ASSERTION(id < eColorName_COUNT, "LookupName mess up");
167 if (nsnull != aResult) {
168 *aResult = nsColorNames::kColors[id];
170 return PR_TRUE;
172 return PR_FALSE;
175 NS_GFX_(nscolor)
176 NS_ComposeColors(nscolor aBG, nscolor aFG)
178 PRIntn bgAlpha = NS_GET_A(aBG);
179 PRIntn r, g, b, a;
181 // First compute what we get drawing aBG onto RGBA(0,0,0,0)
182 MOZ_BLEND(r, 0, NS_GET_R(aBG), bgAlpha);
183 MOZ_BLEND(g, 0, NS_GET_G(aBG), bgAlpha);
184 MOZ_BLEND(b, 0, NS_GET_B(aBG), bgAlpha);
185 a = bgAlpha;
187 // Now draw aFG on top of that
188 PRIntn fgAlpha = NS_GET_A(aFG);
189 MOZ_BLEND(r, r, NS_GET_R(aFG), fgAlpha);
190 MOZ_BLEND(g, g, NS_GET_G(aFG), fgAlpha);
191 MOZ_BLEND(b, b, NS_GET_B(aFG), fgAlpha);
192 MOZ_BLEND(a, a, 255, fgAlpha);
194 return NS_RGBA(r, g, b, a);
197 // Functions to convert from HSL color space to RGB color space.
198 // This is the algorithm described in the CSS3 specification
200 // helper
201 static float
202 HSL_HueToRGB(float m1, float m2, float h)
204 if (h < 0.0f)
205 h += 1.0f;
206 if (h > 1.0f)
207 h -= 1.0f;
208 if (h < (float)(1.0/6.0))
209 return m1 + (m2 - m1)*h*6.0f;
210 if (h < (float)(1.0/2.0))
211 return m2;
212 if (h < (float)(2.0/3.0))
213 return m1 + (m2 - m1)*((float)(2.0/3.0) - h)*6.0f;
214 return m1;
217 // The float parameters are all expected to be in the range 0-1
218 NS_GFX_(nscolor)
219 NS_HSL2RGB(float h, float s, float l)
221 PRUint8 r, g, b;
222 float m1, m2;
223 if (l <= 0.5f) {
224 m2 = l*(s+1);
225 } else {
226 m2 = l + s - l*s;
228 m1 = l*2 - m2;
229 r = PRUint8(255 * HSL_HueToRGB(m1, m2, h + 1.0f/3.0f));
230 g = PRUint8(255 * HSL_HueToRGB(m1, m2, h));
231 b = PRUint8(255 * HSL_HueToRGB(m1, m2, h - 1.0f/3.0f));
232 return NS_RGB(r, g, b);