Created
February 24, 2019 11:58
-
-
Save run-dlang/965a2fb793bda7b1a82b0512d78973f3 to your computer and use it in GitHub Desktop.
Code shared from run.dlang.io.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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