Compare commits
15 Commits
Prerelease
...
master
Author | SHA1 | Date | |
---|---|---|---|
6a8938305e | |||
42e773b5a1 | |||
25d804ce79 | |||
954b8cb4b5 | |||
cc4773abba | |||
ce624106f9 | |||
36e180b6c0 | |||
18289d321c | |||
d8d6ad5edc | |||
2c52899c34 | |||
aeebf81a39 | |||
fe25751b07 | |||
40b8206443 | |||
8f49ba5e49 | |||
944e568ecf |
78
README.md
78
README.md
@@ -0,0 +1,78 @@
|
|||||||
|
# mcolor - Maxine's Mean Color Library
|
||||||
|
|
||||||
|
mcolor is a C++20 library designed to provide an efficient suite for color management. Ideal for use in games, console applications, UI, and so forth.
|
||||||
|
|
||||||
|
## Color as a Class
|
||||||
|
|
||||||
|
At its heart, mcolor defines fundamental color structures for clear and concise representation:
|
||||||
|
|
||||||
|
- `Color3`: Represents an RGB color with 8-bit unsigned integer components (uint8_t r, g, b).
|
||||||
|
- `Color4`: Extends Color3 to include an alpha channel (uint8_t r, g, b, a).
|
||||||
|
|
||||||
|
These core types are complemented by a full range of conversion structs, enabling seamless transitions between various color models:
|
||||||
|
|
||||||
|
- `HSV`, `HSVA`: Hue, Saturation, Value (with Alpha)
|
||||||
|
- `RGB`, `RGBA`: Red, Green, Blue (with Alpha) using u8 components.
|
||||||
|
- `RGBf`, `RGBAf`: Red, Green, Blue (with Alpha) using float components.
|
||||||
|
- `LCH`, `LCHA`: Lightness, Chroma, Hue (with Alpha)
|
||||||
|
- `CMYK`: Cyan, Magenta, Yellow, Key (Black)
|
||||||
|
|
||||||
|
The library also includes organized Color Palettes within dedicated namespaces:
|
||||||
|
- `Colors::Primary`, or just `Colors`,
|
||||||
|
- <span style='color: red;'>Colors::Reds</span>
|
||||||
|
- <span style='color: orange;'>Colors::Oranges</span>
|
||||||
|
- <span style='color: yellow;'>Colors::Yellows</span>
|
||||||
|
- <span style='color: green;'>Colors::Greens</span>
|
||||||
|
- <span style='color: cyan;'>Colors::Cyans</span>
|
||||||
|
- <span style='color: blue;'>Colors::Blues</span>
|
||||||
|
- <span style='color: purple;'>Colors::Purples</span>
|
||||||
|
- <span style='color: pink;'>Colors::Pinks</span>
|
||||||
|
- <span style='color: white;'>Colors::Whites</span>
|
||||||
|
- <span style='color: gray;'>Colors::Grays</span>
|
||||||
|
- <span style='color: brown;'>Colors::Browns</span>
|
||||||
|
|
||||||
|
offering a rich set of predefined swatches for immediate use.
|
||||||
|
|
||||||
|
Additionally, we have worked to implement Ansi Escape Codes, console-output utilities, and cross-platform abstraction so that it works the same on Windows and Linux.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Integrating mcolor into your project is straightforward. Here's a quick sample:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
int main() {
|
||||||
|
#ifdef WIN32
|
||||||
|
mcolor::windowsSaneify();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mcolor::printBuiltinColorList();
|
||||||
|
mcolor::printAnsiColorTable();
|
||||||
|
mcolor::printRGBConsoleTest();
|
||||||
|
|
||||||
|
|
||||||
|
for (float i = 0; i < 360; i+=10.f)
|
||||||
|
{
|
||||||
|
HSVA hsva {i, 1.f, 1.f};
|
||||||
|
|
||||||
|
Color4 c = Color4(hsva);
|
||||||
|
|
||||||
|
std::cout << std::format("{}hue:{} rgb: {},{},{} hex: {}", c.ToEscapeCode(), i, c.r, c.g, c.b, c.ToHex()) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
This library was created by `maxine`, and is currently maintained by Josh O'Leary.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Pull requests and issues are always welcome! You know what to do!
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This work is expressly dedicated to the Public Domain under the Unlicense.
|
||||||
|
|
||||||
|
|
||||||
|
201
include/AnsiEscapeCodes.hpp
Normal file
201
include/AnsiEscapeCodes.hpp
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <format>
|
||||||
|
#include <Color4.hpp>
|
||||||
|
|
||||||
|
// Gets set to whatever your terminal emulator is configured for.
|
||||||
|
// This means black can be shown as purple if configured that way.
|
||||||
|
namespace mcolor
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Used for composing legacy ANSI escape sequence builtin colors.
|
||||||
|
/// We much recommend using modern Color4/Color3
|
||||||
|
enum class AnsiColor : uint8_t
|
||||||
|
{
|
||||||
|
RESET = 0,
|
||||||
|
BELL,
|
||||||
|
BOLD,
|
||||||
|
DIM = 2,
|
||||||
|
FG_BLACK = 30,
|
||||||
|
FG_RED,
|
||||||
|
FG_GREEN,
|
||||||
|
FG_YELLOW,
|
||||||
|
FG_BLUE,
|
||||||
|
FG_MAGENTA,
|
||||||
|
FG_CYAN,
|
||||||
|
FG_WHITE,
|
||||||
|
FG_DEFAULT = 39,
|
||||||
|
BG_BLACK = 40,
|
||||||
|
BG_RED,
|
||||||
|
BG_GREEN,
|
||||||
|
BG_YELLOW,
|
||||||
|
BG_BLUE,
|
||||||
|
BG_MAGENTA,
|
||||||
|
BG_CYAN,
|
||||||
|
BG_WHITE,
|
||||||
|
BG_DEFAULT = 49,
|
||||||
|
FG_BRIGHT_BLACK = 90,
|
||||||
|
FG_BRIGHT_RED,
|
||||||
|
FG_BRIGHT_GREEN,
|
||||||
|
FG_BRIGHT_YELLOW,
|
||||||
|
FG_BRIGHT_BLUE,
|
||||||
|
FG_BRIGHT_MAGENTA,
|
||||||
|
FG_BRIGHT_CYAN,
|
||||||
|
FG_BRIGHT_WHITE = 97,
|
||||||
|
BG_BRIGHT_BLACK = 100,
|
||||||
|
BG_BRIGHT_RED,
|
||||||
|
BG_BRIGHT_GREEN,
|
||||||
|
BG_BRIGHT_YELLOW,
|
||||||
|
BG_BRIGHT_BLUE,
|
||||||
|
BG_BRIGHT_MAGENTA,
|
||||||
|
BG_BRIGHT_CYAN,
|
||||||
|
BG_BRIGHT_WHITE = 107,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::string AnsiEscapePrefix = "\033[";
|
||||||
|
|
||||||
|
namespace AnsiEscapeCodes {
|
||||||
|
|
||||||
|
#pragma region General
|
||||||
|
static const std::string Bell = "\a";
|
||||||
|
static const std::string Backspace = "\b";
|
||||||
|
static const std::string Tab = "\t";
|
||||||
|
static const std::string Newline = "\n";
|
||||||
|
static const std::string VerticalTab = "\v";
|
||||||
|
static const std::string Newpage = "\f";
|
||||||
|
static const std::string Return = "\r";
|
||||||
|
static const std::string Escape = "\033";
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Cursor Controls
|
||||||
|
/// Moves cursor to home position {0, 0}.
|
||||||
|
static const std::string CursorHome = AnsiEscapePrefix + "H";
|
||||||
|
/// Moves cursor to line Y, column X.
|
||||||
|
static std::string CursorTo(int line, int column);
|
||||||
|
/// Moves the cursor up # lines.
|
||||||
|
static std::string CursorUp(int lines);
|
||||||
|
|
||||||
|
/// Moves the cursor down # lines.
|
||||||
|
static std::string CursorDown(int lines);
|
||||||
|
|
||||||
|
/// Moves the cursor right # lines.
|
||||||
|
static std::string CursorRight(int lines);
|
||||||
|
|
||||||
|
/// Moves the cursor left # lines.
|
||||||
|
static std::string CursorLeft(int lines);
|
||||||
|
|
||||||
|
/// Moves cursor to the beginning of line, # lines down from the current line.
|
||||||
|
static std::string CursorNextLineStart(int lines);
|
||||||
|
|
||||||
|
/// Moves cursor to the beginning of line, # lines up from the current line.
|
||||||
|
static std::string CursorPrevLineStart(int lines);
|
||||||
|
|
||||||
|
/// Moves cursor to column #.
|
||||||
|
static std::string CursorColumn(int column);
|
||||||
|
|
||||||
|
/// Save current cursor position.
|
||||||
|
static const std::string CursorSave = AnsiEscapePrefix + "7";
|
||||||
|
/// Restore cursor to last saved position.
|
||||||
|
static const std::string CursorRestore = AnsiEscapePrefix + "8";
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Erase Functions
|
||||||
|
static const std::string EraseInDisplay = AnsiEscapePrefix + "J";
|
||||||
|
/// Erase from cursor until end of screen.
|
||||||
|
static const std::string EraseAfterCursor = AnsiEscapePrefix + "0J";
|
||||||
|
/// Erase from cursor to beginning of screen.
|
||||||
|
static const std::string EraseBeforeCursor = AnsiEscapePrefix + "1J";
|
||||||
|
static const std::string EraseEntireScreen = AnsiEscapePrefix + "2J";
|
||||||
|
static const std::string EraseSavedLines = AnsiEscapePrefix + "3J";
|
||||||
|
static const std::string EraseInLine = AnsiEscapePrefix + "K";
|
||||||
|
static const std::string EraseLineAfterCursor = AnsiEscapePrefix + "0K";
|
||||||
|
static const std::string EraseLineBeforeCursor = AnsiEscapePrefix + "1K";
|
||||||
|
#pragma endregion
|
||||||
|
#pragma region Graphics Sequences
|
||||||
|
static const std::string ResetAll = AnsiEscapePrefix + "0m";
|
||||||
|
static const std::string Bold = AnsiEscapePrefix + "1m";
|
||||||
|
static const std::string Dim = AnsiEscapePrefix + "2m";
|
||||||
|
static const std::string Italic = AnsiEscapePrefix + "3m";
|
||||||
|
static const std::string Underline = AnsiEscapePrefix + "4m";
|
||||||
|
static const std::string Blinking = AnsiEscapePrefix + "5m";
|
||||||
|
static const std::string Inverse = AnsiEscapePrefix + "6m";
|
||||||
|
static const std::string Hidden = AnsiEscapePrefix + "7m";
|
||||||
|
static const std::string Strikethrough = AnsiEscapePrefix + "8m";
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Color Sequences
|
||||||
|
|
||||||
|
static const std::string FgBlack = AnsiEscapePrefix + "30";
|
||||||
|
static const std::string BgBlack = AnsiEscapePrefix + "40";
|
||||||
|
|
||||||
|
static const std::string FgRed = AnsiEscapePrefix + "31";
|
||||||
|
static const std::string BgRed = AnsiEscapePrefix + "41";
|
||||||
|
|
||||||
|
static const std::string FgGreen = AnsiEscapePrefix + "32";
|
||||||
|
static const std::string BgGreen = AnsiEscapePrefix + "42";
|
||||||
|
|
||||||
|
static const std::string FgYellow = AnsiEscapePrefix + "33";
|
||||||
|
static const std::string BgYellow = AnsiEscapePrefix + "43";
|
||||||
|
|
||||||
|
static const std::string FgBlue = AnsiEscapePrefix + "34";
|
||||||
|
static const std::string BgBlue = AnsiEscapePrefix + "44";
|
||||||
|
|
||||||
|
static const std::string FgMagenta = AnsiEscapePrefix + "35";
|
||||||
|
static const std::string BgMagenta = AnsiEscapePrefix + "45";
|
||||||
|
|
||||||
|
static const std::string FgCyan = AnsiEscapePrefix + "36";
|
||||||
|
static const std::string BgCyan = AnsiEscapePrefix + "46";
|
||||||
|
|
||||||
|
static const std::string FgWhite = AnsiEscapePrefix + "37";
|
||||||
|
static const std::string BgWhite = AnsiEscapePrefix + "47";
|
||||||
|
|
||||||
|
static const std::string FgDefault = AnsiEscapePrefix + "38";
|
||||||
|
static const std::string BgDefault = AnsiEscapePrefix + "48";
|
||||||
|
|
||||||
|
static const std::string FgBrightBlack = AnsiEscapePrefix + "90";
|
||||||
|
static const std::string BgBrightBlack = AnsiEscapePrefix + "100";
|
||||||
|
|
||||||
|
static const std::string FgBrightRed = AnsiEscapePrefix + "91";
|
||||||
|
static const std::string BgBrightRed = AnsiEscapePrefix + "101";
|
||||||
|
|
||||||
|
static const std::string FgBrightGreen = AnsiEscapePrefix + "92";
|
||||||
|
static const std::string BgBrightGreen = AnsiEscapePrefix + "102";
|
||||||
|
|
||||||
|
static const std::string FgBrightYellow = AnsiEscapePrefix + "93";
|
||||||
|
static const std::string BgBrightYellow = AnsiEscapePrefix + "103";
|
||||||
|
|
||||||
|
static const std::string FgBrightBlue = AnsiEscapePrefix + "94";
|
||||||
|
static const std::string BgBrightBlue = AnsiEscapePrefix + "104";
|
||||||
|
|
||||||
|
static const std::string FgBrightMagenta = AnsiEscapePrefix + "95";
|
||||||
|
static const std::string BgBrightMagenta = AnsiEscapePrefix + "105";
|
||||||
|
|
||||||
|
static const std::string FgBrightCyan = AnsiEscapePrefix + "96";
|
||||||
|
static const std::string BgBrightCyan = AnsiEscapePrefix + "106";
|
||||||
|
|
||||||
|
static const std::string FgBrightWhite = AnsiEscapePrefix + "97";
|
||||||
|
static const std::string BgBrightWhite = AnsiEscapePrefix + "107";
|
||||||
|
|
||||||
|
static std::string FgTrueColor(int r, int g, int b);
|
||||||
|
|
||||||
|
static std::string FgTrueColor(const Color4& c);
|
||||||
|
|
||||||
|
static std::string BgTrueColor(int r, int g, int b);
|
||||||
|
|
||||||
|
static std::string BgTrueColor(const Color4& c);
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Private Modes
|
||||||
|
inline static const std::string CursorInvisible = AnsiEscapePrefix + "?25l";
|
||||||
|
static const std::string CursorVisible = AnsiEscapePrefix + "?25h";
|
||||||
|
static const std::string RestoreScreen = AnsiEscapePrefix + "?47l";
|
||||||
|
static const std::string SaveScreen = AnsiEscapePrefix + "?47h";
|
||||||
|
static const std::string EnableAltBuffer = AnsiEscapePrefix + "?1049h";
|
||||||
|
static const std::string DisableAltBuffer = AnsiEscapePrefix + "?1049l";
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -18,12 +18,17 @@ class Color4;
|
|||||||
|
|
||||||
std::string toEscapeCode(Color4 c, bool bg=false);
|
std::string toEscapeCode(Color4 c, bool bg=false);
|
||||||
|
|
||||||
void print_builtin_color_list();
|
namespace mcolor
|
||||||
|
{
|
||||||
|
void printBuiltinColorList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// A type representing a color with alpha.
|
/// A type representing a color with alpha.
|
||||||
/// Our default format is RGBA with 8 bits-per-channel.
|
/// Our default format is RGBA with 8 bits-per-channel.
|
||||||
/// Conversions to other color formats are provided.
|
/// Conversions to other color formats are provided.
|
||||||
class Color4 {
|
class Color4
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
u8 r;
|
u8 r;
|
||||||
u8 g;
|
u8 g;
|
||||||
@@ -73,15 +78,17 @@ public:
|
|||||||
|
|
||||||
static Color4 FromHexA(const std::string& hexACode);
|
static Color4 FromHexA(const std::string& hexACode);
|
||||||
|
|
||||||
static Color4 FromHSV(float hue, float saturation, float value, float alpha = 1.f) {
|
static Color4 FromHSV(const HSV& hsv, float alpha = 1.f);
|
||||||
// TODO: implement
|
|
||||||
return {};
|
/// @param hue The hue value represented in degrees [0-360]
|
||||||
}
|
|
||||||
|
static Color4 FromHSV(float hue, float saturation, float value, float alpha = 1.f);
|
||||||
static Color4 FromHSL(float hue, float saturation, float lightness, float alpha = 1.f);
|
static Color4 FromHSL(float hue, float saturation, float lightness, float alpha = 1.f);
|
||||||
static Color4 FromNormalized(float red, float green, float blue, float alpha = 1.f);
|
static Color4 FromNormalized(float red, float green, float blue, float alpha = 1.f);
|
||||||
static Color4 FromLCH(float l, float c, float h, float alpha = 1.f);
|
static Color4 FromLCH(float l, float c, float h, float alpha = 1.f);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Performs the interpolation in normalized color space (0-1) and converts it back.
|
||||||
[[nodiscard]] Color4 Lerp(const Color4& rhs, float t) const;
|
[[nodiscard]] Color4 Lerp(const Color4& rhs, float t) const;
|
||||||
static Color4 Lerp(const Color4& lhs, const Color4& rhs, float t);
|
static Color4 Lerp(const Color4& lhs, const Color4& rhs, float t);
|
||||||
|
|
||||||
@@ -93,7 +100,7 @@ public:
|
|||||||
[[nodiscard]] Color4 LerpByHSVA(const Color4& rhs, float t) const;
|
[[nodiscard]] Color4 LerpByHSVA(const Color4& rhs, float t) const;
|
||||||
|
|
||||||
[[nodiscard]] std::string ToHex() const;
|
[[nodiscard]] std::string ToHex() const;
|
||||||
[[nodiscard]] std::string ToHexA() const;
|
[[nodiscard]] std::string ToHexAlpha() const;
|
||||||
|
|
||||||
[[nodiscard]] u8 RedChannel() const;
|
[[nodiscard]] u8 RedChannel() const;
|
||||||
[[nodiscard]] u8 GreenChannel() const;
|
[[nodiscard]] u8 GreenChannel() const;
|
||||||
@@ -128,4 +135,22 @@ public:
|
|||||||
// TODO: Color4 ToLCH
|
// TODO: Color4 ToLCH
|
||||||
LCH ToLCH() const;
|
LCH ToLCH() const;
|
||||||
|
|
||||||
};
|
// TODO: Disparate with mcolor::toEscapeCode, resolve.
|
||||||
|
[[nodiscard]] std::string EscapeCode(bool bg = false, bool bold = false) const;
|
||||||
|
|
||||||
|
[[nodiscard]] std::string FGEscapeCode(bool bold = false) const;
|
||||||
|
[[nodiscard]] std::string BGEscapeCode(bool bold = false) const;
|
||||||
|
|
||||||
|
|
||||||
|
bool operator==(const Color4& rhs) const;
|
||||||
|
|
||||||
|
bool operator!=(const Color4& rhs) const;
|
||||||
|
|
||||||
|
|
||||||
|
std::string ToEscapeCode(bool bg = false) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream& operator << (std::ostream& os, const Color4& c) {
|
||||||
|
os << "Color4(" << c.r << "," << c.g << "," << c.b << "," << c.a << ") AKA " << c.ToHex();
|
||||||
|
return os;
|
||||||
|
}
|
@@ -5,7 +5,8 @@
|
|||||||
#define COLOR static const Color4
|
#define COLOR static const Color4
|
||||||
|
|
||||||
namespace Colors {
|
namespace Colors {
|
||||||
COLOR Transparent{0,0,0,0};
|
|
||||||
|
COLOR Transparent = Color4(0,0,0,0);
|
||||||
namespace Primary {
|
namespace Primary {
|
||||||
COLOR Red{255, 0, 0};
|
COLOR Red{255, 0, 0};
|
||||||
COLOR Green{0, 255, 0};
|
COLOR Green{0, 255, 0};
|
||||||
@@ -174,4 +175,5 @@ namespace Colors {
|
|||||||
COLOR Brown{164, 42, 42};
|
COLOR Brown{164, 42, 42};
|
||||||
COLOR Maroon{128, 0, 0};
|
COLOR Maroon{128, 0, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -7,86 +7,21 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "Color3.hpp"
|
||||||
#include "Color4.hpp"
|
#include "Color4.hpp"
|
||||||
|
#include "Colors.hpp"
|
||||||
|
#include "AnsiEscapeCodes.hpp"
|
||||||
|
|
||||||
// Gets set to whatever your terminal emulator is configured for.
|
namespace mcolor {
|
||||||
// This means black can be shown as purple if configured that way.
|
|
||||||
namespace mcolor
|
|
||||||
{
|
|
||||||
enum class AnsiColor : uint8_t
|
|
||||||
{
|
|
||||||
RESET = 0,
|
|
||||||
BOLD,
|
|
||||||
DIM = 2,
|
|
||||||
FG_BLACK = 30,
|
|
||||||
FG_RED,
|
|
||||||
FG_GREEN,
|
|
||||||
FG_YELLOW,
|
|
||||||
FG_BLUE,
|
|
||||||
FG_MAGENTA,
|
|
||||||
FG_CYAN,
|
|
||||||
FG_WHITE,
|
|
||||||
FG_DEFAULT = 39,
|
|
||||||
BG_BLACK = 40,
|
|
||||||
BG_RED,
|
|
||||||
BG_GREEN,
|
|
||||||
BG_YELLOW,
|
|
||||||
BG_BLUE,
|
|
||||||
BG_MAGENTA,
|
|
||||||
BG_CYAN,
|
|
||||||
BG_WHITE,
|
|
||||||
BG_DEFAULT = 49,
|
|
||||||
FG_BRIGHT_BLACK = 90,
|
|
||||||
FG_BRIGHT_RED,
|
|
||||||
FG_BRIGHT_GREEN,
|
|
||||||
FG_BRIGHT_YELLOW,
|
|
||||||
FG_BRIGHT_BLUE,
|
|
||||||
FG_BRIGHT_MAGENTA,
|
|
||||||
FG_BRIGHT_CYAN,
|
|
||||||
FG_BRIGHT_WHITE = 97,
|
|
||||||
BG_BRIGHT_BLACK = 100,
|
|
||||||
BG_BRIGHT_RED,
|
|
||||||
BG_BRIGHT_GREEN,
|
|
||||||
BG_BRIGHT_YELLOW,
|
|
||||||
BG_BRIGHT_BLUE,
|
|
||||||
BG_BRIGHT_MAGENTA,
|
|
||||||
BG_BRIGHT_CYAN,
|
|
||||||
BG_BRIGHT_WHITE = 107,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace mcolor::rgbColors
|
|
||||||
{
|
|
||||||
// Basically default ugly standard UNIX colors for now
|
|
||||||
static const Color4 BLACK = {0,0,0};
|
|
||||||
static const Color4 RED = {170, 0, 0};
|
|
||||||
static const Color4 GREEN = {0, 170, 0};
|
|
||||||
static const Color4 YELLOW = {170, 170, 0};
|
|
||||||
static const Color4 BLUE = {0, 0, 170};
|
|
||||||
static const Color4 MAGENTA = {170, 0, 170};
|
|
||||||
static const Color4 CYAN = {0, 170, 170};
|
|
||||||
static const Color4 WHITE = {170, 170, 170};
|
|
||||||
static const Color4 DEFAULT = {170, 170, 170};
|
|
||||||
|
|
||||||
static const Color4 BRIGHT_BLACK = {8,5, 85,};
|
|
||||||
static const Color4 BRIGHT_RED = {85, 85, 255};
|
|
||||||
static const Color4 BRIGHT_GREEN = {85, 255, 85};
|
|
||||||
static const Color4 BRIGHT_YELLOW = {85, 255, 255};
|
|
||||||
static const Color4 BRIGHT_BLUE = {255, 85, 85};
|
|
||||||
static const Color4 BRIGHT_MAGENTA = {255, 85, 255};
|
|
||||||
static const Color4 BRIGHT_CYAN = {255, 255, 85};
|
|
||||||
static const Color4 BRIGHT_WHITE = {255, 255, 255};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace mcolor
|
|
||||||
{
|
|
||||||
std::string toEscapeCode(Color4 c, bool bg=false);
|
std::string toEscapeCode(Color4 c, bool bg=false);
|
||||||
|
|
||||||
std::string toEscapeCode(AnsiColor c);
|
std::string toEscapeCode(AnsiColor c);
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
|
/// Performs a hack that allows the windows console to interpret ANSI codes.
|
||||||
|
/// @note This only works on Windows 10 version 1511 and newer.
|
||||||
void windowsSaneify();
|
void windowsSaneify();
|
||||||
#endif
|
|
||||||
|
|
||||||
void printAnsiColorTable();
|
void printAnsiColorTable();
|
||||||
|
|
||||||
|
27
main.cpp
27
main.cpp
@@ -5,11 +5,15 @@
|
|||||||
#include <Color4.hpp>
|
#include <Color4.hpp>
|
||||||
#include <Colors.hpp>
|
#include <Colors.hpp>
|
||||||
|
|
||||||
|
std::string fmt_color(const Color4& c)
|
||||||
|
{
|
||||||
|
return std::format("{}hue:{} rgb: {},{},{} hex: {}", c.ToEscapeCode(), c.ToHSV().h, c.r, c.g, c.b, c.ToHex());
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
mcolor::windowsSaneify();
|
||||||
mcolor::windowsSaneify();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO: Demo Color Space Math Operations
|
// TODO: Demo Color Space Math Operations
|
||||||
|
|
||||||
@@ -17,9 +21,24 @@ int main()
|
|||||||
|
|
||||||
// TODO: Demo Color output in console.
|
// TODO: Demo Color output in console.
|
||||||
|
|
||||||
print_builtin_color_list();
|
mcolor::printBuiltinColorList();
|
||||||
mcolor::printAnsiColorTable();
|
mcolor::printAnsiColorTable();
|
||||||
mcolor::printRGBConsoleTest();
|
mcolor::printRGBConsoleTest();
|
||||||
|
|
||||||
|
std::cout << "Color construction from hex codes:" << std::endl;
|
||||||
|
std::cout << fmt_color(Color4::FromHex("#FFFFFF")) << std::endl;
|
||||||
|
std::cout << fmt_color(Color4::FromHex("#F0F0F0")) << std::endl;
|
||||||
|
std::cout << fmt_color(Color4::FromHex("#0F0F0F")) << std::endl;
|
||||||
|
std::cout << fmt_color(Color4::FromHex("#00AAFF")) << std::endl;
|
||||||
|
|
||||||
|
for (float i = 0; i < 360; i+=10.f)
|
||||||
|
{
|
||||||
|
HSVA hsva {i, 1.f, 1.f};
|
||||||
|
|
||||||
|
Color4 c = Color4(hsva);
|
||||||
|
|
||||||
|
std::cout << std::format("{}hue:{} rgb: {},{},{} hex: {}", c.ToEscapeCode(), i, c.r, c.g, c.b, c.ToHex()) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
49
src/AnsiEscapeCodes.cpp
Normal file
49
src/AnsiEscapeCodes.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#include <AnsiEscapeCodes.hpp>
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::CursorTo(int line, int column) {
|
||||||
|
return AnsiEscapePrefix + std::format("{};{}H", line, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::CursorUp(int lines) {
|
||||||
|
return AnsiEscapePrefix + std::format("{}A", lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::CursorDown(int lines) {
|
||||||
|
return AnsiEscapePrefix + std::format("{}B", lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::CursorRight(int lines) {
|
||||||
|
return AnsiEscapePrefix + std::format("{}D", lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::CursorLeft(int lines) {
|
||||||
|
return AnsiEscapePrefix + std::format("{}D", lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::CursorNextLineStart(int lines) {
|
||||||
|
return AnsiEscapePrefix + std::format("{}D", lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::CursorPrevLineStart(int lines) {
|
||||||
|
return AnsiEscapePrefix + std::format("{}D", lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::CursorColumn(int column) {
|
||||||
|
return AnsiEscapePrefix + std::format("{}G", column);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::FgTrueColor(int r, int g, int b) {
|
||||||
|
return AnsiEscapePrefix + std::format("38;2;{};{};{}m", r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::FgTrueColor(const Color4 &c) {
|
||||||
|
return FgTrueColor(c.r, c.g, c.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::BgTrueColor(int r, int g, int b) {
|
||||||
|
return AnsiEscapePrefix + std::format("48;2;{};{};{}m", r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mcolor::AnsiEscapeCodes::BgTrueColor(const Color4 &c) {
|
||||||
|
return BgTrueColor(c.r, c.g, c.b);
|
||||||
|
}
|
@@ -20,7 +20,7 @@ Color3 Color3::FromHex(const std::string &hexCode) {
|
|||||||
// TODO: Support 9-character hex codes (with alpha), but raise a warning that suggests using Color4 instead.
|
// TODO: Support 9-character hex codes (with alpha), but raise a warning that suggests using Color4 instead.
|
||||||
if (hexCode.length() == 7) {
|
if (hexCode.length() == 7) {
|
||||||
u8 r, g, b;
|
u8 r, g, b;
|
||||||
std::sscanf(hexCode.c_str(), "#%02x%02x%02x", &r, &g, &b);
|
std::sscanf(hexCode.c_str(), "#%02hhx%02hhx%02hhx", &r, &g, &b);
|
||||||
return {r, g, b};
|
return {r, g, b};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
258
src/Color4.cpp
258
src/Color4.cpp
@@ -2,8 +2,10 @@
|
|||||||
#include <format>
|
#include <format>
|
||||||
#include <ColorFormats.hpp>
|
#include <ColorFormats.hpp>
|
||||||
|
|
||||||
|
#if !defined(WIN32)
|
||||||
|
// For some reason this causes crash with exit code: -1073741819 on winblows.
|
||||||
std::vector<Color4> list;
|
std::vector<Color4> list;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string toEscapeCode(Color4 c, bool bg){
|
std::string toEscapeCode(Color4 c, bool bg){
|
||||||
if (bg)
|
if (bg)
|
||||||
@@ -12,12 +14,14 @@ std::string toEscapeCode(Color4 c, bool bg){
|
|||||||
return std::format("\033[38;2;{};{};{}m", c.r, c.g, c.b);
|
return std::format("\033[38;2;{};{};{}m", c.r, c.g, c.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_builtin_color_list() {
|
void mcolor::printBuiltinColorList() {
|
||||||
|
#if !defined(WIN32)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const Color4& color : list) {
|
for (const Color4& color : list) {
|
||||||
std::cout << toEscapeCode(color) << i << ": " << "Hello, world!" << std::endl;
|
std::cout << toEscapeCode(color) << i << ": " << "Hello, world!" << std::endl;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Color4::Color4(const RGB &rgb, u8 alpha): Color4(rgb.r, rgb.g, rgb.b, alpha) {}
|
Color4::Color4(const RGB &rgb, u8 alpha): Color4(rgb.r, rgb.g, rgb.b, alpha) {}
|
||||||
@@ -29,55 +33,78 @@ Color4::Color4(const RGBf &rgb, float alpha): Color4(rgb.r * 255, rgb.g * 255, r
|
|||||||
Color4::Color4(const RGBAf &rgba): Color4(rgba.r * 255, rgba.g * 255, rgba.b * 255, rgba.a * 255) { }
|
Color4::Color4(const RGBAf &rgba): Color4(rgba.r * 255, rgba.g * 255, rgba.b * 255, rgba.a * 255) { }
|
||||||
|
|
||||||
Color4::Color4(const HSV &hsv, float alpha) {
|
Color4::Color4(const HSV &hsv, float alpha) {
|
||||||
float h = hsv.h;
|
|
||||||
float s = hsv.s;
|
|
||||||
float v = hsv.v;
|
|
||||||
float M = 255*hsv.v;
|
|
||||||
float m = M*(1-hsv.s);
|
|
||||||
|
|
||||||
float z = (M-m)*(1 - std::abs( std::fmod(hsv.h/60.f, 2) - 1));
|
float hue = hsv.h;
|
||||||
|
float saturation = hsv.s;
|
||||||
|
float value = hsv.v;
|
||||||
|
|
||||||
if (0 <= h <= 60) {
|
float hh, p, q, t, ff;
|
||||||
r = M;
|
long i;
|
||||||
g = z + m;
|
float rn, gn, bn;
|
||||||
b = m;
|
|
||||||
}
|
if (saturation <= 0.0) { // < is bogus, just shuts up warnings.
|
||||||
if (60 <= h < 120) {
|
r = value*255;
|
||||||
r = z + m;
|
g = value*255;
|
||||||
g = M;
|
b = value*255;
|
||||||
b = m;
|
return;
|
||||||
}
|
//return Color4(RGBAf{rn, bn, gn, alpha});
|
||||||
if (120 <= h < 180) {
|
|
||||||
r = m;
|
|
||||||
g = M;
|
|
||||||
b = z + m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (180 <= h < 240) {
|
hh = hue;
|
||||||
r = m;
|
if (hh >= 360.f) hh = 0;
|
||||||
g = z + m;
|
hh /= 60.f;
|
||||||
b = M;
|
i = (long)hh;
|
||||||
}
|
ff = hh - i;
|
||||||
|
p = value * (1.f - saturation);
|
||||||
|
q = value * (1.f - (saturation * ff));
|
||||||
|
t = value * (1.f - (saturation * (1.f - ff)));
|
||||||
|
|
||||||
if (240 <= h < 300) {
|
switch(i) {
|
||||||
r = z + m;
|
case 0:
|
||||||
g = m;
|
rn = value;
|
||||||
b = M;
|
gn = t;
|
||||||
|
bn = p;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
rn = q;
|
||||||
|
gn = value;
|
||||||
|
bn = p;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
rn = p;
|
||||||
|
gn = value;
|
||||||
|
bn = t;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
rn = p;
|
||||||
|
gn = q;
|
||||||
|
bn = value;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
rn = t;
|
||||||
|
gn = p;
|
||||||
|
bn = value;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
default:
|
||||||
|
rn = value;
|
||||||
|
gn = p;
|
||||||
|
bn = q;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
this->r = rn * 255;
|
||||||
if (300 <= h < 360) {
|
this->g = gn * 255;
|
||||||
r = M;
|
this->b = bn * 255;
|
||||||
g = m;
|
this->a = alpha * 255;
|
||||||
b = z + m;
|
//return Color4(RGBAf{rn, gn, bn, alpha});
|
||||||
}
|
|
||||||
|
|
||||||
a = alpha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Color4::Color4(const Color3 &color3, u8 alpha) {r = color3.r; g = color3.g; b = color3.b; a = alpha;}
|
Color4::Color4(const Color3 &color3, u8 alpha) {r = color3.r; g = color3.g; b = color3.b; a = alpha;}
|
||||||
|
|
||||||
Color4::Color4(u8 red, u8 green, u8 blue, u8 alpha): r(red), g(green), b(blue), a(alpha) {
|
Color4::Color4(u8 red, u8 green, u8 blue, u8 alpha): r(red), g(green), b(blue), a(alpha) {
|
||||||
|
#if !defined(WIN32)
|
||||||
list.push_back(*this);
|
list.push_back(*this);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Color4 Color4::FromColor3(const Color3 &color3, u8 alpha) {return Color4(color3, alpha);}
|
Color4 Color4::FromColor3(const Color3 &color3, u8 alpha) {return Color4(color3, alpha);}
|
||||||
@@ -87,13 +114,13 @@ Color4 Color4::FromHex(const std::string &hexCode, u8 alpha) {
|
|||||||
// TODO: Support 9-character hex codes (with alpha), but raise a warning that suggests using FromHexA explicitly instead.
|
// TODO: Support 9-character hex codes (with alpha), but raise a warning that suggests using FromHexA explicitly instead.
|
||||||
if (hexCode.length() == 7) {
|
if (hexCode.length() == 7) {
|
||||||
u8 r, g, b;
|
u8 r, g, b;
|
||||||
std::sscanf(hexCode.c_str(), "#%02x%02x%02x", &r, &g, &b);
|
std::sscanf(hexCode.c_str(), "#%02hhx%02hhx%02hhx", &r, &g, &b);
|
||||||
return {r, g, b, alpha};
|
return {r, g, b, alpha};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hexCode.length() == 9) {
|
if (hexCode.length() == 9) {
|
||||||
u8 r, g, b, a;
|
u8 r, g, b, a;
|
||||||
std::sscanf(hexCode.c_str(), "#%02x%02x%02x%02x", &r, &g, &b, &a);
|
std::sscanf(hexCode.c_str(), "#%02hhx%02hhx%02hhx%02hhx", &r, &g, &b, &a);
|
||||||
return {r, g, b, a};
|
return {r, g, b, a};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +130,7 @@ Color4 Color4::FromHex(const std::string &hexCode, u8 alpha) {
|
|||||||
Color4 Color4::FromHexA(const std::string &hexACode) {
|
Color4 Color4::FromHexA(const std::string &hexACode) {
|
||||||
if (hexACode.length() == 9) {
|
if (hexACode.length() == 9) {
|
||||||
u8 r, g, b, a;
|
u8 r, g, b, a;
|
||||||
std::sscanf(hexACode.c_str(), "#%02x%02x%02x%02x", &r, &g, &b, &a);
|
std::sscanf(hexACode.c_str(), "#%02hhx%02hhx%02hhx%02hhx", &r, &g, &b, &a);
|
||||||
return {r, g, b, a};
|
return {r, g, b, a};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +182,7 @@ Color4 Color4::FromNormalized(float red, float green, float blue, float alpha) {
|
|||||||
|
|
||||||
Color4 Color4::Lerp(const Color4 &rhs, float t) const {
|
Color4 Color4::Lerp(const Color4 &rhs, float t) const {
|
||||||
|
|
||||||
/// Performs the interpolation in normalized color space (0-1) and converts it back.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -299,3 +326,148 @@ LCH Color4::ToLCH() const {
|
|||||||
// TODO: Implement
|
// TODO: Implement
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Color4::EscapeCode(bool bg, bool bold) const {
|
||||||
|
if (bg)
|
||||||
|
return std::format("\033[48;2;{};{};{}m", r, g, b);
|
||||||
|
|
||||||
|
return std::format("\033[38;2;{};{};{}m", r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Color4::FGEscapeCode(bool bold) const {
|
||||||
|
return EscapeCode(false, bold);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Color4::BGEscapeCode(bool bold) const {
|
||||||
|
return EscapeCode(true, bold);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Color4::operator==(const Color4& rhs) const
|
||||||
|
{
|
||||||
|
return r == rhs.r
|
||||||
|
&& g == rhs.g
|
||||||
|
&& b == rhs.b
|
||||||
|
&& a == rhs.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Color4::operator!=(const Color4& rhs) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Color4::ToEscapeCode(bool bg) const {
|
||||||
|
if (bg)
|
||||||
|
return std::format("\033[48;2;{};{};{}m", r, g, b);
|
||||||
|
|
||||||
|
return std::format("\033[38;2;{};{};{}m", r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string decimal_to_hex(int dec, int digits = 0)
|
||||||
|
{
|
||||||
|
if (dec < 1) return std::string(digits, '0');
|
||||||
|
|
||||||
|
int hex = dec;
|
||||||
|
std::string hexStr = "";
|
||||||
|
while (dec > 0)
|
||||||
|
{
|
||||||
|
hex = dec % 16;
|
||||||
|
|
||||||
|
if (hex < 10)
|
||||||
|
hexStr = hexStr.insert(0, std::string(1, (hex + 48)));
|
||||||
|
else
|
||||||
|
hexStr = hexStr.insert(0, std::string(1, (hex + 55)));
|
||||||
|
|
||||||
|
dec /= 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (digits > 0)
|
||||||
|
{
|
||||||
|
while (hexStr.length() < digits)
|
||||||
|
{
|
||||||
|
hexStr = "0" + hexStr;
|
||||||
|
digits--;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return hexStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string Color4::ToHex() const {
|
||||||
|
std::string rs = decimal_to_hex(r, 2);
|
||||||
|
std::string gs = decimal_to_hex(g, 2);
|
||||||
|
std::string bs = decimal_to_hex(b, 2);
|
||||||
|
return "#" + rs + gs + bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Color4::ToHexAlpha() const {
|
||||||
|
std::string rs = decimal_to_hex(r, 2);
|
||||||
|
std::string gs = decimal_to_hex(g, 2);
|
||||||
|
std::string bs = decimal_to_hex(b, 2);
|
||||||
|
std::string as = decimal_to_hex(a, 2);
|
||||||
|
return "#" + rs + gs + bs + as;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color4 Color4::FromHSV(float hue, float saturation, float value, float alpha) {
|
||||||
|
float hh, p, q, t, ff;
|
||||||
|
long i;
|
||||||
|
float rn, gn, bn;
|
||||||
|
|
||||||
|
if (saturation <= 0.0) { // < is bogus, just shuts up warnings.
|
||||||
|
rn = value;
|
||||||
|
bn = value;
|
||||||
|
gn = value;
|
||||||
|
return Color4(RGBAf{rn, bn, gn, alpha});
|
||||||
|
}
|
||||||
|
|
||||||
|
hh = hue;
|
||||||
|
if (hh >= 360.f) hh = 0;
|
||||||
|
hh /= 60.f;
|
||||||
|
i = (long)hh;
|
||||||
|
ff = hh - i;
|
||||||
|
p = value * (1.f - saturation);
|
||||||
|
q = value * (1.f - (saturation * ff));
|
||||||
|
t = value * (1.f - (saturation * (1.f - ff)));
|
||||||
|
|
||||||
|
switch(i) {
|
||||||
|
case 0:
|
||||||
|
rn = value;
|
||||||
|
gn = t;
|
||||||
|
bn = p;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
rn = q;
|
||||||
|
gn = value;
|
||||||
|
bn = p;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
rn = p;
|
||||||
|
gn = value;
|
||||||
|
bn = t;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
rn = p;
|
||||||
|
gn = q;
|
||||||
|
bn = value;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
rn = t;
|
||||||
|
gn = p;
|
||||||
|
bn = value;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
default:
|
||||||
|
rn = value;
|
||||||
|
gn = p;
|
||||||
|
bn = q;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Color4(RGBAf{rn, gn, bn, alpha});
|
||||||
|
}
|
||||||
|
|
||||||
|
Color4 Color4::FromHSV(const HSV &hsv, float alpha) {
|
||||||
|
return FromHSV(hsv.h, hsv.s, hsv.v, alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color4::Color4(const HSVA &hsva) : Color4(HSV{hsva.h,hsva.s,hsva.v}, hsva.a) {}
|
||||||
|
@@ -26,7 +26,7 @@ namespace mcolor
|
|||||||
return std::format("\033[{}m", static_cast<typename std::underlying_type<AnsiColor>::type>(c));
|
return std::format("\033[{}m", static_cast<typename std::underlying_type<AnsiColor>::type>(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
/*
|
/*
|
||||||
* Beat Windows into submission and make it interpret ansi codes.
|
* Beat Windows into submission and make it interpret ansi codes.
|
||||||
* Fuck you Microsoft we're doing this the right way.
|
* Fuck you Microsoft we're doing this the right way.
|
||||||
@@ -37,6 +37,7 @@ namespace mcolor
|
|||||||
* along with any code that is printing the escape codes to a terminal.
|
* along with any code that is printing the escape codes to a terminal.
|
||||||
*/
|
*/
|
||||||
void windowsSaneify() {
|
void windowsSaneify() {
|
||||||
|
#ifdef WIN32
|
||||||
HANDLE handleOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE handleOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
DWORD consoleMode;
|
DWORD consoleMode;
|
||||||
GetConsoleMode( handleOut, &consoleMode);
|
GetConsoleMode( handleOut, &consoleMode);
|
||||||
@@ -44,11 +45,11 @@ namespace mcolor
|
|||||||
consoleMode |= DISABLE_NEWLINE_AUTO_RETURN;
|
consoleMode |= DISABLE_NEWLINE_AUTO_RETURN;
|
||||||
SetConsoleMode( handleOut , consoleMode );
|
SetConsoleMode( handleOut , consoleMode );
|
||||||
SetConsoleOutputCP(CP_UTF8);
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void printAnsiColorTable()
|
|
||||||
{
|
void printAnsiColorTable() {
|
||||||
std::vector<AnsiColor> ansifg = {
|
std::vector<AnsiColor> ansifg = {
|
||||||
AnsiColor::FG_BLACK,
|
AnsiColor::FG_BLACK,
|
||||||
AnsiColor::FG_RED,
|
AnsiColor::FG_RED,
|
||||||
|
Reference in New Issue
Block a user