1 #pragma once 2 #include <cstdint> 3 #include <cstdio> 4 5 //#define CONSOLE_COLORS_FORCE_ASCII 6 7 #if defined _WIN32 && !defined PRINT_COLORED_FORCE_ASCII 8 #define USE_WIN32_API 9 #endif 10 11 #if defined(USE_WIN32_API) 12 13 namespace win32_lite 14 { 15 typedef void* HANDLE; 16 typedef uint32_t DWORD; 17 18 #define WIN32_LITE_STD_INPUT_HANDLE (static_cast<win32_lite::DWORD>(-10)) 19 #define WIN32_LITE_STD_OUTPUT_HANDLE (static_cast<win32_lite::DWORD>(-11)) 20 #define WIN32_LITE_STD_ERROR_HANDLE (static_cast<win32_lite::DWORD>(-12)) 21 22 #define WIN32_LITE_ENABLE_VIRTUAL_TERMINAL_PROCESSING (4) 23 24 #define WIN32_LITE_DECLSPEC_IMPORT __declspec(dllimport) 25 26 #define WIN32_LITE_WINAPI __stdcall 27 28 typedef short SHORT; 29 typedef unsigned short WORD; 30 typedef int WINBOOL; 31 32 extern "C" 33 { 34 WIN32_LITE_DECLSPEC_IMPORT WINBOOL WIN32_LITE_WINAPI GetConsoleMode(HANDLE hConsole, DWORD* dwMode); 35 WIN32_LITE_DECLSPEC_IMPORT WINBOOL WIN32_LITE_WINAPI SetConsoleMode(HANDLE hConsole, DWORD dwMode); 36 WIN32_LITE_DECLSPEC_IMPORT HANDLE WIN32_LITE_WINAPI GetStdHandle(DWORD nStdHandle); 37 WIN32_LITE_DECLSPEC_IMPORT WINBOOL WIN32_LITE_WINAPI SetConsoleTextAttribute(HANDLE hConsoleOutput, 38 WORD wAttributes); 39 } 40 } // namespace win32_lite 41 42 #endif 43 44 namespace console_colors 45 { 46 47 enum text_color : uint32_t 48 { 49 Black = 0x00, 50 DarkBlue = 0x01, 51 DarkGreen = 0x02, 52 DarkCyan = 0x03, 53 DarkRed = 0x04, 54 DarkMagenta = 0x05, 55 DarkYellow = 0x06, 56 LightGrey = 0x07, 57 Gray = 0x08, 58 Blue = 0x09, 59 Green = 0x0A, 60 Cyan = 0x0B, 61 Red = 0x0C, 62 Magenta = 0x0D, 63 Yellow = 0x0E, 64 White = 0x0F, 65 BgBlack = 0x00, 66 BgDarkBlue = 0x10, 67 BgDarkGreen = 0x20, 68 BgDarkCyan = 0x30, 69 BgDarkRed = 0x40, 70 BgDarkMagenta = 0x50, 71 BgDarkYellow = 0x60, 72 BgLightGrey = 0x70, 73 BgGray = 0x80, 74 BgBlue = 0x90, 75 BgGreen = 0xA0, 76 BgCyan = 0xB0, 77 BgRed = 0xC0, 78 BgMagenta = 0xD0, 79 BgYellow = 0xE0, 80 BgWhite = 0xF0, 81 82 Normal = BgBlack | LightGrey 83 }; 84 85 enum console_buffer 86 { 87 ConsoleStdOutput, 88 ConsoleStdError 89 }; 90 91 struct console_color 92 { 93 public: console_colorconsole_colors::console_color94 console_color(text_color c, console_buffer console = ConsoleStdOutput) 95 : m_old(get(console)), m_console(console) 96 { 97 set(c, m_console); 98 } 99 ~console_colorconsole_colors::console_color100 ~console_color() { set(m_old, m_console); } 101 102 private: getconsole_colors::console_color103 text_color get(console_buffer = ConsoleStdOutput) { return saved_color(); } 104 setconsole_colors::console_color105 void set(text_color new_color, console_buffer console = ConsoleStdOutput) 106 { 107 #ifdef USE_WIN32_API 108 win32_lite::SetConsoleTextAttribute(win32_lite::GetStdHandle(console == ConsoleStdOutput 109 ? WIN32_LITE_STD_OUTPUT_HANDLE 110 : WIN32_LITE_STD_ERROR_HANDLE), 111 static_cast<win32_lite::WORD>(new_color)); 112 #else 113 if (new_color != Normal) 114 { 115 uint8_t t = new_color & 0xF; 116 uint8_t b = (new_color & 0xF0) >> 4; 117 uint8_t tnum = 30 + ((t & 1) << 2 | (t & 2) | (t & 4) >> 2); 118 uint8_t bnum = 40 + ((b & 1) << 2 | (b & 2) | (b & 4) >> 2); 119 if (t & 8) 120 tnum += 60; 121 if (b & 8) 122 bnum += 60; 123 std::fprintf(console == ConsoleStdOutput ? stdout : stderr, "\x1B[%d;%dm", tnum, bnum); 124 } 125 else 126 { 127 std::fprintf(console == ConsoleStdOutput ? stdout : stderr, "\x1B[0m"); 128 } 129 #endif 130 saved_color() = new_color; 131 } 132 133 text_color m_old; 134 console_buffer m_console; saved_colorconsole_colors::console_color135 static text_color& saved_color() 136 { 137 static text_color color = Normal; 138 return color; 139 } 140 }; 141 142 template <text_color color, console_buffer console = ConsoleStdOutput> 143 struct console_color_tpl : public console_color 144 { 145 public: console_color_tplconsole_colors::console_color_tpl146 console_color_tpl() : console_color(color, console) {} 147 148 private: 149 }; 150 151 typedef console_color_tpl<DarkBlue> darkblue_text; 152 typedef console_color_tpl<DarkGreen> darkgreen_text; 153 typedef console_color_tpl<DarkCyan> darkcyan_text; 154 typedef console_color_tpl<DarkRed> darkred_text; 155 typedef console_color_tpl<DarkMagenta> darkmagenta_text; 156 typedef console_color_tpl<DarkYellow> darkyellow_text; 157 typedef console_color_tpl<LightGrey> lightgrey_text; 158 typedef console_color_tpl<Gray> gray_text; 159 typedef console_color_tpl<Blue> blue_text; 160 typedef console_color_tpl<Green> green_text; 161 typedef console_color_tpl<Cyan> cyan_text; 162 typedef console_color_tpl<Red> red_text; 163 typedef console_color_tpl<Magenta> magenta_text; 164 typedef console_color_tpl<Yellow> yellow_text; 165 typedef console_color_tpl<White> white_text; 166 } // namespace console_colors 167