1 //          Copyright Ferdinand Majerech 2014.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE_1_0.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5 
6 
7 /// Tools to manipulate 4D ubyte vectors as RGBA colors.
8 module gl3n_extra.color;
9 
10 
11 import std.traits;
12 
13 import gl3n_extra.linalg;
14 
15 
16 /// 8-bit RGBA color.
17 alias Color = vec4ub;
18 
19 
20 /// Construct an RGBA color from individual channels.
21 Color rgba(I)(I r, I g, I b, I a) @safe pure nothrow @nogc
22     if(isIntegral!I)
23 {
24     assert(r >= 0 && r <= ubyte.max &&
25            g >= 0 && g <= ubyte.max &&
26            b >= 0 && b <= ubyte.max &&
27            a >= 0 && a <= ubyte.max , "Color channels out of range");
28     return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b, cast(ubyte)a);
29 }
30 
31 /// Construct an RGB (RGBA with full alpha) color from individual channels.
32 Color rgb(I)(I r, I g, I b) @safe pure nothrow @nogc
33     if(isIntegral!I)
34 {
35     return rgba(r, g, b, 255);
36 }
37 
38 import std.ascii: toUpper, isHexDigit;
39 import std..string;
40 
41 /// RGB color from a hexadecimal string (CSS style), e.g. FFFFFF for white.
42 template rgb(string c) if(c.length == 6 && c.count!isHexDigit == 6)
43 {
44     enum auto rgb = rgba!(c ~ "FF");
45 }
46 
47 /// RGBA color from a hexadecimal string (CSS style), e.g. FFFFFF80 for half-transparent white.
48 Color rgba(string c)() @safe pure nothrow @nogc
49     if(c.length == 8 && c.count!isHexDigit == 8)
50 {
51     // Funcs to parse one digit and a 2-digit channel.
52     enum digit   = (char d) => d >= '0' && d <= '9' ? d - '0' : 10 + d.toUpper - 'A';
53     enum channel = (string hex) => cast(ubyte)(16 * digit(hex[0]) + digit(hex[1]));
54     return Color(channel(c[0 .. 2]), channel(c[2 .. 4]), 
55                  channel(c[4 .. 6]), channel(c[6 .. 8]));
56 }