Skip to content

Instantly share code, notes, and snippets.

@run-dlang
Created February 24, 2019 11:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save run-dlang/965a2fb793bda7b1a82b0512d78973f3 to your computer and use it in GitHub Desktop.
Save run-dlang/965a2fb793bda7b1a82b0512d78973f3 to your computer and use it in GitHub Desktop.
Code shared from run.dlang.io.
import std.algorithm.mutation;
///Returns a hexadecimal string representation of the integer.
string intToHex(int i, int format = 0){
string result;
do{
switch(i & 0x000F){
case 1: result ~='1'; break;
case 2: result ~='2'; break;
case 3: result ~='3'; break;
case 4: result ~='4'; break;
case 5: result ~='5'; break;
case 6: result ~='6'; break;
case 7: result ~='7'; break;
case 8: result ~='8'; break;
case 9: result ~='9'; break;
case 10: result ~='A'; break;
case 11: result ~='B'; break;
case 12: result ~='C'; break;
case 13: result ~='D'; break;
case 14: result ~='E'; break;
case 15: result ~='F'; break;
default: result ~='0'; break;
}
i = i >>> 4;
}while(i > 0);
if(result.length < format){
for(size_t j = result.length ; j < format ; j++){
result ~= '0';
}
}
reverse(cast(char[])result);
return result;
}
/**
* Various representations of color with various accessibility modes.
*/
public struct Color{
union{
uint raw; ///Raw representation in integer form, also forces the system to align in INT32.
ubyte[4] colors; ///Normal representation, aliases are used for color naming.
}
version(LittleEndian){
public @nogc @property ubyte alpha(){ return colors[0]; }
public @nogc @property ubyte red(){ return colors[1]; }
public @nogc @property ubyte green(){ return colors[2]; }
public @nogc @property ubyte blue(){ return colors[3]; }
public @nogc @property ubyte alpha(ubyte value){ return colors[0] = value; }
public @nogc @property ubyte red(ubyte value){ return colors[1] = value; }
public @nogc @property ubyte green(ubyte value){ return colors[2] = value; }
public @nogc @property ubyte blue(ubyte value){ return colors[3] = value; }
}else{
public @nogc @property ubyte alpha(){ return colors[3]; }
public @nogc @property ubyte red(){ return colors[2]; }
public @nogc @property ubyte green(){ return colors[1]; }
public @nogc @property ubyte blue(){ return colors[0]; }
public @nogc @property ubyte alpha(ubyte value){ return colors[3] = value; }
public @nogc @property ubyte red(ubyte value){ return colors[2] = value; }
public @nogc @property ubyte green(ubyte value){ return colors[1] = value; }
public @nogc @property ubyte blue(ubyte value){ return colors[0] = value; }
}
/**
* Contructs a color from four individual values.
*/
public @nogc this(ubyte alpha, ubyte red, ubyte green, ubyte blue){
this.alpha = alpha;
this.red = red;
this.green = green;
this.blue = blue;
}
/**
* Constructs a color from a single 32 bit unsigned integer.
*/
public @nogc this(uint val){
raw = val;
}
/**
* Operator overloading for quick math. '*' is alpha-blending, '^' is XOR blitter, '&' is normal "blitter".
* Alpha is used from right hand side and kept on left hand side when needed
*/
public Color opBinary(string op)(Color rhs){
static if(op == "+"){
int r = red + rhs.red, g = green + rhs.green, b = blue + rhs.blue, a = alpha + rhs.alpha;
return Color(a > 255 ? 255 : cast(ubyte)a, r > 255 ? 255 : cast(ubyte)r, g > 255 ? 255 : cast(ubyte)g, b > 255 ? 255 : cast(ubyte)b);
}else static if(op == "-"){
int r = red - rhs.red, g = green - rhs.green, b = blue - rhs.blue, a = alpha - rhs.alpha;
return Color(a < 0 ? 0 : cast(ubyte)a, r < 0 ? 0 : cast(ubyte)r, g < 0 ? 0 : cast(ubyte)g, b < 0 ? 0 : cast(ubyte)b);
}else static if(op == "^"){
return Color(alpha ^ rhs.alpha, red ^ rhs.red, green ^ rhs.green, blue ^ rhs.blue);
}else static if(op == "&"){
return rhs.alpha ? rhs : this;
}else static if(op == "*"){
return Color(alpha, cast(ubyte)( ( (rhs.red * (1 + rhs.alpha)) + (red * (256 - rhs.alpha)) )>>8 ),
cast(ubyte)( ( (rhs.green * (1 + rhs.alpha)) + (green * (256 - rhs.alpha)) )>>8 ),
cast(ubyte)( ( (rhs.blue * (1 + rhs.alpha)) + (blue * (256 - rhs.alpha)) )>>8 ));
}else static assert(0, "Operator '" ~ op ~ "' not supported!");
}
/**
* Returns a string for debugging.
*/
public string toString() const // added const
{
//import PixelPerfectEngine.system.etc;
return "0x" ~ intToHex(raw, 8);
}
}
static immutable immutable(Color)[] clrs;
static this()
{
clrs = [Color(0, 255, 0, 0),
Color(0, 0, 255, 0),
Color(0, 0, 0, 255)];
}
enum ct_clrs = [Color(0, 255, 0, 0),
Color(0, 0, 255, 0),
Color(0, 0, 0, 255)];
void main()
{
//assert(clrs[1].green == 255); // green() should be const
import std.stdio;
writefln("0x%08X", clrs[1].raw);
writeln(clrs[1]);
Color[] clrs2 = clrs.dup;
clrs2[1].red = 123;
writeln(clrs2[1]);
clrs2 = ct_clrs;
clrs2[2].green = 123;
writeln(clrs2[2]);
assert(clrs2[1].green == 255);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment