layout/base/nsCSSColorUtils.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /* functions that manipulate colors */
     8 #include "nsCSSColorUtils.h"
     9 #include "nsDebug.h"
    10 #include <math.h>
    12 // Weird color computing code stolen from winfe which was stolen
    13 // from the xfe which was written originally by Eric Bina. So there.
    15 #define RED_LUMINOSITY        299
    16 #define GREEN_LUMINOSITY      587
    17 #define BLUE_LUMINOSITY       114
    18 #define INTENSITY_FACTOR      25
    19 #define LUMINOSITY_FACTOR     75
    21 #define MAX_COLOR             255
    22 #define COLOR_DARK_THRESHOLD  51
    23 #define COLOR_LIGHT_THRESHOLD 204
    25 #define COLOR_LITE_BS_FACTOR 45
    26 #define COLOR_LITE_TS_FACTOR 70
    28 #define COLOR_DARK_BS_FACTOR 30
    29 #define COLOR_DARK_TS_FACTOR 50
    31 #define LIGHT_GRAY NS_RGB(192, 192, 192)
    32 #define DARK_GRAY  NS_RGB(96, 96, 96)
    34 #define MAX_BRIGHTNESS  254
    35 #define MAX_DARKNESS     0
    37 void NS_GetSpecial3DColors(nscolor aResult[2],
    38                            nscolor aBackgroundColor,
    39                            nscolor aBorderColor)
    40 {
    42   uint8_t f0, f1;
    43   uint8_t r, g, b;
    45   uint8_t rb = NS_GET_R(aBorderColor);
    46   uint8_t gb = NS_GET_G(aBorderColor);
    47   uint8_t bb = NS_GET_B(aBorderColor);
    49   uint8_t a = NS_GET_A(aBorderColor);
    51   // This needs to be optimized.
    52   // Calculating background brightness again and again is 
    53   // a waste of time!!!. Just calculate it only once.
    54   // .....somehow!!!
    56   uint8_t red = NS_GET_R(aBackgroundColor);
    57   uint8_t green = NS_GET_G(aBackgroundColor);
    58   uint8_t blue = NS_GET_B(aBackgroundColor);
    60   uint8_t elementBrightness = NS_GetBrightness(rb,gb,bb);
    61   uint8_t backgroundBrightness = NS_GetBrightness(red, green, blue);
    64   if (backgroundBrightness < COLOR_DARK_THRESHOLD) {
    65     f0 = COLOR_DARK_BS_FACTOR;
    66     f1 = COLOR_DARK_TS_FACTOR;
    67 	if(elementBrightness == MAX_DARKNESS)
    68 	{
    69        rb = NS_GET_R(DARK_GRAY);
    70        gb = NS_GET_G(DARK_GRAY);
    71        bb = NS_GET_B(DARK_GRAY);
    72 	}
    73   }else if (backgroundBrightness > COLOR_LIGHT_THRESHOLD) {
    74     f0 = COLOR_LITE_BS_FACTOR;
    75     f1 = COLOR_LITE_TS_FACTOR;
    76 	if(elementBrightness == MAX_BRIGHTNESS)
    77 	{
    78        rb = NS_GET_R(LIGHT_GRAY);
    79        gb = NS_GET_G(LIGHT_GRAY);
    80        bb = NS_GET_B(LIGHT_GRAY);
    81 	}
    82   }else {
    83     f0 = COLOR_DARK_BS_FACTOR +
    84       (backgroundBrightness *
    85        (COLOR_LITE_BS_FACTOR - COLOR_DARK_BS_FACTOR) / MAX_COLOR);
    86     f1 = COLOR_DARK_TS_FACTOR +
    87       (backgroundBrightness *
    88        (COLOR_LITE_TS_FACTOR - COLOR_DARK_TS_FACTOR) / MAX_COLOR);
    89   }
    92   r = rb - (f0 * rb / 100);
    93   g = gb - (f0 * gb / 100);
    94   b = bb - (f0 * bb / 100);
    95   aResult[0] = NS_RGBA(r, g, b, a);
    97   r = rb + (f1 * (MAX_COLOR - rb) / 100);
    98   g = gb + (f1 * (MAX_COLOR - gb) / 100);
    99   b = bb + (f1 * (MAX_COLOR - bb) / 100);
   100   aResult[1] = NS_RGBA(r, g, b, a);
   101 }
   103 int NS_GetBrightness(uint8_t aRed, uint8_t aGreen, uint8_t aBlue)
   104 {
   106   uint8_t intensity = (aRed + aGreen + aBlue) / 3;
   108   uint8_t luminosity = NS_GetLuminosity(NS_RGB(aRed, aGreen, aBlue)) / 1000;
   110   return ((intensity * INTENSITY_FACTOR) +
   111           (luminosity * LUMINOSITY_FACTOR)) / 100;
   112 }
   114 int32_t NS_GetLuminosity(nscolor aColor)
   115 {
   116   // When aColor is not opaque, the perceived luminosity will depend
   117   // on what color(s) aColor is ultimately drawn on top of, which we
   118   // do not know.
   119   NS_ASSERTION(NS_GET_A(aColor) == 255,
   120                "impossible to compute luminosity of a non-opaque color");
   122   return (NS_GET_R(aColor) * RED_LUMINOSITY +
   123           NS_GET_G(aColor) * GREEN_LUMINOSITY +
   124           NS_GET_B(aColor) * BLUE_LUMINOSITY);
   125 }
   127 // Function to convert RGB color space into the HSV colorspace
   128 // Hue is the primary color defined from 0 to 359 degrees
   129 // Saturation is defined from 0 to 255.  The higher the number.. the deeper
   130 // the color Value is the brightness of the color. 0 is black, 255 is white.
   131 void NS_RGB2HSV(nscolor aColor, uint16_t &aHue, uint16_t &aSat,
   132                 uint16_t &aValue, uint8_t &aAlpha)
   133 {
   134   uint8_t r, g, b;
   135   int16_t delta, min, max, r1, b1, g1;
   136   float   hue;
   138   r = NS_GET_R(aColor);
   139   g = NS_GET_G(aColor);
   140   b = NS_GET_B(aColor);
   142   if (r>g) {
   143     max = r;
   144     min = g;
   145   } else {
   146     max = g;
   147     min = r;
   148   }
   150   if (b>max) {
   151     max = b;
   152   }
   153   if (b<min) {
   154     min = b;
   155   }
   157   // value or brightness will always be the max of all the colors(RGB)
   158   aValue = max;   
   159   delta = max-min;
   160   aSat = (max!=0)?((delta*255)/max):0;
   161   r1 = r;
   162   b1 = b;
   163   g1 = g;
   165   if (aSat==0) {
   166     hue = 1000;
   167   } else {
   168     if(r==max){
   169       hue=(float)(g1-b1)/(float)delta;
   170     } else if (g1==max) {
   171       hue= 2.0f+(float)(b1-r1)/(float)delta;
   172     } else { 
   173       hue = 4.0f+(float)(r1-g1)/(float)delta;
   174     }
   175   }
   177   if(hue<999) {
   178     hue*=60;
   179     if(hue<0){
   180       hue+=360;
   181     }
   182   } else {
   183     hue=0;
   184   }
   186   aHue = (uint16_t)hue;
   188   aAlpha = NS_GET_A(aColor);
   189 }
   191 // Function to convert HSV color space into the RGB colorspace
   192 // Hue is the primary color defined from 0 to 359 degrees
   193 // Saturation is defined from 0 to 255.  The higher the number.. the deeper
   194 // the color Value is the brightness of the color. 0 is black, 255 is white.
   195 void NS_HSV2RGB(nscolor &aColor, uint16_t aHue, uint16_t aSat, uint16_t aValue,
   196                 uint8_t aAlpha)
   197 {
   198   uint16_t  r = 0, g = 0, b = 0;
   199   uint16_t  i, p, q, t;
   200   double    h, f, percent;
   202   if ( aSat == 0 ){
   203     // achromatic color, no hue is defined
   204     r = aValue;
   205     g = aValue;
   206     b = aValue;
   207   } else {
   208     // hue in in degrees around the color wheel defined from
   209     // 0 to 360 degrees.  
   210     if (aHue >= 360) {
   211       aHue = 0;
   212     }
   214     // we break the color wheel into 6 areas.. these
   215     // areas define how the saturation and value define the color.
   216     // reds behave differently than the blues
   217     h = (double)aHue / 60.0;
   218     i = (uint16_t) floor(h);
   219     f = h-(double)i;
   220     percent = ((double)aValue/255.0);   // this needs to be a value from 0 to 1, so a percentage
   221                                         // can be calculated of the saturation.
   222     p = (uint16_t)(percent*(255-aSat));
   223     q = (uint16_t)(percent*(255-(aSat*f)));
   224     t = (uint16_t)(percent*(255-(aSat*(1.0-f))));
   226     // i is guaranteed to never be larger than 5.
   227     switch(i){
   228       case 0: r = aValue; g = t; b = p;break;
   229       case 1: r = q; g = aValue; b = p;break;
   230       case 2: r = p; g = aValue; b = t;break;
   231       case 3: r = p; g = q; b = aValue;break;
   232       case 4: r = t; g = p; b = aValue;break;
   233       case 5: r = aValue; g = p; b = q;break;
   234     }
   235   }
   236   aColor = NS_RGBA(r, g, b, aAlpha);
   237 }
   239 #undef RED_LUMINOSITY
   240 #undef GREEN_LUMINOSITY
   241 #undef BLUE_LUMINOSITY
   242 #undef INTENSITY_FACTOR
   243 #undef LUMINOSITY_FACTOR
   245 #undef MAX_COLOR
   246 #undef COLOR_DARK_THRESHOLD
   247 #undef COLOR_LIGHT_THRESHOLD
   249 #undef COLOR_LITE_BS_FACTOR
   250 #undef COLOR_LITE_TS_FACTOR
   252 #undef COLOR_DARK_BS_FACTOR
   253 #undef COLOR_DARK_TS_FACTOR
   255 #undef LIGHT_GRAY
   256 #undef DARK_GRAY
   258 #undef MAX_BRIGHTNESS
   259 #undef MAX_DARKNESS

mercurial