1 module des.util.colorparse; 2 3 /// 4 ulong hex2ulong( string hex ) 5 { 6 import std..string; 7 8 enum tbl = [ '0': 0, '1': 1, '2': 2, '3': 3, 9 '4': 4, '5': 5, '6': 6, '7': 7, 10 '8': 8, '9': 9, 'A': 10, 'B': 11, 11 'C': 12, 'D': 13, 'E': 14, 'F': 15 ]; 12 13 ulong ret = 0; 14 size_t i = 0; 15 auto uHex = toUpper( hex ); 16 foreach_reverse( c; uHex ) 17 ret += tbl[c] << (4 * i++); 18 19 return ret; 20 } 21 22 /// 23 T[4] parseColorStr(T=float)( string cstr, real norm=1 ) 24 { 25 if( cstr[0] == '#' ) 26 cstr = cstr[ 1 .. $ ]; 27 else if( cstr[0] == '0' && cstr[1] == 'x' ) 28 cstr = cstr[ 2 .. $ ]; 29 else 30 throw new Exception( "unsupported hex color string (format): '" ~ cstr ~ "'" ); 31 32 ulong shortWrite = 0; 33 bool alpha = false; 34 switch( cstr.length ) 35 { 36 case 1: 37 shortWrite = 2; 38 break; 39 case 2: 40 shortWrite = 3; 41 alpha = true; 42 break; 43 case 3: 44 shortWrite = 1; 45 break; 46 case 4: 47 shortWrite = 1; 48 alpha = true; 49 break; 50 case 6: break; 51 case 8: 52 alpha = true; 53 break; 54 default: 55 throw new Exception( "unsupported hex color string (length): '" ~ cstr ~ "'" ); 56 } 57 58 if( shortWrite == 1 ) 59 { 60 string buf; 61 62 foreach( c; cstr ) 63 buf ~= [c,c]; 64 65 cstr = buf; 66 } 67 else if( shortWrite >= 2 ) 68 { 69 string buf; 70 71 buf ~= [ cstr[0], cstr[0], cstr[0], cstr[0], cstr[0], cstr[0] ]; 72 73 if( shortWrite == 3 ) 74 buf ~= [ cstr[1], cstr[1] ]; 75 76 cstr = buf; 77 } 78 79 ulong val = hex2ulong( cstr ); 80 81 enum compbits = byte.sizeof * 8; 82 enum compmask = 0xFF; 83 84 auto k = norm / cast(real)(compmask); 85 auto cr = cast(T)( ( ( val >> ( ( 2 + alpha ) * compbits ) ) & compmask ) * k ); 86 auto cg = cast(T)( ( ( val >> ( ( 1 + alpha ) * compbits ) ) & compmask ) * k ); 87 auto cb = cast(T)( ( ( val >> ( ( 0 + alpha ) * compbits ) ) & compmask ) * k ); 88 auto ca = cast(T)( alpha ? ( val & compmask ) * k : norm ); 89 90 return [ cr, cg, cb, ca ]; 91 } 92 93 /// 94 unittest 95 { 96 assert( [1.0f,0,1,0] == parseColorStr( "#FF00FF00" ) ); 97 assert( [1.0f,0,1,1] == parseColorStr( "#FF00FF" ) ); 98 assert( [1.0f,0,1,0] == parseColorStr( "#F0F0" ) ); 99 assert( [1.0f,0,1,1] == parseColorStr( "#F0F" ) ); 100 assert( [1.0f,1,1,0] == parseColorStr( "#F0" ) ); 101 assert( [1.0f,1,1,1] == parseColorStr( "#F" ) ); 102 assert( [0.0f,0,0,1] == parseColorStr( "#0" ) ); 103 assert( [1.0f,1,1,1] == parseColorStr( "0xF" ) ); 104 assert( [0.0f,0,0,1] == parseColorStr( "0x0" ) ); 105 106 assert( [255,15,255,255] == parseColorStr!ubyte( "#FF0FFF", 255 ) ); 107 }