ansicolor.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. #include "ansicolor.h"
  2. #include <string>
  3. /**
  4. * @file
  5. * @brief ANSIColor
  6. */
  7. /**
  8. * Construct a new ANSIColor::ANSIColor object
  9. * with sensible defaults (White on Black).
  10. *
  11. */
  12. ANSIColor::ANSIColor() : fg(COLOR::WHITE), bg(COLOR::BLACK), attr(0) {}
  13. /**
  14. * Construct a new ANSIColor::ANSIColor object
  15. * with attribute set.
  16. *
  17. * @param[in] a ATTR
  18. */
  19. ANSIColor::ANSIColor(ATTR a) : ANSIColor() { Attr(a); }
  20. /* // This won't work. There's no clear way to set bold colors easily.
  21. ANSIColor::ANSIColor(int c1) {}
  22. ANSIColor::ANSIColor(int c1, int c2) {}
  23. */
  24. /**
  25. * Construct a new ANSIColor::ANSIColor object
  26. * with a foreground color.
  27. *
  28. * @param[in] f COLOR
  29. */
  30. ANSIColor::ANSIColor(COLOR f) : ANSIColor() { fg = f; }
  31. /**
  32. * Construct a new ANSIColor::ANSIColor object
  33. * with a foreground color and attribute.
  34. *
  35. * @param[in] f COLOR
  36. * @param[in] a ATTR
  37. */
  38. ANSIColor::ANSIColor(COLOR f, ATTR a) : ANSIColor() {
  39. fg = f;
  40. Attr(a);
  41. }
  42. /**
  43. * Construct a new ANSIColor::ANSIColor object
  44. * with a foreground color and attributes.
  45. *
  46. * @param[in] f COLOR
  47. * @param[in] a1 ATTR
  48. * @param[in] a2 ATTR
  49. */
  50. ANSIColor::ANSIColor(COLOR f, ATTR a1, ATTR a2) : ANSIColor() {
  51. fg = f;
  52. Attr(a1);
  53. Attr(a2);
  54. }
  55. ANSIColor::ANSIColor(std::initializer_list<int> il) : ANSIColor() {
  56. for (auto const &i : il) {
  57. switch (i) {
  58. case 1:
  59. attr |= A_BOLD;
  60. break;
  61. case 5:
  62. attr |= A_BLINK;
  63. break;
  64. case 30:
  65. case 31:
  66. case 32:
  67. case 33:
  68. case 34:
  69. case 35:
  70. case 36:
  71. case 37:
  72. fg = (COLOR)(i - 30);
  73. break;
  74. case 40:
  75. case 41:
  76. case 42:
  77. case 43:
  78. case 44:
  79. case 45:
  80. case 46:
  81. case 47:
  82. bg = (COLOR)(i - 40);
  83. break;
  84. }
  85. }
  86. }
  87. /**
  88. * Construct a new ANSIColor::ANSIColor object
  89. * with a foreground and background color.
  90. *
  91. * @param[in] f foreground COLOR
  92. * @param[in] b background COLOR
  93. */
  94. ANSIColor::ANSIColor(COLOR f, COLOR b) : ANSIColor() {
  95. fg = f;
  96. bg = b;
  97. }
  98. /**
  99. * Construct a new ANSIColor::ANSIColor object
  100. * with a foreground color, background color,
  101. * and attribute.
  102. *
  103. * @param[in] f foreground COLOR
  104. * @param[in] b background COLOR
  105. * @param[in] a ATTR
  106. */
  107. ANSIColor::ANSIColor(COLOR f, COLOR b, ATTR a) : ANSIColor() {
  108. fg = f;
  109. bg = b;
  110. Attr(a);
  111. }
  112. /**
  113. * Construct a new ANSIColor::ANSIColor object
  114. * with foreground, background color and attributes.
  115. *
  116. * @param[in] f foreground COLOR
  117. * @param[in] b background COLOR
  118. * @param[in] a1 ATTR
  119. * @param[in] a2 ATTR
  120. */
  121. ANSIColor::ANSIColor(COLOR f, COLOR b, ATTR a1, ATTR a2) : ANSIColor() {
  122. fg = f;
  123. bg = b;
  124. Attr(a1);
  125. Attr(a2);
  126. }
  127. /**
  128. * Set attribute. We return the object so
  129. * calls can be chained.
  130. *
  131. * @param[in] a ATTR
  132. * @return ANSIColor&
  133. */
  134. ANSIColor &ANSIColor::Attr(ATTR a) {
  135. switch (a) {
  136. case ATTR::RESET:
  137. attr |= A_RESET;
  138. break;
  139. case ATTR::BOLD:
  140. attr |= A_BOLD;
  141. break;
  142. case ATTR::BLINK:
  143. attr |= A_BLINK;
  144. break;
  145. case ATTR::INVERSE:
  146. attr |= A_INVERSE;
  147. break;
  148. }
  149. return *this;
  150. }
  151. #define MASK (A_BOLD | A_BLINK | A_INVERSE)
  152. /**
  153. * Equal operator.
  154. *
  155. * This compares colors and attributes, but ignores reset.
  156. *
  157. * @param[in] c const ANSIColor &
  158. * @return bool
  159. */
  160. bool ANSIColor::operator==(const ANSIColor &c) const {
  161. return ((fg == c.fg) and (bg == c.bg) and ((attr & MASK) == (c.attr & MASK)));
  162. }
  163. /**
  164. * Not-equal operator.
  165. *
  166. * This compares colors and attributes, but ignores reset.
  167. *
  168. * @param[in] c const ANSIColor &
  169. * @return bool
  170. */
  171. bool ANSIColor::operator!=(const ANSIColor &c) const {
  172. return !((fg == c.fg) and (bg == c.bg) and
  173. ((attr & MASK) == (c.attr & MASK)));
  174. }
  175. /**
  176. * @brief Set foreground color
  177. *
  178. * @param[in] f foreground COLOR
  179. */
  180. void ANSIColor::setFg(COLOR f) {
  181. fg = f;
  182. attr = 0;
  183. }
  184. /**
  185. * @brief Set foreground color and attribute
  186. *
  187. * @param[in] f foreground COLOR
  188. * @param[in] a ATTR
  189. */
  190. void ANSIColor::setFg(COLOR f, ATTR a) {
  191. fg = f;
  192. setAttr(a);
  193. }
  194. /**
  195. * @brief Set background color
  196. *
  197. * @param[in] b background COLOR
  198. */
  199. void ANSIColor::setBg(COLOR b) { bg = b; }
  200. /**
  201. * @brief Set attribute
  202. *
  203. * This clears all the attributes before setting the selected ATTR.
  204. *
  205. * @param[in] a ATTR
  206. */
  207. void ANSIColor::setAttr(ATTR a) {
  208. // first, clear all attributes
  209. attr = 0;
  210. Attr(a);
  211. }
  212. /**
  213. * Output the full ANSI codes for attributes and color.
  214. * This does not look at the previous values.
  215. */
  216. std::string ANSIColor::output(void) const {
  217. std::string clr(CSI);
  218. // check for special cases
  219. if (((attr & A_RESET) == A_RESET) and (fg == COLOR::BLACK) and
  220. (bg == COLOR::BLACK)) {
  221. clr += "0m";
  222. return clr;
  223. }
  224. if (((attr & A_RESET) == A_RESET) and (fg == COLOR::WHITE) and
  225. (bg == COLOR::BLACK)) {
  226. clr += "0m";
  227. return clr;
  228. }
  229. if ((attr & A_RESET) == A_RESET) {
  230. clr += "0;";
  231. }
  232. if ((attr & A_BOLD) == A_BOLD) {
  233. if ((attr & A_BLINK) == A_BLINK) {
  234. clr += "5;";
  235. }
  236. clr += "1;";
  237. } else {
  238. if (!((attr & A_RESET) == A_RESET)) clr += "0;";
  239. if ((attr & A_BLINK) == A_BLINK) {
  240. clr += "5;";
  241. }
  242. }
  243. clr += std::to_string(30 + (int)fg) + ";";
  244. clr += std::to_string(40 + (int)bg) + "m";
  245. return clr;
  246. }
  247. std::string ANSIColor::operator()(void) const {
  248. std::string clr(CSI);
  249. // check for special cases
  250. if (((attr & A_RESET) == A_RESET) and (fg == COLOR::BLACK) and
  251. (bg == COLOR::BLACK)) {
  252. clr += "0m";
  253. return clr;
  254. }
  255. if (((attr & A_RESET) == A_RESET) and (fg == COLOR::WHITE) and
  256. (bg == COLOR::BLACK)) {
  257. clr += "0m";
  258. return clr;
  259. }
  260. if ((attr & A_RESET) == A_RESET) {
  261. clr += "0;";
  262. }
  263. if ((attr & A_BOLD) == A_BOLD) {
  264. if ((attr & A_BLINK) == A_BLINK) {
  265. clr += "5;";
  266. }
  267. clr += "1;";
  268. } else {
  269. if (!((attr & A_RESET) == A_RESET)) clr += "0;";
  270. if ((attr & A_BLINK) == A_BLINK) {
  271. clr += "5;";
  272. }
  273. }
  274. clr += std::to_string(30 + (int)fg) + ";";
  275. clr += std::to_string(40 + (int)bg) + "m";
  276. return clr;
  277. }
  278. ANSIColor reset(ATTR::RESET);