1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/base/nsCSSColorUtils.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,259 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* functions that manipulate colors */ 1.10 + 1.11 +#include "nsCSSColorUtils.h" 1.12 +#include "nsDebug.h" 1.13 +#include <math.h> 1.14 + 1.15 +// Weird color computing code stolen from winfe which was stolen 1.16 +// from the xfe which was written originally by Eric Bina. So there. 1.17 + 1.18 +#define RED_LUMINOSITY 299 1.19 +#define GREEN_LUMINOSITY 587 1.20 +#define BLUE_LUMINOSITY 114 1.21 +#define INTENSITY_FACTOR 25 1.22 +#define LUMINOSITY_FACTOR 75 1.23 + 1.24 +#define MAX_COLOR 255 1.25 +#define COLOR_DARK_THRESHOLD 51 1.26 +#define COLOR_LIGHT_THRESHOLD 204 1.27 + 1.28 +#define COLOR_LITE_BS_FACTOR 45 1.29 +#define COLOR_LITE_TS_FACTOR 70 1.30 + 1.31 +#define COLOR_DARK_BS_FACTOR 30 1.32 +#define COLOR_DARK_TS_FACTOR 50 1.33 + 1.34 +#define LIGHT_GRAY NS_RGB(192, 192, 192) 1.35 +#define DARK_GRAY NS_RGB(96, 96, 96) 1.36 + 1.37 +#define MAX_BRIGHTNESS 254 1.38 +#define MAX_DARKNESS 0 1.39 + 1.40 +void NS_GetSpecial3DColors(nscolor aResult[2], 1.41 + nscolor aBackgroundColor, 1.42 + nscolor aBorderColor) 1.43 +{ 1.44 + 1.45 + uint8_t f0, f1; 1.46 + uint8_t r, g, b; 1.47 + 1.48 + uint8_t rb = NS_GET_R(aBorderColor); 1.49 + uint8_t gb = NS_GET_G(aBorderColor); 1.50 + uint8_t bb = NS_GET_B(aBorderColor); 1.51 + 1.52 + uint8_t a = NS_GET_A(aBorderColor); 1.53 + 1.54 + // This needs to be optimized. 1.55 + // Calculating background brightness again and again is 1.56 + // a waste of time!!!. Just calculate it only once. 1.57 + // .....somehow!!! 1.58 + 1.59 + uint8_t red = NS_GET_R(aBackgroundColor); 1.60 + uint8_t green = NS_GET_G(aBackgroundColor); 1.61 + uint8_t blue = NS_GET_B(aBackgroundColor); 1.62 + 1.63 + uint8_t elementBrightness = NS_GetBrightness(rb,gb,bb); 1.64 + uint8_t backgroundBrightness = NS_GetBrightness(red, green, blue); 1.65 + 1.66 + 1.67 + if (backgroundBrightness < COLOR_DARK_THRESHOLD) { 1.68 + f0 = COLOR_DARK_BS_FACTOR; 1.69 + f1 = COLOR_DARK_TS_FACTOR; 1.70 + if(elementBrightness == MAX_DARKNESS) 1.71 + { 1.72 + rb = NS_GET_R(DARK_GRAY); 1.73 + gb = NS_GET_G(DARK_GRAY); 1.74 + bb = NS_GET_B(DARK_GRAY); 1.75 + } 1.76 + }else if (backgroundBrightness > COLOR_LIGHT_THRESHOLD) { 1.77 + f0 = COLOR_LITE_BS_FACTOR; 1.78 + f1 = COLOR_LITE_TS_FACTOR; 1.79 + if(elementBrightness == MAX_BRIGHTNESS) 1.80 + { 1.81 + rb = NS_GET_R(LIGHT_GRAY); 1.82 + gb = NS_GET_G(LIGHT_GRAY); 1.83 + bb = NS_GET_B(LIGHT_GRAY); 1.84 + } 1.85 + }else { 1.86 + f0 = COLOR_DARK_BS_FACTOR + 1.87 + (backgroundBrightness * 1.88 + (COLOR_LITE_BS_FACTOR - COLOR_DARK_BS_FACTOR) / MAX_COLOR); 1.89 + f1 = COLOR_DARK_TS_FACTOR + 1.90 + (backgroundBrightness * 1.91 + (COLOR_LITE_TS_FACTOR - COLOR_DARK_TS_FACTOR) / MAX_COLOR); 1.92 + } 1.93 + 1.94 + 1.95 + r = rb - (f0 * rb / 100); 1.96 + g = gb - (f0 * gb / 100); 1.97 + b = bb - (f0 * bb / 100); 1.98 + aResult[0] = NS_RGBA(r, g, b, a); 1.99 + 1.100 + r = rb + (f1 * (MAX_COLOR - rb) / 100); 1.101 + g = gb + (f1 * (MAX_COLOR - gb) / 100); 1.102 + b = bb + (f1 * (MAX_COLOR - bb) / 100); 1.103 + aResult[1] = NS_RGBA(r, g, b, a); 1.104 +} 1.105 + 1.106 +int NS_GetBrightness(uint8_t aRed, uint8_t aGreen, uint8_t aBlue) 1.107 +{ 1.108 + 1.109 + uint8_t intensity = (aRed + aGreen + aBlue) / 3; 1.110 + 1.111 + uint8_t luminosity = NS_GetLuminosity(NS_RGB(aRed, aGreen, aBlue)) / 1000; 1.112 + 1.113 + return ((intensity * INTENSITY_FACTOR) + 1.114 + (luminosity * LUMINOSITY_FACTOR)) / 100; 1.115 +} 1.116 + 1.117 +int32_t NS_GetLuminosity(nscolor aColor) 1.118 +{ 1.119 + // When aColor is not opaque, the perceived luminosity will depend 1.120 + // on what color(s) aColor is ultimately drawn on top of, which we 1.121 + // do not know. 1.122 + NS_ASSERTION(NS_GET_A(aColor) == 255, 1.123 + "impossible to compute luminosity of a non-opaque color"); 1.124 + 1.125 + return (NS_GET_R(aColor) * RED_LUMINOSITY + 1.126 + NS_GET_G(aColor) * GREEN_LUMINOSITY + 1.127 + NS_GET_B(aColor) * BLUE_LUMINOSITY); 1.128 +} 1.129 + 1.130 +// Function to convert RGB color space into the HSV colorspace 1.131 +// Hue is the primary color defined from 0 to 359 degrees 1.132 +// Saturation is defined from 0 to 255. The higher the number.. the deeper 1.133 +// the color Value is the brightness of the color. 0 is black, 255 is white. 1.134 +void NS_RGB2HSV(nscolor aColor, uint16_t &aHue, uint16_t &aSat, 1.135 + uint16_t &aValue, uint8_t &aAlpha) 1.136 +{ 1.137 + uint8_t r, g, b; 1.138 + int16_t delta, min, max, r1, b1, g1; 1.139 + float hue; 1.140 + 1.141 + r = NS_GET_R(aColor); 1.142 + g = NS_GET_G(aColor); 1.143 + b = NS_GET_B(aColor); 1.144 + 1.145 + if (r>g) { 1.146 + max = r; 1.147 + min = g; 1.148 + } else { 1.149 + max = g; 1.150 + min = r; 1.151 + } 1.152 + 1.153 + if (b>max) { 1.154 + max = b; 1.155 + } 1.156 + if (b<min) { 1.157 + min = b; 1.158 + } 1.159 + 1.160 + // value or brightness will always be the max of all the colors(RGB) 1.161 + aValue = max; 1.162 + delta = max-min; 1.163 + aSat = (max!=0)?((delta*255)/max):0; 1.164 + r1 = r; 1.165 + b1 = b; 1.166 + g1 = g; 1.167 + 1.168 + if (aSat==0) { 1.169 + hue = 1000; 1.170 + } else { 1.171 + if(r==max){ 1.172 + hue=(float)(g1-b1)/(float)delta; 1.173 + } else if (g1==max) { 1.174 + hue= 2.0f+(float)(b1-r1)/(float)delta; 1.175 + } else { 1.176 + hue = 4.0f+(float)(r1-g1)/(float)delta; 1.177 + } 1.178 + } 1.179 + 1.180 + if(hue<999) { 1.181 + hue*=60; 1.182 + if(hue<0){ 1.183 + hue+=360; 1.184 + } 1.185 + } else { 1.186 + hue=0; 1.187 + } 1.188 + 1.189 + aHue = (uint16_t)hue; 1.190 + 1.191 + aAlpha = NS_GET_A(aColor); 1.192 +} 1.193 + 1.194 +// Function to convert HSV color space into the RGB colorspace 1.195 +// Hue is the primary color defined from 0 to 359 degrees 1.196 +// Saturation is defined from 0 to 255. The higher the number.. the deeper 1.197 +// the color Value is the brightness of the color. 0 is black, 255 is white. 1.198 +void NS_HSV2RGB(nscolor &aColor, uint16_t aHue, uint16_t aSat, uint16_t aValue, 1.199 + uint8_t aAlpha) 1.200 +{ 1.201 + uint16_t r = 0, g = 0, b = 0; 1.202 + uint16_t i, p, q, t; 1.203 + double h, f, percent; 1.204 + 1.205 + if ( aSat == 0 ){ 1.206 + // achromatic color, no hue is defined 1.207 + r = aValue; 1.208 + g = aValue; 1.209 + b = aValue; 1.210 + } else { 1.211 + // hue in in degrees around the color wheel defined from 1.212 + // 0 to 360 degrees. 1.213 + if (aHue >= 360) { 1.214 + aHue = 0; 1.215 + } 1.216 + 1.217 + // we break the color wheel into 6 areas.. these 1.218 + // areas define how the saturation and value define the color. 1.219 + // reds behave differently than the blues 1.220 + h = (double)aHue / 60.0; 1.221 + i = (uint16_t) floor(h); 1.222 + f = h-(double)i; 1.223 + percent = ((double)aValue/255.0); // this needs to be a value from 0 to 1, so a percentage 1.224 + // can be calculated of the saturation. 1.225 + p = (uint16_t)(percent*(255-aSat)); 1.226 + q = (uint16_t)(percent*(255-(aSat*f))); 1.227 + t = (uint16_t)(percent*(255-(aSat*(1.0-f)))); 1.228 + 1.229 + // i is guaranteed to never be larger than 5. 1.230 + switch(i){ 1.231 + case 0: r = aValue; g = t; b = p;break; 1.232 + case 1: r = q; g = aValue; b = p;break; 1.233 + case 2: r = p; g = aValue; b = t;break; 1.234 + case 3: r = p; g = q; b = aValue;break; 1.235 + case 4: r = t; g = p; b = aValue;break; 1.236 + case 5: r = aValue; g = p; b = q;break; 1.237 + } 1.238 + } 1.239 + aColor = NS_RGBA(r, g, b, aAlpha); 1.240 +} 1.241 + 1.242 +#undef RED_LUMINOSITY 1.243 +#undef GREEN_LUMINOSITY 1.244 +#undef BLUE_LUMINOSITY 1.245 +#undef INTENSITY_FACTOR 1.246 +#undef LUMINOSITY_FACTOR 1.247 + 1.248 +#undef MAX_COLOR 1.249 +#undef COLOR_DARK_THRESHOLD 1.250 +#undef COLOR_LIGHT_THRESHOLD 1.251 + 1.252 +#undef COLOR_LITE_BS_FACTOR 1.253 +#undef COLOR_LITE_TS_FACTOR 1.254 + 1.255 +#undef COLOR_DARK_BS_FACTOR 1.256 +#undef COLOR_DARK_TS_FACTOR 1.257 + 1.258 +#undef LIGHT_GRAY 1.259 +#undef DARK_GRAY 1.260 + 1.261 +#undef MAX_BRIGHTNESS 1.262 +#undef MAX_DARKNESS