1 /*
2  *******************************************************************************************
3  * Dgame (a D game framework) - Copyright (c) Randy Schütt
4  *
5  * This software is provided 'as-is', without any express or implied warranty.
6  * In no event will the authors be held liable for any damages arising from
7  * the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not claim
14  *    that you wrote the original software. If you use this software in a product,
15  *    an acknowledgment in the product documentation would be appreciated but is
16  *    not required.
17  *
18  * 2. Altered source versions must be plainly marked as such, and must not be
19  *    misrepresented as being the original software.
20  *
21  * 3. This notice may not be removed or altered from any source distribution.
22  *******************************************************************************************
23  */
24 module Dgame.Graphic.Color;
25 
26 private:
27 
28 import derelict.sdl2.types;
29 
30 mixin template Colors(T) {
31     static immutable T Aliceblue            = T(240, 248, 255);
32     static immutable T Antiquewhite         = T(250, 235, 215);
33     static immutable T Aquamarine           = T(127, 255, 212);
34     static immutable T Azure                = T(240, 255, 255);
35     static immutable T Beige                = T(245, 245, 220);
36     static immutable T Bisque               = T(255, 228, 196);
37     static immutable T Black                = T(  0,   0,   0);
38     static immutable T Blanchedalmond       = T(255, 235, 205);
39     static immutable T Blue                 = T(  0,   0, 255);
40     static immutable T Blueviolet           = T(138,  43, 226);
41     static immutable T Brown                = T(165,  42,  42);
42     static immutable T Burlywood            = T(222, 184, 135);
43     static immutable T Cadetblue            = T( 95, 158, 160);
44     static immutable T Chartreuse           = T(127, 255,   0);
45     static immutable T Chocolate            = T(210, 105,  30);
46     static immutable T Coral                = T(255, 127,  80);
47     static immutable T Cornflowerblue       = T(100, 149, 237);
48     static immutable T Cornsilk             = T(255, 248, 220);
49     static immutable T Cyan                 = T(  0, 255, 255);
50     static immutable T Darkblue             = T(  0,   0, 139);
51     static immutable T Darkcyan             = T(  0, 139, 139);
52     static immutable T Darkgoldenrod        = T(184, 134,  11);
53     static immutable T Darkgray             = T(169, 169, 169);
54     static immutable T Darkgreen            = T(  0, 100,   0);
55     static immutable T Darkkhaki            = T(189, 183, 107);
56     static immutable T Darkmagenta          = T(139,   0, 139);
57     static immutable T Darkolivegreen       = T( 85, 107,  47);
58     static immutable T Darkorange           = T(255, 140,   0);
59     static immutable T Darkorchid           = T(153,  50, 204);
60     static immutable T Darkred              = T(139,   0,   0);
61     static immutable T Darksalmon           = T(233, 150, 122);
62     static immutable T Darkseagreen         = T(143, 188, 143);
63     static immutable T Darkslateblue        = T( 72,  61, 139);
64     static immutable T Darkslategray        = T( 47,  79,  79);
65     static immutable T Darkturquoise        = T(  0, 206, 209);
66     static immutable T Darkviolet           = T(148,   0, 211);
67     static immutable T Deeppink             = T(255,  20, 147);
68     static immutable T Deepskyblue          = T(  0, 191, 255);
69     static immutable T Dimgray              = T(105, 105, 105);
70     static immutable T Dodgerblue           = T( 30, 144, 255);
71     static immutable T Firebrick            = T(178,  34,  34);
72     static immutable T Floralwhite          = T(255, 250, 240);
73     static immutable T Forestgreen          = T( 34, 139,  34);
74     static immutable T Gainsboro            = T(220, 220, 220);
75     static immutable T Ghostwhite           = T(248, 248, 255);
76     static immutable T Gold                 = T(255, 215,   0);
77     static immutable T Goldenrod            = T(218, 165,  32);
78     static immutable T Green                = T(  0, 255,   0);
79     static immutable T Greenyellow          = T(173, 255,  47);
80     static immutable T Honeydew             = T(240, 255, 240);
81     static immutable T Hotpink              = T(255, 105, 180);
82     static immutable T Indianred            = T(205,  92,  92);
83     static immutable T Ivory                = T(255, 255, 240);
84     static immutable T Khaki                = T(240, 230, 140);
85     static immutable T Lavender             = T(230, 230, 250);
86     static immutable T Lavenderblush        = T(255, 240, 245);
87     static immutable T Lawngreen            = T(124, 252,   0);
88     static immutable T Lemonchiffon         = T(255, 250, 205);
89     static immutable T Lightblue            = T(173, 216, 230);
90     static immutable T Lightcoral           = T(240, 128, 128);
91     static immutable T Lightcyan            = T(224, 255, 255);
92     static immutable T Lightgoldenrod       = T(238, 221, 130);
93     static immutable T Lightgoldenrodyellow = T(250, 250, 210);
94     static immutable T Lightgray            = T(211, 211, 211);
95     static immutable T Lightgreen           = T(144, 238, 144);
96     static immutable T Lightpink            = T(255, 182, 193);
97     static immutable T Lightsalmon          = T(255, 160, 122);
98     static immutable T Lightseagreen        = T( 32, 178, 170);
99     static immutable T Lightskyblue         = T(135, 206, 250);
100     static immutable T Lightslateblue       = T(132, 112, 255);
101     static immutable T Lightslategray       = T(119, 136, 153);
102     static immutable T Lightsteelblue       = T(176, 196, 222);
103     static immutable T Lightyellow          = T(255, 255, 224);
104     static immutable T Limegreen            = T( 50, 205,  50);
105     static immutable T Linen                = T(250, 240, 230);
106     static immutable T Magenta              = T(255,   0, 255);
107     static immutable T Maroon               = T(176,  48,  96);
108     static immutable T Mediumaquamarine     = T(102, 205, 170);
109     static immutable T Mediumblue           = T(  0,   0, 205);
110     static immutable T Mediumorchid         = T(186,  85, 211);
111     static immutable T Mediumpurple         = T(147, 112, 219);
112     static immutable T Mediumseagreen       = T( 60, 179, 113);
113     static immutable T Mediumslateblue      = T(123, 104, 238);
114     static immutable T Mediumspringgreen    = T(  0, 250, 154);
115     static immutable T Mediumturquoise      = T( 72, 209, 204);
116     static immutable T Mediumvioletred      = T(199,  21, 133);
117     static immutable T Midnightblue         = T( 25,  25, 112);
118     static immutable T Mintcream            = T(245, 255, 250);
119     static immutable T Mistyrose            = T(255, 228, 225);
120     static immutable T Moccasin             = T(255, 228, 181);
121     static immutable T Navajowhite          = T(255, 222, 173);
122     static immutable T Navy                 = T(  0,   0, 128);
123     static immutable T Navyblue             = T(  0,   0, 128);
124     static immutable T Oldlace              = T(253, 245, 230);
125     static immutable T Olivedrab            = T(107, 142,  35);
126     static immutable T Orange               = T(255, 165,   0);
127     static immutable T Orangered            = T(255,  69,   0);
128     static immutable T Orchid               = T(218, 112, 214);
129     static immutable T Palegoldenrod        = T(238, 232, 170);
130     static immutable T Palegreen            = T(152, 251, 152);
131     static immutable T Paleturquoise        = T(175, 238, 238);
132     static immutable T Palevioletred        = T(219, 112, 147);
133     static immutable T Papayawhip           = T(255, 239, 213);
134     static immutable T Peachpuff            = T(255, 218, 185);
135     static immutable T Peru                 = T(205, 133,  63);
136     static immutable T Pink                 = T(255, 192, 203);
137     static immutable T Plum                 = T(221, 160, 221);
138     static immutable T Powderblue           = T(176, 224, 230);
139     static immutable T Purple               = T(160,  32, 240);
140     static immutable T Red                  = T(255,   0,   0);
141     static immutable T Rosybrown            = T(188, 143, 143);
142     static immutable T Royalblue            = T( 65, 105, 225);
143     static immutable T Saddlebrown          = T(139,  69,  19);
144     static immutable T Salmon               = T(250, 128, 114);
145     static immutable T Sandybrown           = T(244, 164,  96);
146     static immutable T Seagreen             = T( 46, 139,  87);
147     static immutable T Seashell             = T(255, 245, 238);
148     static immutable T Sienna               = T(160,  82,  45);
149     static immutable T Skyblue              = T(135, 206, 235);
150     static immutable T Slateblue            = T(106,  90, 205);
151     static immutable T Slategray            = T(112, 128, 144);
152     static immutable T Snow                 = T(255, 250, 250);
153     static immutable T Springgreen          = T(  0, 255, 127);
154     static immutable T Steelblue            = T( 70, 130, 180);
155     static immutable T Tan                  = T(210, 180, 140);
156     static immutable T Thistle              = T(216, 191, 216);
157     static immutable T Tomato               = T(255,  99,  71);
158     static immutable T Turquoise            = T( 64, 224, 208);
159     static immutable T Violet               = T(238, 130, 238);
160     static immutable T Violetred            = T(208,  32, 144);
161     static immutable T Wheat                = T(245, 222, 179);
162     static immutable T White                = T(255, 255, 255);
163     static immutable T Whitesmoke           = T(245, 245, 245);
164     static immutable T Yellow               = T(255, 255,   0);
165     static immutable T Yellowgreen          = T(154, 205,  50);
166 }
167 
168 package(Dgame):
169 
170 @nogc
171 SDL_Color* _transfer(ref const Color4b src, ref SDL_Color dst) pure nothrow {
172     dst.r = src.red;
173     dst.g = src.green;
174     dst.b = src.blue;
175     dst.a = src.alpha;
176 
177     return &dst;
178 }
179 
180 public:
181 
182 /**
183  * Color4b defines a structure which contains 4 ubyte values, each for red, green, blue and alpha.
184  *
185  * Author: Randy Schuett (rswhite4@googlemail.com)
186  */
187 struct Color4b {
188     mixin Colors!Color4b;
189 
190     /**
191      * The color components
192      */
193     ubyte red, green, blue, alpha;
194 
195     /**
196      * CTor
197      */
198     @nogc
199     this(ubyte red, ubyte green, ubyte blue, ubyte alpha = 255) pure nothrow {
200         this.red   = red;
201         this.green = green;
202         this.blue  = blue;
203         this.alpha = alpha;
204     }
205 
206     /**
207      * CTor
208      */
209     @nogc
210     this(uint hexValue) pure nothrow {
211         version (LittleEndian) {
212             this.alpha = (hexValue >> 24) & 0xff;
213             this.blue  = (hexValue >> 16) & 0xff;
214             this.green = (hexValue >>  8) & 0xff;
215             this.red   = hexValue & 0xff;
216         } else {
217             this.red   = (hexValue >> 24) & 0xff;
218             this.green = (hexValue >> 16) & 0xff;
219             this.blue  = (hexValue >>  8) & 0xff;
220             this.alpha = hexValue & 0xff;
221         }
222     }
223 
224     /**
225      * CTor
226      *
227      * Expect that every component is in range 0.0 .. 1.0
228      */
229     @nogc
230     this(ref const Color4f col) pure nothrow
231     in {
232         assert(col.red   >= 0f && col.red   <= 1f);
233         assert(col.green >= 0f && col.green <= 1f);
234         assert(col.blue  >= 0f && col.blue  <= 1f);
235         assert(col.alpha >= 0f && col.alpha <= 1f);
236     } body {
237         this.red   = cast(ubyte)(ubyte.max * col.red);
238         this.green = cast(ubyte)(ubyte.max * col.green);
239         this.blue  = cast(ubyte)(ubyte.max * col.blue);
240         this.alpha = cast(ubyte)(ubyte.max * col.alpha);
241     }
242 
243     /**
244      * Returns a copy of the current Color with a given transpareny.
245      */
246     @nogc
247     Color4b withTransparency(ubyte alpha) const pure nothrow {
248         return Color4b(this.red, this.green, this.blue, alpha);
249     }
250 
251     /**
252      * opEquals: compares two Colors.
253      */
254     @nogc
255     bool opEquals(ref const Color4b col) const pure nothrow {
256         return this.red   == col.red &&
257                this.green == col.green &&
258                this.blue  == col.blue &&
259                this.alpha == col.alpha;
260     }
261 
262     /**
263      * Returns the RGBA color information as static array
264      */
265     @nogc
266     ubyte[4] asRGBA() const pure nothrow {
267         return [this.red, this.green, this.blue, this.alpha];
268     }
269 
270     /**
271      * Returns RGB the color information as static array
272      */
273      @nogc
274     ubyte[3] asRGB() const pure nothrow {
275         return [this.red, this.green, this.blue];
276     }
277 
278     /**
279      * Returns the RGBA color information as hex value
280      */
281     @nogc
282     uint asHex() const pure nothrow {
283         version (LittleEndian)
284             return ((this.alpha & 0xff) << 24) + ((this.blue & 0xff) << 16) + ((this.green & 0xff) << 8) + (this.red & 0xff);
285         else
286             return ((this.red & 0xff) << 24) + ((this.green & 0xff) << 16) + ((this.blue & 0xff) << 8) + (this.alpha & 0xff);
287     }
288 }
289 
290 unittest {
291     const Color4b red_col = Color4b.Red;
292     immutable uint hex_red = red_col.asHex();
293 
294     assert(hex_red == 0xff0000ff);
295     assert(Color4b(hex_red) == red_col);
296 }
297 
298 /**
299  * Color4f defines a structure which contains 4 floats values, each for red, green, blue and alpha.
300  *
301  * Author: Randy Schuett (rswhite4@googlemail.com)
302  */
303 struct Color4f {
304     mixin Colors!Color4f;
305 
306     /**
307      * The color components
308      */
309     float red, green, blue, alpha;
310 
311     /**
312      * CTor
313      */
314     @nogc
315     this(ubyte red, ubyte green, ubyte blue, ubyte alpha = 255) pure nothrow {
316         this.red   = red   > 0 ? red   / 255f : 0;
317         this.green = green > 0 ? green / 255f : 0;
318         this.blue  = blue  > 0 ? blue  / 255f : 0;
319         this.alpha = alpha > 0 ? alpha / 255f : 0;
320     }
321 
322     /**
323      * CTor
324      * Expect that every component is in range 0.0 .. 1.0
325      */
326     @nogc
327     this(float red, float green, float blue, float alpha = 1) pure nothrow
328     in {
329         assert(red   >= 0f && red   <= 1f);
330         assert(green >= 0f && green <= 1f);
331         assert(blue  >= 0f && blue  <= 1f);
332         assert(alpha >= 0f && alpha <= 1f);
333     } body {
334         this.red   = red;
335         this.green = green;
336         this.blue  = blue;
337         this.alpha = alpha;
338     }
339 
340     /**
341      * CTor
342      */
343     @nogc
344     this(ref const Color4b col) pure nothrow {
345         this(col.red, col.green, col.blue, col.alpha);
346     }
347 
348     /**
349      * opEquals: compares two Colors.
350      */
351     @nogc
352     bool opEquals(ref const Color4f col) const pure nothrow {
353         return this.red   == col.red &&
354                this.green == col.green &&
355                this.blue  == col.blue &&
356                this.alpha == col.alpha;
357     }
358 
359     /**
360      * Returns the RGBA color information as static array
361      */
362     @nogc
363     float[4] asRGBA() const pure nothrow {
364         return [this.red, this.green, this.blue, this.alpha];
365     }
366 
367     /**
368      * Returns RGB the color information as static array
369      */
370      @nogc
371     float[3] asRGB() const pure nothrow {
372         return [this.red, this.green, this.blue];
373     }
374 }