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