summaryrefslogtreecommitdiffstats
path: root/layout/base/nsCSSColorUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layout/base/nsCSSColorUtils.cpp')
-rw-r--r--layout/base/nsCSSColorUtils.cpp259
1 files changed, 259 insertions, 0 deletions
diff --git a/layout/base/nsCSSColorUtils.cpp b/layout/base/nsCSSColorUtils.cpp
new file mode 100644
index 000000000..806b7c3cb
--- /dev/null
+++ b/layout/base/nsCSSColorUtils.cpp
@@ -0,0 +1,259 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* functions that manipulate colors */
+
+#include "nsCSSColorUtils.h"
+#include "nsDebug.h"
+#include <math.h>
+
+// Weird color computing code stolen from winfe which was stolen
+// from the xfe which was written originally by Eric Bina. So there.
+
+#define RED_LUMINOSITY 299
+#define GREEN_LUMINOSITY 587
+#define BLUE_LUMINOSITY 114
+#define INTENSITY_FACTOR 25
+#define LUMINOSITY_FACTOR 75
+
+#define MAX_COLOR 255
+#define COLOR_DARK_THRESHOLD 51
+#define COLOR_LIGHT_THRESHOLD 204
+
+#define COLOR_LITE_BS_FACTOR 45
+#define COLOR_LITE_TS_FACTOR 70
+
+#define COLOR_DARK_BS_FACTOR 30
+#define COLOR_DARK_TS_FACTOR 50
+
+#define LIGHT_GRAY NS_RGB(192, 192, 192)
+#define DARK_GRAY NS_RGB(96, 96, 96)
+
+#define MAX_BRIGHTNESS 254
+#define MAX_DARKNESS 0
+
+void NS_GetSpecial3DColors(nscolor aResult[2],
+ nscolor aBackgroundColor,
+ nscolor aBorderColor)
+{
+
+ uint8_t f0, f1;
+ uint8_t r, g, b;
+
+ uint8_t rb = NS_GET_R(aBorderColor);
+ uint8_t gb = NS_GET_G(aBorderColor);
+ uint8_t bb = NS_GET_B(aBorderColor);
+
+ uint8_t a = NS_GET_A(aBorderColor);
+
+ // This needs to be optimized.
+ // Calculating background brightness again and again is
+ // a waste of time!!!. Just calculate it only once.
+ // .....somehow!!!
+
+ uint8_t red = NS_GET_R(aBackgroundColor);
+ uint8_t green = NS_GET_G(aBackgroundColor);
+ uint8_t blue = NS_GET_B(aBackgroundColor);
+
+ uint8_t elementBrightness = NS_GetBrightness(rb,gb,bb);
+ uint8_t backgroundBrightness = NS_GetBrightness(red, green, blue);
+
+
+ if (backgroundBrightness < COLOR_DARK_THRESHOLD) {
+ f0 = COLOR_DARK_BS_FACTOR;
+ f1 = COLOR_DARK_TS_FACTOR;
+ if(elementBrightness == MAX_DARKNESS)
+ {
+ rb = NS_GET_R(DARK_GRAY);
+ gb = NS_GET_G(DARK_GRAY);
+ bb = NS_GET_B(DARK_GRAY);
+ }
+ }else if (backgroundBrightness > COLOR_LIGHT_THRESHOLD) {
+ f0 = COLOR_LITE_BS_FACTOR;
+ f1 = COLOR_LITE_TS_FACTOR;
+ if(elementBrightness == MAX_BRIGHTNESS)
+ {
+ rb = NS_GET_R(LIGHT_GRAY);
+ gb = NS_GET_G(LIGHT_GRAY);
+ bb = NS_GET_B(LIGHT_GRAY);
+ }
+ }else {
+ f0 = COLOR_DARK_BS_FACTOR +
+ (backgroundBrightness *
+ (COLOR_LITE_BS_FACTOR - COLOR_DARK_BS_FACTOR) / MAX_COLOR);
+ f1 = COLOR_DARK_TS_FACTOR +
+ (backgroundBrightness *
+ (COLOR_LITE_TS_FACTOR - COLOR_DARK_TS_FACTOR) / MAX_COLOR);
+ }
+
+
+ r = rb - (f0 * rb / 100);
+ g = gb - (f0 * gb / 100);
+ b = bb - (f0 * bb / 100);
+ aResult[0] = NS_RGBA(r, g, b, a);
+
+ r = rb + (f1 * (MAX_COLOR - rb) / 100);
+ g = gb + (f1 * (MAX_COLOR - gb) / 100);
+ b = bb + (f1 * (MAX_COLOR - bb) / 100);
+ aResult[1] = NS_RGBA(r, g, b, a);
+}
+
+int NS_GetBrightness(uint8_t aRed, uint8_t aGreen, uint8_t aBlue)
+{
+
+ uint8_t intensity = (aRed + aGreen + aBlue) / 3;
+
+ uint8_t luminosity = NS_GetLuminosity(NS_RGB(aRed, aGreen, aBlue)) / 1000;
+
+ return ((intensity * INTENSITY_FACTOR) +
+ (luminosity * LUMINOSITY_FACTOR)) / 100;
+}
+
+int32_t NS_GetLuminosity(nscolor aColor)
+{
+ // When aColor is not opaque, the perceived luminosity will depend
+ // on what color(s) aColor is ultimately drawn on top of, which we
+ // do not know.
+ NS_ASSERTION(NS_GET_A(aColor) == 255,
+ "impossible to compute luminosity of a non-opaque color");
+
+ return (NS_GET_R(aColor) * RED_LUMINOSITY +
+ NS_GET_G(aColor) * GREEN_LUMINOSITY +
+ NS_GET_B(aColor) * BLUE_LUMINOSITY);
+}
+
+// Function to convert RGB color space into the HSV colorspace
+// Hue is the primary color defined from 0 to 359 degrees
+// Saturation is defined from 0 to 255. The higher the number.. the deeper
+// the color Value is the brightness of the color. 0 is black, 255 is white.
+void NS_RGB2HSV(nscolor aColor, uint16_t &aHue, uint16_t &aSat,
+ uint16_t &aValue, uint8_t &aAlpha)
+{
+ uint8_t r, g, b;
+ int16_t delta, min, max, r1, b1, g1;
+ float hue;
+
+ r = NS_GET_R(aColor);
+ g = NS_GET_G(aColor);
+ b = NS_GET_B(aColor);
+
+ if (r>g) {
+ max = r;
+ min = g;
+ } else {
+ max = g;
+ min = r;
+ }
+
+ if (b>max) {
+ max = b;
+ }
+ if (b<min) {
+ min = b;
+ }
+
+ // value or brightness will always be the max of all the colors(RGB)
+ aValue = max;
+ delta = max-min;
+ aSat = (max!=0)?((delta*255)/max):0;
+ r1 = r;
+ b1 = b;
+ g1 = g;
+
+ if (aSat==0) {
+ hue = 1000;
+ } else {
+ if(r==max){
+ hue=(float)(g1-b1)/(float)delta;
+ } else if (g1==max) {
+ hue= 2.0f+(float)(b1-r1)/(float)delta;
+ } else {
+ hue = 4.0f+(float)(r1-g1)/(float)delta;
+ }
+ }
+
+ if(hue<999) {
+ hue*=60;
+ if(hue<0){
+ hue+=360;
+ }
+ } else {
+ hue=0;
+ }
+
+ aHue = (uint16_t)hue;
+
+ aAlpha = NS_GET_A(aColor);
+}
+
+// Function to convert HSV color space into the RGB colorspace
+// Hue is the primary color defined from 0 to 359 degrees
+// Saturation is defined from 0 to 255. The higher the number.. the deeper
+// the color Value is the brightness of the color. 0 is black, 255 is white.
+void NS_HSV2RGB(nscolor &aColor, uint16_t aHue, uint16_t aSat, uint16_t aValue,
+ uint8_t aAlpha)
+{
+ uint16_t r = 0, g = 0, b = 0;
+ uint16_t i, p, q, t;
+ double h, f, percent;
+
+ if ( aSat == 0 ){
+ // achromatic color, no hue is defined
+ r = aValue;
+ g = aValue;
+ b = aValue;
+ } else {
+ // hue in in degrees around the color wheel defined from
+ // 0 to 360 degrees.
+ if (aHue >= 360) {
+ aHue = 0;
+ }
+
+ // we break the color wheel into 6 areas.. these
+ // areas define how the saturation and value define the color.
+ // reds behave differently than the blues
+ h = (double)aHue / 60.0;
+ i = (uint16_t) floor(h);
+ f = h-(double)i;
+ percent = ((double)aValue/255.0); // this needs to be a value from 0 to 1, so a percentage
+ // can be calculated of the saturation.
+ p = (uint16_t)(percent*(255-aSat));
+ q = (uint16_t)(percent*(255-(aSat*f)));
+ t = (uint16_t)(percent*(255-(aSat*(1.0-f))));
+
+ // i is guaranteed to never be larger than 5.
+ switch(i){
+ case 0: r = aValue; g = t; b = p;break;
+ case 1: r = q; g = aValue; b = p;break;
+ case 2: r = p; g = aValue; b = t;break;
+ case 3: r = p; g = q; b = aValue;break;
+ case 4: r = t; g = p; b = aValue;break;
+ case 5: r = aValue; g = p; b = q;break;
+ }
+ }
+ aColor = NS_RGBA(r, g, b, aAlpha);
+}
+
+#undef RED_LUMINOSITY
+#undef GREEN_LUMINOSITY
+#undef BLUE_LUMINOSITY
+#undef INTENSITY_FACTOR
+#undef LUMINOSITY_FACTOR
+
+#undef MAX_COLOR
+#undef COLOR_DARK_THRESHOLD
+#undef COLOR_LIGHT_THRESHOLD
+
+#undef COLOR_LITE_BS_FACTOR
+#undef COLOR_LITE_TS_FACTOR
+
+#undef COLOR_DARK_BS_FACTOR
+#undef COLOR_DARK_TS_FACTOR
+
+#undef LIGHT_GRAY
+#undef DARK_GRAY
+
+#undef MAX_BRIGHTNESS
+#undef MAX_DARKNESS