1 /**
2 	Colors.c
3 	All sorts of operations on colors.
4 
5 	@author Tyron
6 */
7 
8 static const RGBA_ALPHA = 0;
9 static const RGBA_RED = 1;
10 static const RGBA_GREEN = 2;
11 static const RGBA_BLUE = 3;
12 
13 // documented in /docs/sdk/script/fn
HSL(int h,int s,int l)14 global func HSL(int h, int s, int l)  { return HSL2RGB(RGB(h, s, l)); }
HSLa(int h,int s,int l,int a)15 global func HSLa(int h, int s, int l, int a) { return  HSL2RGB(RGB(h, s, l)) ^ ~(a & 255) << 24; }
16 
17 // documented in /docs/sdk/script/fn
RGB(int r,int g,int b)18 global func RGB(int r, int g, int b) { return (255 << 24) | (r & 255) << 16 | (g & 255) << 8 | (b & 255); }
RGBa(int r,int g,int b,int a)19 global func RGBa (int r, int g, int b, int a) { return (a & 255) << 24 | (r & 255) << 16 | (g & 255) << 8 | (b & 255); }
20 
21 // documented in /docs/sdk/script/fn
GetRGBaValue(int val,int sel)22 global func GetRGBaValue(int val, int sel) { return val >> ((3 - sel) * 8) & 255; }
DoRGBaValue(int val,int chng,int sel)23 global func DoRGBaValue(int val, int chng, int sel) { return val + (chng << ((3 - sel) * 8)); }
24 
25 // documented in /docs/sdk/script/fn
SetRGBaValue(int val,int newval,int sel)26 global func SetRGBaValue(int val, int newval, int sel)
27 {
28 	// 'delete' old color
29 	val = val & ~(255 << ((3 - sel) * 8));
30 	// add new
31 	return val | newval << ((3 - sel) * 8);
32 }
33 
34 // documented in /docs/sdk/script/fn
SplitRGBaValue(int rgb)35 global func SplitRGBaValue(int rgb)
36 {
37 	return {
38 		R = GetRGBaValue(rgb, RGBA_RED),
39 		G = GetRGBaValue(rgb, RGBA_GREEN),
40 		B = GetRGBaValue(rgb, RGBA_BLUE),
41 		Alpha = GetRGBaValue(rgb, RGBA_ALPHA)
42 	};
43 }
44 
45 // documented in /docs/sdk/script/fn
HSL2RGB(int hsl)46 global func HSL2RGB(int hsl)
47 {
48 	var hue = GetRGBaValue(hsl, 1), sat = GetRGBaValue(hsl, 2), lightness = GetRGBaValue(hsl, 3);
49 	var red, green, blue;
50 	var var1, var2;
51 
52 	if (sat == 0)
53 	{
54 		red = green = blue = lightness;
55 	}
56 	else
57 	{
58 		if (lightness < 128)
59 			var2 = lightness * (255 + sat) / 255;
60 		else
61 			var2 = lightness + sat - lightness * sat / 255;
62 
63 		var1 = 2 * lightness - var2;
64 
65 		red = Hue_2_RGB(var1, var2, hue + 85);
66 		green = Hue_2_RGB(var1, var2, hue);
67 		blue = Hue_2_RGB(var1, var2, hue - 85);
68 	}
69 
70 	return RGB(red, green, blue);
71 }
72 
Hue_2_RGB(int var1,int var2,int hue)73 global func Hue_2_RGB(int var1, int var2, int hue)
74 {
75 	if (hue < 0)
76 		hue += 255;
77 	if (hue > 255)
78 		hue -= 255;
79 	if (6 * hue < 255)
80 		return var1 + (var2 - var1) * 6 * hue / 255;
81 	if (2 * hue < 255)
82 		return var2;
83 	if (3 * hue < 510)
84 		return var1 + (var2 - var1) * ( 510 / 3 - hue ) * 6 / 255;
85 	return var1;
86 }
87 
88 // documented in /docs/sdk/script/fn
RGB2HSL(int rgb)89 global func RGB2HSL(int rgb)
90 {
91 	var red = GetRGBaValue(rgb, RGBA_RED), green = GetRGBaValue(rgb, RGBA_GREEN), blue = GetRGBaValue(rgb, RGBA_BLUE);
92 	var min_val = Min(red, Min(green, blue)), max_val = Max(red, Max(green, blue));
93 	var diff_val = max_val - min_val;
94 	var lightness = (max_val + min_val) / 2;
95 	var hue, sat, diff_red, diff_green, diff_blue;
96 
97 	if (diff_val==0)
98 	{
99 		hue = 0;
100 		sat = 0;
101 	}
102 	else
103 	{
104 		if (lightness < 128)
105 			sat = 255 * diff_val / (max_val + min_val);
106 		else
107 			sat = 255 * diff_val / (510 - (max_val + min_val));
108 
109 		diff_red = ((255 * (max_val - red)) / 6 + (255 * diff_val) / 2) / diff_val;
110 		diff_green = ((255 * (max_val - green)) / 6 + (255 * diff_val) / 2) / diff_val;
111 		diff_blue = ((255 * (max_val - blue )) / 6 + (255 * diff_val) / 2) / diff_val;
112 
113 		if (red == max_val)
114 			hue = diff_blue -diff_green;
115 		else if (green == max_val)
116 			hue = 255 / 3 + diff_red - diff_blue;
117 		else if (blue == max_val)
118 			hue = 510 / 3 + diff_green - diff_red;
119 
120 		if (hue < 0)
121 			hue += 255;
122 		if (hue > 255)
123 			hue -= 255;
124 	}
125 
126 	return RGB(hue, sat, lightness);
127 }
128