eb76c42a3bb48d655de5d11d4517233ca1cf7d68
[reactos.git] / reactos / lib / 3rdparty / cardlib / cardcolor.cpp
1 //
2 // Colour support
3 //
4 //#include <windows.h>
5
6 #define WIN32_NO_STATUS
7 #include <windef.h>
8 #include <wingdi.h>
9
10 #define MakeRGB RGB
11
12 #define MIN3(a,b,c) ( (a)<=(b) ? (a)<=(c)?(a):(c) : (b)<=(c)?(b):(c) )
13 #define MAX3(a,b,c) ( (a)>=(b) ? (a)>=(c)?(a):(c) : (b)>=(c)?(b):(c) )
14
15 inline double fMax(double a, double b)
16 {
17 return a < b ? b : a;
18 }
19
20 inline double fMin(double a, double b)
21 {
22 return a < b ? a : b;
23 }
24 /******************************************************************************
25 FUNCTION: RGBtoHLS
26 PURPOSE: Convert from RGB to HLS
27 IN: RGB color (0xBBGGRR)
28 OUT: Hue, Saturation, Luminance from 0 to 1
29 COPYRIGHT:1995-1997 Robert Mashlan
30 Modified for LabWindows/CVI, 1999 Guillaume Dargaud
31 ******************************************************************************/
32 void RGBtoHLS(const COLORREF rgb, double *H, double *L, double *S )
33 {
34 double delta;
35 double r = (double)((rgb )&0xFF)/255;
36 double g = (double)((rgb>> 8)&0xFF)/255;
37 double b = (double)((rgb>>16)&0xFF)/255;
38 double cmax = MAX3(r,g,b);
39 double cmin = MIN3(r,g,b);
40 *L=(cmax+cmin)/2.0;
41
42 if(cmax == cmin)
43 {
44 *S = *H = 0; // it's really undefined
45 }
46 else
47 {
48 if(*L < 0.5) *S = (cmax-cmin)/(cmax+cmin);
49 else *S = (cmax-cmin)/(2.0-cmax-cmin);
50
51 delta = cmax - cmin;
52
53 if(r == cmax)
54 {
55 *H = (g - b) / delta;
56 }
57 else
58 {
59 if(g == cmax) *H = 2.0 + (b-r) / delta;
60 else *H = 4.0 + (r-g) / delta;
61 }
62 *H /= 6.0;
63 if (*H < 0.0) *H += 1;
64 }
65 }
66
67 /******************************************************************************
68 FUNCTION: HueToRGB
69 PURPOSE: Convert a hue (color) to RGB
70 COPYRIGHT:1995-1997 Robert Mashlan
71 Modified for LabWindows/CVI, 1999 Guillaume Dargaud
72 ******************************************************************************/
73 double HueToRGB(const double m1, const double m2, double h )
74 {
75 if (h<0) h+=1.0;
76 if (h>1) h-=1.0;
77 if (6.0*h < 1 ) return (m1+(m2-m1)*h*6.0);
78 if (2.0*h < 1 ) return m2;
79 if (3.0*h < 2.0) return (m1+(m2-m1)*((2.0/3.0)-h)*6.0);
80 return m1;
81 }
82
83
84 /******************************************************************************
85 FUNCTION: HLStoRGB
86 PURPOSE: Convert from HSL to RGB
87 IN: Hue, Saturation, Luminance from 0 to 1
88 RETURN: RGB color (0xBBGGRR)
89 COPYRIGHT:1995-1997 Robert Mashlan
90 Modified for LabWindows/CVI, 1999 Guillaume Dargaud
91 ******************************************************************************/
92
93 COLORREF HLStoRGB(const double H, const double L, const double S )
94 {
95 double r,g,b;
96 double m1, m2;
97
98 if(S == 0)
99 {
100 r = g = b = L;
101 }
102 else
103 {
104 if (L <= 0.5)
105 m2 = L * (1.0 + S);
106 else
107 m2 = L + S - L * S;
108
109 m1 = 2.0 * L - m2;
110
111 r = HueToRGB(m1,m2,H+1.0/3.0);
112 g = HueToRGB(m1,m2,H);
113 b = HueToRGB(m1,m2,H-1.0/3.0);
114 }
115
116 return RGB(r*255, g*255, b*255);
117 }
118
119
120
121 /******************************************************************************
122 FUNCTION: ColorScaleHSL
123 PURPOSE: Returns the HSL linear interpolated color between 2 colors
124 (more natural looking than RGB interpolation)
125 For instance if the luminance is the same in Col1 and Col2,
126 then the luminance of the result will be the same
127 If Ratio=0, you get Col1,
128 If Ratio=1, you get Col2
129 IN: Col1: low color in hex 0xBBGGRR format
130 Col2: high color in hex 0xBBGGRR format
131 Ratio: 0 for low color, 1 for high color, or in between
132 EXAMPLE: Col1=0, Col2=0xFF00FF, Ratio=0.5 returns 0x1F5F3F
133 ******************************************************************************/
134 COLORREF ColorScaleHSL( const COLORREF Col1, const COLORREF Col2, const double Ratio)
135 {
136 static double H1, H2, S1, S2, L1, L2;
137
138 if (Ratio<=0) return Col1; // Ratio parameter must be between 0 and 1
139 else if (Ratio>=1) return Col2;
140
141 RGBtoHLS( Col1, &H1, &L1, &S1);
142 RGBtoHLS( Col2, &H2, &L2, &S2);
143 return HLStoRGB( H1+(H2-H1)*Ratio, L1+(L2-L1)*Ratio, S1+(S2-S1)*Ratio );
144 }
145
146
147 /******************************************************************************
148 FUNCTION: ColorScaleRGB
149 PURPOSE: Returns the RGB linear interpolated color between 2 colors
150 If Ratio=0, you get Col1,
151 If Ratio=1, you get Col2
152 IN: Col1: low color in hex 0xBBGGRR format
153 Col2: high color in hex 0xBBGGRR format
154 Ratio: 0 for low color, 1 for high color, or in between
155 EXAMPLE: Col1=0, Col2=0xFF00FF, Ratio=0.5 returns 0x800080
156 ******************************************************************************/
157 COLORREF ColorScaleRGB( const COLORREF Col1,
158 const COLORREF Col2,
159 const double Ratio) {
160 int R1=(Col1)&0xFF, G1=(Col1>>8)&0xFF, B1=(Col1>>16)&0xFF;
161 int R2=(Col2)&0xFF, G2=(Col2>>8)&0xFF, B2=(Col2>>16)&0xFF;
162
163 if (Ratio<=0) return Col1; // Ratio parameter must be between 0 and 1
164 else if (Ratio>=1) return Col2;
165
166 /* return RGB(
167 (R1 + (R2 - R1) * (Ratio + 0.02) + 0.5), // rounding
168 (G1 + (G2 - G1) * (Ratio - 0.00) + 0.5),
169 (B1 + (B2 - B1) * (Ratio + 0.05) + 0.5)
170 );*/
171
172 /*double r = Ratio;
173 if(Col2 == 0)
174 r = 1-Ratio;
175 else
176 r = 1+Ratio;
177 R1 = (int)(double(R1) * r + 0.5);
178 G1 = (int)(double(G1) * r + 0.5);
179 B1 = (int)(double(B1) * r + 0.5);
180 return RGB(R1,G1,B1);*/
181
182 return RGB(
183 (R1 + (R2 - R1) * (Ratio + 0.02) + 0.5), // rounding
184 (G1 + (G2 - G1) * (Ratio - 0.00) + 0.5),
185 (B1 + (B2 - B1) * (Ratio + 0.05) + 0.5)
186 );
187 }
188
189
190
191 COLORREF ColorDarker(COLORREF col, double ratio)
192 {
193 return ColorScaleHSL(col, RGB(0,0,0), ratio);
194 }
195
196 COLORREF ColorLighter(COLORREF col, double ratio)
197 {
198 return ColorScaleHSL(col, RGB(255,255,255), ratio);
199 }
200
201 //
202 // Experimental!!!
203 //
204 #if 0
205
206 typedef enum { Red, Green, Blue };
207
208 void RGBtoHLS(COLORREF rgb, double *Hue, double *Lum, double *Sat)
209 {
210 double mn, mx;
211 int major;
212
213 BYTE red, green, blue;
214
215 red = GetRValue(rgb);
216 green = GetGValue(rgb);
217 blue = GetBValue(rgb);
218
219 if(red < green)
220 {
221 mn = red; mx = green; major = Green;
222 }
223 else
224 {
225 mn = green; mx = red; major = Red;
226 }
227
228 if(blue < mn)
229 {
230 mn = blue;
231 }
232 else if(blue > mx)
233 {
234 mx = blue; major = Blue;
235 }
236
237 if(mn == mx)
238 {
239 *Lum = mn / 255;
240 *Sat = 0;
241 *Hue = 0;
242 }
243 else
244 {
245 *Lum = (mx + mn) / 510;
246
247 if(*Lum <= 0.5)
248 *Sat = (mx-mn) / (mn+mx);
249 else
250 *Sat = (mx-mn) / (510-mn-mx);
251
252 switch(major)
253 {
254 case Red: *Hue = (green-blue) * 60.0 / (mx-mn) + 360.0;
255 break;
256
257 case Green: *Hue = (blue-red) * 60.0 / (mx-mn) + 120.0;
258 break;
259
260 case Blue: *Hue = (red-green) * 60.0 / (mx-mn) + 240.0;
261 break;
262
263 }
264
265 if(*Hue > 360.0)
266 *Hue -= 360.0;
267 }
268 }
269
270 static BYTE Value(double m1, double m2, double hue)
271 {
272
273 if(hue > 360) hue -= 360;
274 else if(hue < 0) hue += 360;
275
276 if(hue < 60)
277 m1 = m1 + (m2 - m1) * hue / 60;
278 else if(hue < 180)
279 m1 = m2;
280 else if(hue < 240)
281 m1 = m1 + (m2 - m1) * (240 - hue) / 60;
282
283 return (BYTE)(m1 * 255);
284 }
285
286 COLORREF HLStoRGB(const double Hue, const double Lum, const double Sat)
287 {
288 BYTE red, green, blue;
289
290 if(Sat == 0)
291 {
292 red = green = blue = (BYTE)(Lum * 255);
293 }
294 else
295 {
296 double m1, m2;
297
298 if(Lum <= 0.5)
299 m2 = Lum + Lum * Sat;
300 else
301 m2 = Lum + Sat - Lum * Sat;
302
303 m1 = 2 * Lum - m2;
304
305 red = Value(m1, m2, Hue + 120);
306 green = Value(m1, m2, Hue);
307 blue = Value(m1, m2, Hue - 120);
308 }
309
310 return RGB(red, green, blue);
311 }
312
313 COLORREF ScaleLumRGB(COLORREF col1, double ratio)
314 {
315 double H1, L1, S1;
316
317 RGBtoHLS(col1, &H1, &L1, &S1);
318
319 L1 += L1 * ratio;
320
321 return HLStoRGB(H1, L1, S1);
322 }
323
324 COLORREF ColorScaleHSL(const COLORREF Col1, const COLORREF Col2, const double Ratio)
325 {
326 static double H1, H2, S1, S2, L1, L2;
327
328 if(Ratio <= 0) return Col1; // Ratio parameter must be between 0 and 1
329 else if(Ratio >= 1) return Col2;
330
331 RGBtoHLS( Col1, &H1, &L1, &S1);
332 RGBtoHLS( Col2, &H2, &L2, &S2);
333
334 return HLStoRGB( H1 /*+ (H2 - H1 ) * Ratio*/, L1 + (L2 - L1) * Ratio, S1 + (S2 - S1) * Ratio * 2);
335 }
336
337 COLORREF ColorScaleRGB(const COLORREF Col1, const COLORREF Col2, const double Ratio)
338 {
339 return ColorScaleHSL(Col1, Col2, Ratio);
340 }
341 #endif