16 using namespace std::literals;
19 const std::array<const char*, 33> palette16code = {
41 return red_ == rhs.red_ && green_ == rhs.green_ && blue_ == rhs.blue_ &&
46 return !operator==(rhs);
52 return is_background_color ?
"49"s :
"39"s;
55 return palette16code[2 * red_ + is_background_color];
58 return (is_background_color ?
"48;5;"s :
"38;5;"s) +
std::to_string(red_);
62 return (is_background_color ?
"48;2;"s :
"38;2;"s)
87 type_ = ColorType::Palette16;
99 : type_(ColorType::
TrueColor), red_(red), green_(green), blue_(blue) {
105 const int max_distance = 256 * 256 * 3;
106 int closest = max_distance;
108 const int database_begin = 16;
109 const int database_end = 256;
110 for (
int i = database_begin; i < database_end; ++i) {
112 const int dr = color_info.
red - red;
113 const int dg = color_info.
green - green;
114 const int db = color_info.
blue - blue;
115 const int dist = dr * dr + dg * dg + db * db;
116 if (closest > dist) {
123 type_ = ColorType::Palette256;
126 type_ = ColorType::Palette16;
140 return {red, green, blue};
156 uint8_t region = h / 43;
157 uint8_t remainder = (h - (region * 43)) * 6;
158 uint8_t p = (v * (255 - s)) >> 8;
159 uint8_t q = (v * (255 - ((s * remainder) >> 8))) >> 8;
160 uint8_t t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
164 case 0:
return Color(v,t,p);
165 case 1:
return Color(q,v,p);
166 case 2:
return Color(p,v,t);
167 case 3:
return Color(p,q,v);
168 case 4:
return Color(t,p,v);
169 case 5:
return Color(v,p,q);
177 if (a.type_ == ColorType::Palette1 ||
178 b.type_ == ColorType::Palette1) {
187 uint8_t* red, uint8_t* green, uint8_t* blue) {
188 switch (
color.type_) {
189 case ColorType::Palette1: {
193 case ColorType::Palette16: {
201 case ColorType::Palette256: {
209 case ColorType::TrueColor:
212 *green =
color.green_;
225 get_color(a, &a_r, &a_g, &a_b);
226 get_color(b, &b_r, &b_g, &b_b);
230 auto interp = [t](uint8_t a_u, uint8_t b_u) {
231 constexpr
float gamma = 2.2F;
232 const float a_f = powf(a_u, gamma);
233 const float b_f = powf(b_u, gamma);
234 const float c_f = a_f * (1.0F - t) +
236 return static_cast<uint8_t
>(powf(c_f, 1.F / gamma));
243 inline namespace literals {
245 Color operator""_rgb(
unsigned long long int combined) {
247 auto const red =
static_cast<uint8_t
>(combined >> 16U);
248 auto const green =
static_cast<uint8_t
>(combined >> 8U);
249 auto const blue =
static_cast<uint8_t
>(combined);
250 return {red, green, blue};
A class representing terminal colors.
enum Palette1 uint8_t enum Palette16 uint8_t enum Palette256 uint8_t Color()
Build a transparent color.
static Color HSV(uint8_t hue, uint8_t saturation, uint8_t value)
Build a Color from its HSV representation. https://en.wikipedia.org/wiki/HSL_and_HSV.
bool operator!=(const Color &rhs) const
bool operator==(const Color &rhs) const
static Color RGB(uint8_t red, uint8_t green, uint8_t blue)
Build a Color from its RGB representation. https://en.wikipedia.org/wiki/RGB_color_model.
std::string Print(bool is_background_color) const
static Color Interpolate(float t, const Color &a, const Color &b)
Color ColorSupport()
Get the color support of the terminal.
std::string to_string(const std::wstring &s)
Convert a UTF8 std::string into a std::wstring.
ColorInfo GetColorInfo(Color::Palette256 index)
Decorator color(Color)
Decorate using a foreground color.