forked from mirrors/gecko-dev
		
	 e226046cb8
			
		
	
	
		e226046cb8
		
	
	
	
	
		
			
			# ignore-this-changeset Depends on D28954 Differential Revision: https://phabricator.services.mozilla.com/D28956 --HG-- extra : moz-landing-system : lando
		
			
				
	
	
		
			202 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* 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
 | |
| 
 | |
| void NS_GetSpecial3DColors(nscolor aResult[2], nscolor aBorderColor) {
 | |
|   const float kDarkerScale = 2.0f / 3.0f;
 | |
| 
 | |
|   uint8_t r = NS_GET_R(aBorderColor);
 | |
|   uint8_t g = NS_GET_G(aBorderColor);
 | |
|   uint8_t b = NS_GET_B(aBorderColor);
 | |
|   uint8_t a = NS_GET_A(aBorderColor);
 | |
|   if (r == 0 && g == 0 && b == 0) {
 | |
|     // 0.3 * black
 | |
|     aResult[0] = NS_RGBA(76, 76, 76, a);
 | |
|     // 0.7 * black
 | |
|     aResult[1] = NS_RGBA(178, 178, 178, a);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   aResult[0] = NS_RGBA(uint8_t(r * kDarkerScale), uint8_t(g * kDarkerScale),
 | |
|                        uint8_t(b * kDarkerScale), a);
 | |
|   aResult[1] = aBorderColor;
 | |
| }
 | |
| 
 | |
| 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
 |