Bug 1879449 [wpt PR 44489] - [wptrunner] Add `infrastructure/expected-fail/` test...
[gecko.git] / layout / base / nsCSSColorUtils.cpp
blob66e6a333bac167a9d9abbd780ef9e60b03a2de99
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* functions that manipulate colors */
9 #include "nsCSSColorUtils.h"
10 #include "nsDebug.h"
11 #include <math.h>
13 // Weird color computing code stolen from winfe which was stolen
14 // from the xfe which was written originally by Eric Bina. So there.
16 #define RED_LUMINOSITY 299
17 #define GREEN_LUMINOSITY 587
18 #define BLUE_LUMINOSITY 114
19 #define INTENSITY_FACTOR 25
20 #define LUMINOSITY_FACTOR 75
22 void NS_GetSpecial3DColors(nscolor aResult[2], nscolor aBorderColor) {
23 const float kDarkerScale = 2.0f / 3.0f;
25 uint8_t r = NS_GET_R(aBorderColor);
26 uint8_t g = NS_GET_G(aBorderColor);
27 uint8_t b = NS_GET_B(aBorderColor);
28 uint8_t a = NS_GET_A(aBorderColor);
29 if (r == 0 && g == 0 && b == 0) {
30 // 0.3 * black
31 aResult[0] = NS_RGBA(76, 76, 76, a);
32 // 0.7 * black
33 aResult[1] = NS_RGBA(178, 178, 178, a);
34 return;
37 aResult[0] = NS_RGBA(uint8_t(r * kDarkerScale), uint8_t(g * kDarkerScale),
38 uint8_t(b * kDarkerScale), a);
39 aResult[1] = aBorderColor;
42 int NS_GetBrightness(uint8_t aRed, uint8_t aGreen, uint8_t aBlue) {
43 uint8_t intensity = (aRed + aGreen + aBlue) / 3;
45 uint8_t luminosity = NS_GetLuminosity(NS_RGB(aRed, aGreen, aBlue)) / 1000;
47 return ((intensity * INTENSITY_FACTOR) + (luminosity * LUMINOSITY_FACTOR)) /
48 100;
51 int32_t NS_GetLuminosity(nscolor aColor) {
52 // When aColor is not opaque, the perceived luminosity will depend
53 // on what color(s) aColor is ultimately drawn on top of, which we
54 // do not know.
55 NS_ASSERTION(NS_GET_A(aColor) == 255,
56 "impossible to compute luminosity of a non-opaque color");
58 return (NS_GET_R(aColor) * RED_LUMINOSITY +
59 NS_GET_G(aColor) * GREEN_LUMINOSITY +
60 NS_GET_B(aColor) * BLUE_LUMINOSITY);
63 // Function to convert RGB color space into the HSV colorspace
64 // Hue is the primary color defined from 0 to 359 degrees
65 // Saturation is defined from 0 to 255. The higher the number.. the deeper
66 // the color Value is the brightness of the color. 0 is black, 255 is white.
67 void NS_RGB2HSV(nscolor aColor, uint16_t& aHue, uint16_t& aSat,
68 uint16_t& aValue, uint8_t& aAlpha) {
69 uint8_t r, g, b;
70 int16_t delta, min, max, r1, b1, g1;
71 float hue;
73 r = NS_GET_R(aColor);
74 g = NS_GET_G(aColor);
75 b = NS_GET_B(aColor);
77 if (r > g) {
78 max = r;
79 min = g;
80 } else {
81 max = g;
82 min = r;
85 if (b > max) {
86 max = b;
88 if (b < min) {
89 min = b;
92 // value or brightness will always be the max of all the colors(RGB)
93 aValue = max;
94 delta = max - min;
95 aSat = (max != 0) ? ((delta * 255) / max) : 0;
96 r1 = r;
97 b1 = b;
98 g1 = g;
100 if (aSat == 0) {
101 hue = 1000;
102 } else {
103 if (r == max) {
104 hue = (float)(g1 - b1) / (float)delta;
105 } else if (g1 == max) {
106 hue = 2.0f + (float)(b1 - r1) / (float)delta;
107 } else {
108 hue = 4.0f + (float)(r1 - g1) / (float)delta;
112 if (hue < 999) {
113 hue *= 60;
114 if (hue < 0) {
115 hue += 360;
117 } else {
118 hue = 0;
121 aHue = (uint16_t)hue;
123 aAlpha = NS_GET_A(aColor);
126 // Function to convert HSV color space into the RGB colorspace
127 // Hue is the primary color defined from 0 to 359 degrees
128 // Saturation is defined from 0 to 255. The higher the number.. the deeper
129 // the color Value is the brightness of the color. 0 is black, 255 is white.
130 void NS_HSV2RGB(nscolor& aColor, uint16_t aHue, uint16_t aSat, uint16_t aValue,
131 uint8_t aAlpha) {
132 uint16_t r = 0, g = 0, b = 0;
133 uint16_t i, p, q, t;
134 double h, f, percent;
136 if (aSat == 0) {
137 // achromatic color, no hue is defined
138 r = aValue;
139 g = aValue;
140 b = aValue;
141 } else {
142 // hue in in degrees around the color wheel defined from
143 // 0 to 360 degrees.
144 if (aHue >= 360) {
145 aHue = 0;
148 // we break the color wheel into 6 areas.. these
149 // areas define how the saturation and value define the color.
150 // reds behave differently than the blues
151 h = (double)aHue / 60.0;
152 i = (uint16_t)floor(h);
153 f = h - (double)i;
154 percent = ((double)aValue /
155 255.0); // this needs to be a value from 0 to 1, so a percentage
156 // can be calculated of the saturation.
157 p = (uint16_t)(percent * (255 - aSat));
158 q = (uint16_t)(percent * (255 - (aSat * f)));
159 t = (uint16_t)(percent * (255 - (aSat * (1.0 - f))));
161 // i is guaranteed to never be larger than 5.
162 switch (i) {
163 case 0:
164 r = aValue;
165 g = t;
166 b = p;
167 break;
168 case 1:
169 r = q;
170 g = aValue;
171 b = p;
172 break;
173 case 2:
174 r = p;
175 g = aValue;
176 b = t;
177 break;
178 case 3:
179 r = p;
180 g = q;
181 b = aValue;
182 break;
183 case 4:
184 r = t;
185 g = p;
186 b = aValue;
187 break;
188 case 5:
189 r = aValue;
190 g = p;
191 b = q;
192 break;
195 aColor = NS_RGBA(r, g, b, aAlpha);
198 #undef RED_LUMINOSITY
199 #undef GREEN_LUMINOSITY
200 #undef BLUE_LUMINOSITY
201 #undef INTENSITY_FACTOR
202 #undef LUMINOSITY_FACTOR