layout/base/nsCSSColorUtils.cpp

changeset 0
6474c204b198
     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

mercurial