1 /++ 2 D wrappers for the C functions 3 4 Authors: Matthew Soucy, msoucy@csh.rit.edu 5 License: Subject to the terms of the MIT license, as written in the included LICENSE file. 6 +/ 7 module fabd.dfab; 8 9 import cfab = fabd.fab; 10 import fabd.fab : Color, rgb_t; 11 12 import std.string : toStringz; 13 import std.conv : to; 14 import std.traits : isSomeString; 15 16 private string takeown(char* cptr) 17 { 18 import core.stdc.string : strlen; 19 import core.stdc.stdlib : free; 20 // When fromStringz is in default repos (IE ldc on Fedora) 21 // it should be used instead of manually reimplementing it 22 auto dstr = cptr[0 .. strlen(cptr)].idup; 23 free(cptr); 24 return dstr; 25 } 26 27 /++ 28 Applies the color $(D c) to $(D text). 29 30 Returns the string created as a result 31 +/ 32 string apply_color(String)(String text, Color c) 33 if(isSomeString!String) 34 { 35 return cfab.apply_color(c, text.toStringz).takeown; 36 } 37 38 /++ 39 Applies the $(D c) to the foreground of $(D text) 40 +/ 41 string foreground_256(String)(String text, rgb_t c) 42 if(isSomeString!String) 43 { 44 return cfab.foreground_256(c, text.toStringz).takeown; 45 } 46 47 /++ 48 Applies the $(D c) to the background of $(D text) 49 +/ 50 string background_256(String)(String text, rgb_t c) 51 if(isSomeString!String) 52 { 53 return cfab.background_256(c, text.toStringz).takeown; 54 } 55 56 /++ 57 Highlights $(D text) with the color $(D c) 58 +/ 59 string highlight_256(String)(String text, rgb_t c) 60 if(isSomeString!String) 61 { 62 return cfab.highlight_256(c, text.toStringz).takeown; 63 } 64 65 /++ 66 Converts an xterm color number into an RGB value 67 +/ 68 rgb_t xterm_to_rgb(int xcolor) 69 { 70 auto res = cfab.xterm_to_rgb_i(xcolor); 71 return cfab.rgb_t( 72 (res>>16) & 0xFF, 73 (res>>8) & 0xFF, 74 res & 0xFF 75 ); 76 } 77 78 /++ 79 Create an $(D rgb_t) 80 Params: 81 r = The amount of red 82 g = The amount of green 83 b = The amount of blue 84 +/ 85 auto rgb(ubyte r, ubyte g, ubyte b) { 86 return rgb_t(r, g, b); 87 } 88 89 ///Stores converted image data 90 struct Image 91 { 92 public: 93 /++ 94 Load an image 95 Params: 96 path = The name of the file to load the image from 97 +/ 98 this(string path) 99 { 100 auto xti = cfab.image_to_xterm(path.toStringz); 101 scope(exit) cfab.xcolor_image_free(xti); 102 image = cfab.image_to_string(xti).takeown; 103 } 104 /// Prints the image 105 void toString(scope void delegate(const(char)[]) sink) const 106 { 107 sink(image); 108 } 109 private: 110 @disable this(); 111 112 string image; 113 } 114 115 unittest { 116 // Test styles 117 import std.algorithm : equal; 118 import std.range : chain; 119 enum T = "Hello There"; 120 auto test_generic(Color c, string prefix, string suffix) 121 { 122 return equal(T.apply_color(c).to!string, chain(prefix, T, suffix)); 123 } 124 with(Color) { 125 assert(test_generic(BOLD, "\x1b[1m", "\x1b[22m")); 126 assert(test_generic(ITALIC, "\x1b[3m", "\x1b[23m")); 127 assert(test_generic(UNDER, "\x1b[4m", "\x1b[24m")); 128 assert(test_generic(UNDER2, "\x1b[21m", "\x1b[24m")); 129 assert(test_generic(STRIKE, "\x1b[9m", "\x1b[29m")); 130 assert(test_generic(BLINK, "\x1b[5m", "\x1b[25m")); 131 assert(test_generic(FLIP, "\x1b[7m", "\x1b[27m")); 132 } 133 } 134 135 unittest { 136 // Test colors 137 import std.algorithm : equal; 138 import std.range : chain; 139 enum T = "Hello There"; 140 auto test_color(Color c, string prefix) 141 { 142 return equal(T.apply_color(c).to!string, chain(prefix, T, "\x1b[39m")); 143 } 144 with(Color) { 145 assert(test_color(BLACK, "\x1b[30m")); 146 assert(test_color(RED, "\x1b[31m")); 147 assert(test_color(GREEN, "\x1b[32m")); 148 assert(test_color(YELLOW, "\x1b[33m")); 149 assert(test_color(BLUE, "\x1b[34m")); 150 assert(test_color(MAGENTA, "\x1b[35m")); 151 assert(test_color(CYAN, "\x1b[36m")); 152 assert(test_color(WHITE, "\x1b[37m")); 153 } 154 } 155