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
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.
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 /* functions that manipulate colors */
40 #include "nsCSSColorUtils.h"
44 // Weird color computing code stolen from winfe which was stolen
45 // from the xfe which was written originally by Eric Bina. So there.
47 #define RED_LUMINOSITY 299
48 #define GREEN_LUMINOSITY 587
49 #define BLUE_LUMINOSITY 114
50 #define INTENSITY_FACTOR 25
51 #define LIGHT_FACTOR 0
52 #define LUMINOSITY_FACTOR 75
55 #define COLOR_DARK_THRESHOLD 51
56 #define COLOR_LIGHT_THRESHOLD 204
58 #define COLOR_LITE_BS_FACTOR 45
59 #define COLOR_LITE_TS_FACTOR 70
61 #define COLOR_DARK_BS_FACTOR 30
62 #define COLOR_DARK_TS_FACTOR 50
64 #define LIGHT_GRAY NS_RGB(192, 192, 192)
65 #define DARK_GRAY NS_RGB(96, 96, 96)
66 #define WHITE NS_RGB(255, 255, 255)
67 #define BLACK NS_RGB(0, 0, 0)
69 #define MAX_BRIGHTNESS 254
70 #define MAX_DARKNESS 0
72 void NS_GetSpecial3DColors(nscolor aResult
[2],
73 nscolor aBackgroundColor
,
80 PRUint8 rb
= NS_GET_R(aBorderColor
);
81 PRUint8 gb
= NS_GET_G(aBorderColor
);
82 PRUint8 bb
= NS_GET_B(aBorderColor
);
84 PRUint8 a
= NS_GET_A(aBorderColor
);
86 // This needs to be optimized.
87 // Calculating background brightness again and again is
88 // a waste of time!!!. Just calculate it only once.
91 PRUint8 red
= NS_GET_R(aBackgroundColor
);
92 PRUint8 green
= NS_GET_G(aBackgroundColor
);
93 PRUint8 blue
= NS_GET_B(aBackgroundColor
);
95 PRUint8 elementBrightness
= NS_GetBrightness(rb
,gb
,bb
);
96 PRUint8 backgroundBrightness
= NS_GetBrightness(red
, green
, blue
);
99 if (backgroundBrightness
< COLOR_DARK_THRESHOLD
) {
100 f0
= COLOR_DARK_BS_FACTOR
;
101 f1
= COLOR_DARK_TS_FACTOR
;
102 if(elementBrightness
== MAX_DARKNESS
)
104 rb
= NS_GET_R(DARK_GRAY
);
105 gb
= NS_GET_G(DARK_GRAY
);
106 bb
= NS_GET_B(DARK_GRAY
);
108 }else if (backgroundBrightness
> COLOR_LIGHT_THRESHOLD
) {
109 f0
= COLOR_LITE_BS_FACTOR
;
110 f1
= COLOR_LITE_TS_FACTOR
;
111 if(elementBrightness
== MAX_BRIGHTNESS
)
113 rb
= NS_GET_R(LIGHT_GRAY
);
114 gb
= NS_GET_G(LIGHT_GRAY
);
115 bb
= NS_GET_B(LIGHT_GRAY
);
118 f0
= COLOR_DARK_BS_FACTOR
+
119 (backgroundBrightness
*
120 (COLOR_LITE_BS_FACTOR
- COLOR_DARK_BS_FACTOR
) / MAX_COLOR
);
121 f1
= COLOR_DARK_TS_FACTOR
+
122 (backgroundBrightness
*
123 (COLOR_LITE_TS_FACTOR
- COLOR_DARK_TS_FACTOR
) / MAX_COLOR
);
127 r
= rb
- (f0
* rb
/ 100);
128 g
= gb
- (f0
* gb
/ 100);
129 b
= bb
- (f0
* bb
/ 100);
130 aResult
[0] = NS_RGBA(r
, g
, b
, a
);
132 r
= rb
+ (f1
* (MAX_COLOR
- rb
) / 100);
133 g
= gb
+ (f1
* (MAX_COLOR
- gb
) / 100);
134 b
= bb
+ (f1
* (MAX_COLOR
- bb
) / 100);
135 aResult
[1] = NS_RGBA(r
, g
, b
, a
);
138 int NS_GetBrightness(PRUint8 aRed
, PRUint8 aGreen
, PRUint8 aBlue
)
141 PRUint8 intensity
= (aRed
+ aGreen
+ aBlue
) / 3;
143 PRUint8 luminosity
= NS_GetLuminosity(NS_RGB(aRed
, aGreen
, aBlue
)) / 1000;
145 return ((intensity
* INTENSITY_FACTOR
) +
146 (luminosity
* LUMINOSITY_FACTOR
)) / 100;
149 PRInt32
NS_GetLuminosity(nscolor aColor
)
151 // When aColor is not opaque, the perceived luminosity will depend
152 // on what color(s) aColor is ultimately drawn on top of, which we
154 NS_ASSERTION(NS_GET_A(aColor
) == 255,
155 "impossible to compute luminosity of a non-opaque color");
157 return (NS_GET_R(aColor
) * RED_LUMINOSITY
+
158 NS_GET_G(aColor
) * GREEN_LUMINOSITY
+
159 NS_GET_B(aColor
) * BLUE_LUMINOSITY
);
162 // Function to convert RGB color space into the HSV colorspace
163 // Hue is the primary color defined from 0 to 359 degrees
164 // Saturation is defined from 0 to 255. The higher the number.. the deeper
165 // the color Value is the brightness of the color. 0 is black, 255 is white.
166 void NS_RGB2HSV(nscolor aColor
, PRUint16
&aHue
, PRUint16
&aSat
,
167 PRUint16
&aValue
, PRUint8
&aAlpha
)
170 PRInt16 delta
, min
, max
, r1
, b1
, g1
;
173 r
= NS_GET_R(aColor
);
174 g
= NS_GET_G(aColor
);
175 b
= NS_GET_B(aColor
);
192 // value or brightness will always be the max of all the colors(RGB)
195 aSat
= (max
!=0)?((delta
*255)/max
):0;
204 hue
=(float)(g1
-b1
)/(float)delta
;
205 } else if (g1
==max
) {
206 hue
= 2.0f
+(float)(b1
-r1
)/(float)delta
;
208 hue
= 4.0f
+(float)(r1
-g1
)/(float)delta
;
221 aHue
= (PRUint16
)hue
;
223 aAlpha
= NS_GET_A(aColor
);
226 // Function to convert HSV color space into the RGB colorspace
227 // Hue is the primary color defined from 0 to 359 degrees
228 // Saturation is defined from 0 to 255. The higher the number.. the deeper
229 // the color Value is the brightness of the color. 0 is black, 255 is white.
230 void NS_HSV2RGB(nscolor
&aColor
, PRUint16 aHue
, PRUint16 aSat
, PRUint16 aValue
,
233 PRUint16 r
= 0, g
= 0, b
= 0;
235 double h
, f
, percent
;
238 // achromatic color, no hue is defined
243 // hue in in degrees around the color wheel defined from
249 // we break the color wheel into 6 areas.. these
250 // areas define how the saturation and value define the color.
251 // reds behave differently than the blues
252 h
= (double)aHue
/ 60.0;
253 i
= (PRUint16
) floor(h
);
255 percent
= ((double)aValue
/255.0); // this needs to be a value from 0 to 1, so a percentage
256 // can be calculated of the saturation.
257 p
= (PRUint16
)(percent
*(255-aSat
));
258 q
= (PRUint16
)(percent
*(255-(aSat
*f
)));
259 t
= (PRUint16
)(percent
*(255-(aSat
*(1.0-f
))));
261 // i is guaranteed to never be larger than 5.
263 case 0: r
= aValue
; g
= t
; b
= p
;break;
264 case 1: r
= q
; g
= aValue
; b
= p
;break;
265 case 2: r
= p
; g
= aValue
; b
= t
;break;
266 case 3: r
= p
; g
= q
; b
= aValue
;break;
267 case 4: r
= t
; g
= p
; b
= aValue
;break;
268 case 5: r
= aValue
; g
= p
; b
= q
;break;
271 aColor
= NS_RGBA(r
, g
, b
, aAlpha
);