/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsCSSColorUtils.h" #include // 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 LIGHT_FACTOR 0 #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 WHITE NS_RGB(255, 255, 255) #define BLACK NS_RGB(0, 0, 0) #define MAX_BRIGHTNESS 254 #define MAX_DARKNESS 0 void NS_Get3DColors(nscolor aResult[2], nscolor aBackgroundColor) { int rb = NS_GET_R(aBackgroundColor); int gb = NS_GET_G(aBackgroundColor); int bb = NS_GET_B(aBackgroundColor); int brightness = NS_GetBrightness(rb,gb,bb); int f0, f1; if (brightness < COLOR_DARK_THRESHOLD) { f0 = COLOR_DARK_BS_FACTOR; f1 = COLOR_DARK_TS_FACTOR; } else if (brightness > COLOR_LIGHT_THRESHOLD) { f0 = COLOR_LITE_BS_FACTOR; f1 = COLOR_LITE_TS_FACTOR; } else { f0 = COLOR_DARK_BS_FACTOR + (brightness * (COLOR_LITE_BS_FACTOR - COLOR_DARK_BS_FACTOR) / MAX_COLOR); f1 = COLOR_DARK_TS_FACTOR + (brightness * (COLOR_LITE_TS_FACTOR - COLOR_DARK_TS_FACTOR) / MAX_COLOR); } int r = rb - (f0 * rb / 100); int g = gb - (f0 * gb / 100); int b = bb - (f0 * bb / 100); aResult[0] = NS_RGB(r, g, b); if ((r == rb) && (g == gb) && (b == bb)) { aResult[0] = (aBackgroundColor == BLACK) ? DARK_GRAY : BLACK; } r = rb + (f1 * (MAX_COLOR - rb) / 100); if (r > 255) r = 255; g = gb + (f1 * (MAX_COLOR - gb) / 100); if (g > 255) g = 255; b = bb + (f1 * (MAX_COLOR - bb) / 100); if (b > 255) b = 255; aResult[1] = NS_RGB(r, g, b); if ((r == rb) && (g == gb) && (b == bb)) { aResult[1] = (aBackgroundColor == WHITE) ? LIGHT_GRAY : WHITE; } } void NS_GetSpecial3DColors(nscolor aResult[2], nscolor aBackgroundColor, nscolor aBorderColor) { PRUint8 f0, f1; PRUint8 r, g, b; PRUint8 rb = NS_GET_R(aBorderColor); PRUint8 gb = NS_GET_G(aBorderColor); PRUint8 bb = NS_GET_B(aBorderColor); // This needs to be optimized. // Calculating background brightness again and again is // a waste of time!!!. Just calculate it only once. // .....somehow!!! PRUint8 red = NS_GET_R(aBackgroundColor); PRUint8 green = NS_GET_G(aBackgroundColor); PRUint8 blue = NS_GET_B(aBackgroundColor); PRUint8 elementBrightness = NS_GetBrightness(rb,gb,bb); PRUint8 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_RGB(r, g, b); r = rb + (f1 * (MAX_COLOR - rb) / 100); g = gb + (f1 * (MAX_COLOR - gb) / 100); b = bb + (f1 * (MAX_COLOR - bb) / 100); aResult[1] = NS_RGB(r, g, b); } int NS_GetBrightness(PRUint8 aRed, PRUint8 aGreen, PRUint8 aBlue) { PRUint8 intensity = (aRed + aGreen + aBlue) / 3; PRUint8 luminosity = NS_GetLuminosity(NS_RGB(aRed, aGreen, aBlue)) / 1000; return ((intensity * INTENSITY_FACTOR) + (luminosity * LUMINOSITY_FACTOR)) / 100; } PRInt32 NS_GetLuminosity(nscolor aColor) { 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,PRUint16 &aHue,PRUint16 &aSat,PRUint16 &aValue) { PRUint8 r,g,b; PRInt16 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= 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 = (PRUint16) 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 = (PRUint16)(percent*(255-aSat)); q = (PRUint16)(percent*(255-(aSat*f))); t = (PRUint16)(percent*(255-(aSat*(1.0-f)))); // i is guarenteed 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_RGB(r,g,b); }