Compare commits
27 Commits
Prerelease
...
master
Author | SHA1 | Date | |
---|---|---|---|
6a8938305e | |||
42e773b5a1 | |||
25d804ce79 | |||
954b8cb4b5 | |||
cc4773abba | |||
ce624106f9 | |||
36e180b6c0 | |||
18289d321c | |||
d8d6ad5edc | |||
2c52899c34 | |||
aeebf81a39 | |||
fe25751b07 | |||
40b8206443 | |||
8f49ba5e49 | |||
944e568ecf | |||
9602b24dd1 | |||
69177ff958 | |||
17227de37a | |||
8de16983fc | |||
37e489c2e0 | |||
ba3369b7f1 | |||
b89d908e8c | |||
c2692a27ae | |||
bb157ff855 | |||
6fe4f9b38d | |||
6ca7141f44 | |||
3004690fe0 |
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
|
||||
|
||||
}
|
||||
}
|
@@ -8,19 +8,20 @@ using u8 = uint8_t;
|
||||
/// Represents a 3-channel color value, with Red, Green and Blue components.
|
||||
class Color3 {
|
||||
public:
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 r; // Red value 0-255
|
||||
u8 g; // Green value 0-255
|
||||
u8 b; // Blue value 0-255
|
||||
public:
|
||||
/// Explicitly constructs a Color3 from the given Red, Green, and Blue values.
|
||||
Color3(u8 R, u8 G, u8 B);
|
||||
/// Returns a Color3 parsed from the given hexadecimal string.
|
||||
static Color3 FromHex(const std::string& hexCode);
|
||||
static Color3 FromHSL(u8 hue, u8 saturation, u8 lightness);
|
||||
|
||||
Color3() = default;
|
||||
public:
|
||||
/// Returns a Color3 that is somewhere in-between this and the given Color3, determined by the alpha [0-1].
|
||||
Color3 Lerp(const Color3& rhs, float alpha) const;
|
||||
Color3 Lerp(const Color3& rhs, float t) const;
|
||||
|
||||
/// Returns the red channel [0-255].
|
||||
u8 RedChannel () const;
|
||||
@@ -35,4 +36,7 @@ public:
|
||||
/// Returns the blue channel normalized from [0-255] to [0-1].
|
||||
float BlueChannelNormalized() const;
|
||||
|
||||
u8* ptr();
|
||||
[[nodiscard]] const u8* ptr() const;
|
||||
|
||||
};
|
@@ -4,42 +4,153 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
|
||||
#include <Color3.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include "ColorFormats.hpp"
|
||||
|
||||
using u8 = uint8_t;
|
||||
|
||||
class Color4;
|
||||
|
||||
class Color4 {
|
||||
std::string toEscapeCode(Color4 c, bool bg=false);
|
||||
|
||||
namespace mcolor
|
||||
{
|
||||
void printBuiltinColorList();
|
||||
}
|
||||
|
||||
|
||||
/// A type representing a color with alpha.
|
||||
/// Our default format is RGBA with 8 bits-per-channel.
|
||||
/// Conversions to other color formats are provided.
|
||||
class Color4
|
||||
{
|
||||
public:
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 a;
|
||||
public:
|
||||
|
||||
/// The default constructor does not initialize any members.
|
||||
Color4() = default;
|
||||
|
||||
/// Constructs a new Color4 from a Color3 and an optional alpha value.
|
||||
explicit Color4(const Color3& color3, u8 alpha = 255);
|
||||
|
||||
/// Constructs a new Color4 from red, green, blue channel values, and an optional alpha value.
|
||||
Color4(u8 red, u8 green, u8 blue, u8 alpha = 255);
|
||||
|
||||
/// Constructs a new Color4 from an RGB structure and an optional alpha value.
|
||||
explicit Color4(const RGB& rgb, u8 alpha = 255);
|
||||
|
||||
/// Constructs a new Color4 from an RGBA structure.
|
||||
explicit Color4(const RGBA& rgba);
|
||||
|
||||
/// Constructs a new Color4 from a floating-point RGB structure and an optional alpha value.
|
||||
/// @note: Normalizes the color values from ranges [0, 1] to [0, 255].
|
||||
explicit Color4(const RGBf& rgb, float alpha = 1.0f);
|
||||
|
||||
/// Constructs a new Color4 from a floating-point RGBA structure.
|
||||
/// /// @note: Normalizes the color values from ranges [0, 1] to [0, 255].
|
||||
explicit Color4(const RGBAf& rgba);
|
||||
|
||||
/// Constructs a new Color4 from an HSV structure.
|
||||
explicit Color4(const HSV& hsv, float alpha = 1.f);
|
||||
|
||||
/// Constructs a new Color4 from an HSVA structure.
|
||||
explicit Color4(const HSVA& hsva);
|
||||
|
||||
/// TODO: HSL to RGB constructor
|
||||
explicit Color4(const HSL& hsl, float alpha = 1.f);
|
||||
// TODO: LCH to RGB constructor
|
||||
explicit Color4(const LCH& lch, float alpha = 1.f);
|
||||
// TODO: LCHA to RGB constructor
|
||||
explicit Color4(const LCHA& lcha);
|
||||
|
||||
|
||||
static Color4 FromColor3(const Color3& color3, u8 alpha = 255);
|
||||
static Color4 FromHex(const std::string& hexCode, u8 alpha = 255);
|
||||
|
||||
static Color4 FromHexA(const std::string& hexACode);
|
||||
|
||||
static Color4 FromHSV(const HSV& hsv, float alpha = 1.f);
|
||||
|
||||
/// @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 FromNormalized(float red, float green, float blue, float alpha = 1.f);
|
||||
static Color4 FromLCH(float l, float c, float h, float alpha = 1.f);
|
||||
public:
|
||||
u8 RedChannel() const;
|
||||
u8 GreenChannel() const;
|
||||
u8 BlueChannel() const;
|
||||
u8 AlphaChannel() const;
|
||||
|
||||
float RedChannelNormalized() const;
|
||||
float GreenChannelNormalized() const;
|
||||
float BlueChannelNormalized() const;
|
||||
float AlphaChannelNormalized() const;
|
||||
/// Performs the interpolation in normalized color space (0-1) and converts it back.
|
||||
[[nodiscard]] Color4 Lerp(const Color4& rhs, float t) const;
|
||||
static Color4 Lerp(const Color4& lhs, const Color4& rhs, float t);
|
||||
|
||||
[[nodiscard]] float RN() const { return RedChannelNormalized(); }
|
||||
[[nodiscard]] float GN() const { return GreenChannelNormalized(); }
|
||||
[[nodiscard]] float BN() const { return BlueChannelNormalized(); }
|
||||
/// Alternative to Lerp which does not normalize color channels before and after interpolation.
|
||||
[[nodiscard]] Color4 Lerp2(const Color4& rhs, float t) const;
|
||||
/// Alternative to Lerp which does not normalize color channels before and after interpolation.
|
||||
static Color4 Lerp2(const Color4& lhs, const Color4& rhs, float t);
|
||||
|
||||
[[nodiscard]] Color4 LerpByHSVA(const Color4& rhs, float t) const;
|
||||
|
||||
[[nodiscard]] std::string ToHex() const;
|
||||
[[nodiscard]] std::string ToHexAlpha() const;
|
||||
|
||||
[[nodiscard]] u8 RedChannel() const;
|
||||
[[nodiscard]] u8 GreenChannel() const;
|
||||
[[nodiscard]] u8 BlueChannel() const;
|
||||
[[nodiscard]] u8 AlphaChannel() const;
|
||||
|
||||
[[nodiscard]] u8 R() const;
|
||||
[[nodiscard]] u8 G() const;
|
||||
[[nodiscard]] u8 B() const;
|
||||
[[nodiscard]] u8 A() const;
|
||||
|
||||
[[nodiscard]] float RedChannelNormalized() const;
|
||||
[[nodiscard]] float GreenChannelNormalized() const;
|
||||
[[nodiscard]] float BlueChannelNormalized() const;
|
||||
[[nodiscard]] float AlphaChannelNormalized() const;
|
||||
|
||||
[[nodiscard]] float RN() const;
|
||||
[[nodiscard]] float GN() const;
|
||||
[[nodiscard]] float BN() const;
|
||||
[[nodiscard]] float AN() const;
|
||||
|
||||
u8* ptr();
|
||||
[[nodiscard]] const u8* ptr() const;
|
||||
|
||||
[[nodiscard]] HSV ToHSV() const;
|
||||
|
||||
[[nodiscard]] HSVA ToHSVA() const;
|
||||
|
||||
HSL ToHSL() const;
|
||||
HSLA ToHSLA() const;
|
||||
|
||||
// TODO: Color4 ToLCH
|
||||
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;
|
||||
|
||||
|
||||
int* ptr() { return reinterpret_cast<int *>(&r);}
|
||||
[[nodiscard]] const int* ptr() const { return reinterpret_cast<const int *>(&r);}
|
||||
};
|
||||
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;
|
||||
}
|
78
include/ColorFormats.hpp
Normal file
78
include/ColorFormats.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
using u8 = uint8_t;
|
||||
|
||||
/// A structure representing color in Red, Green, Blue format, 8 bits-per-color, or 24-bit, or True-color.
|
||||
struct RGB {
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
};
|
||||
|
||||
struct RGBA {
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 a;
|
||||
};
|
||||
|
||||
struct RGBf {
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
};
|
||||
|
||||
struct RGBAf {
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
|
||||
/// A structure representing color in Hue, Chroma, Value format.
|
||||
struct HSV {
|
||||
float h;
|
||||
float s;
|
||||
float v;
|
||||
};
|
||||
|
||||
struct HSVA {
|
||||
float h;
|
||||
float s;
|
||||
float v;
|
||||
float a;
|
||||
};
|
||||
|
||||
struct HSL {
|
||||
float h;
|
||||
float s;
|
||||
float l;
|
||||
};
|
||||
|
||||
struct HSLA {
|
||||
float h;
|
||||
float s;
|
||||
float l;
|
||||
float a;
|
||||
};
|
||||
|
||||
/// A structure representing a Lum, Chroma, Lightness value.
|
||||
struct LCH {
|
||||
float l;
|
||||
float h;
|
||||
float c;
|
||||
};
|
||||
|
||||
struct LCHA {
|
||||
float l;
|
||||
float h;
|
||||
float c;
|
||||
float a;
|
||||
};
|
||||
|
||||
struct CMYK {
|
||||
float c;
|
||||
float m;
|
||||
float y;
|
||||
float k;
|
||||
};
|
@@ -2,173 +2,178 @@
|
||||
|
||||
#include <Color4.hpp>
|
||||
|
||||
#define COLOR static const Color4
|
||||
|
||||
namespace Colors {
|
||||
|
||||
COLOR Transparent = Color4(0,0,0,0);
|
||||
namespace Primary {
|
||||
static const Color4 Red{255, 0, 0};
|
||||
static const Color4 Green{0, 255, 0};
|
||||
static const Color4 Blue{0, 0, 255};
|
||||
static const Color4 White{255, 255, 255};
|
||||
static const Color4 Black{0, 0, 0};
|
||||
static const Color4 Gray{128, 128, 128};
|
||||
static const Color4 DarkGray{192, 192, 192};
|
||||
static const Color4 LightGray{64, 64, 64};
|
||||
static const Color4 Yellow{255, 255, 0};
|
||||
COLOR Red{255, 0, 0};
|
||||
COLOR Green{0, 255, 0};
|
||||
COLOR Blue{0, 0, 255};
|
||||
COLOR White{255, 255, 255};
|
||||
COLOR Black{0, 0, 0};
|
||||
COLOR Gray{128, 128, 128};
|
||||
COLOR DarkGray{64, 64, 64};
|
||||
COLOR LightGray{192, 192, 192};
|
||||
COLOR Yellow{255, 255, 0};
|
||||
}
|
||||
using namespace Primary;
|
||||
namespace Reds {
|
||||
static const Color4 Fuchsia {255, 0, 255};
|
||||
static const Color4 LightSalmon{255, 160, 122};
|
||||
static const Color4 Salmon{250, 128, 114};
|
||||
static const Color4 DarkSalmon{233, 150, 122};
|
||||
static const Color4 LightCoral{240, 128, 128};
|
||||
static const Color4 IndianRed{205, 92, 92};
|
||||
static const Color4 Crimson{220, 20, 60};
|
||||
static const Color4 Firebrick{178, 34, 34};
|
||||
static const Color4 DarkRed{139, 0, 0};
|
||||
COLOR Fuchsia {255, 0, 255};
|
||||
COLOR LightSalmon{255, 160, 122};
|
||||
COLOR Salmon{250, 128, 114};
|
||||
COLOR DarkSalmon{233, 150, 122};
|
||||
COLOR LightCoral{240, 128, 128};
|
||||
COLOR IndianRed{205, 92, 92};
|
||||
COLOR Crimson{220, 20, 60};
|
||||
COLOR Firebrick{178, 34, 34};
|
||||
COLOR DarkRed{139, 0, 0};
|
||||
}
|
||||
namespace Oranges {
|
||||
static const Color4 Coral{255, 127, 80};
|
||||
static const Color4 Tomato{255, 99, 71};
|
||||
static const Color4 OrangeRed{255, 69, 0};
|
||||
static const Color4 Gold{255, 215, 0};
|
||||
static const Color4 Orange{255, 165, 0};
|
||||
static const Color4 DarkOrange{255, 140, 0};
|
||||
COLOR Coral{255, 127, 80};
|
||||
COLOR Tomato{255, 99, 71};
|
||||
COLOR OrangeRed{255, 69, 0};
|
||||
COLOR Gold{255, 215, 0};
|
||||
COLOR Orange{255, 165, 0};
|
||||
COLOR DarkOrange{255, 140, 0};
|
||||
}
|
||||
namespace Yellows {
|
||||
static const Color4 LightYellow{255, 255, 224};
|
||||
static const Color4 LemonChiffon{255, 250, 205};
|
||||
static const Color4 LightGoldenrodYellow{250, 250, 210};
|
||||
static const Color4 PapayaWhip{255, 239, 213};
|
||||
static const Color4 Moccasin{255, 228, 181};
|
||||
static const Color4 PeachPuff{255, 218, 185};
|
||||
static const Color4 PaleGoldenrod{238, 232, 170};
|
||||
static const Color4 Khaki{240, 230, 140};
|
||||
static const Color4 DarkKhaki{189, 183, 107};
|
||||
COLOR LightYellow{255, 255, 224};
|
||||
COLOR LemonChiffon{255, 250, 205};
|
||||
COLOR LightGoldenrodYellow{250, 250, 210};
|
||||
COLOR PapayaWhip{255, 239, 213};
|
||||
COLOR Moccasin{255, 228, 181};
|
||||
COLOR PeachPuff{255, 218, 185};
|
||||
COLOR PaleGoldenrod{238, 232, 170};
|
||||
COLOR Khaki{240, 230, 140};
|
||||
COLOR DarkKhaki{189, 183, 107};
|
||||
}
|
||||
namespace Greens {
|
||||
static const Color4 LawnGreen{124, 252, 0};
|
||||
static const Color4 Chartreuse{127, 255, 0};
|
||||
static const Color4 LimeGreen{50, 205, 50};
|
||||
static const Color4 ForestGreen{34, 139, 34};
|
||||
static const Color4 DarkGreen{0, 100, 0};
|
||||
static const Color4 GreenYellow{173, 255, 47};
|
||||
static const Color4 YellowGreen{154, 205, 50};
|
||||
static const Color4 SpringGreen{0, 255, 127};
|
||||
static const Color4 MediumSpringGreen{0, 250, 154};
|
||||
static const Color4 LightGreen{144, 238, 144};
|
||||
static const Color4 PaleGreen{152, 251, 152};
|
||||
static const Color4 DarkSeaGreen{143, 188, 143};
|
||||
static const Color4 MediumSeaGreen{60, 179, 113};
|
||||
static const Color4 SeaGreen{46, 139, 87};
|
||||
static const Color4 DarkOliveGreen{85, 107, 47};
|
||||
static const Color4 OliveDrab{107, 142, 35};
|
||||
static const Color4 Lime{0, 255, 0};
|
||||
static const Color4 Olive{128, 128, 0};
|
||||
COLOR LawnGreen{124, 252, 0};
|
||||
COLOR Chartreuse{127, 255, 0};
|
||||
COLOR LimeGreen{50, 205, 50};
|
||||
COLOR ForestGreen{34, 139, 34};
|
||||
COLOR DarkGreen{0, 100, 0};
|
||||
COLOR GreenYellow{173, 255, 47};
|
||||
COLOR YellowGreen{154, 205, 50};
|
||||
COLOR SpringGreen{0, 255, 127};
|
||||
COLOR MediumSpringGreen{0, 250, 154};
|
||||
COLOR LightGreen{144, 238, 144};
|
||||
COLOR PaleGreen{152, 251, 152};
|
||||
COLOR DarkSeaGreen{143, 188, 143};
|
||||
COLOR MediumSeaGreen{60, 179, 113};
|
||||
COLOR SeaGreen{46, 139, 87};
|
||||
COLOR DarkOliveGreen{85, 107, 47};
|
||||
COLOR OliveDrab{107, 142, 35};
|
||||
COLOR Lime{0, 255, 0};
|
||||
COLOR Olive{128, 128, 0};
|
||||
}
|
||||
namespace Cyans {
|
||||
static const Color4 LightCyan{224, 255, 255};
|
||||
static const Color4 Cyan{0, 255, 255};
|
||||
static const Color4 Aqua{0, 255, 255};
|
||||
static const Color4 Aquamarine{127, 255, 212};
|
||||
static const Color4 MediumAquamarine{102, 205, 170};
|
||||
static const Color4 PaleTurquoise{175, 238, 238};
|
||||
static const Color4 Turquoise{64, 224, 208};
|
||||
static const Color4 MediumTurquoise{72, 209, 204};
|
||||
static const Color4 DarkTurquoise{0, 206, 209};
|
||||
static const Color4 LightSeaGreen{32, 178, 170};
|
||||
static const Color4 CadetBlue{95, 158, 160};
|
||||
static const Color4 DarkCyan{0, 139, 139};
|
||||
static const Color4 Teal{0, 128, 128};
|
||||
COLOR LightCyan{224, 255, 255};
|
||||
COLOR Cyan{0, 255, 255};
|
||||
COLOR Aqua{0, 255, 255};
|
||||
COLOR Aquamarine{127, 255, 212};
|
||||
COLOR MediumAquamarine{102, 205, 170};
|
||||
COLOR PaleTurquoise{175, 238, 238};
|
||||
COLOR Turquoise{64, 224, 208};
|
||||
COLOR MediumTurquoise{72, 209, 204};
|
||||
COLOR DarkTurquoise{0, 206, 209};
|
||||
COLOR LightSeaGreen{32, 178, 170};
|
||||
COLOR CadetBlue{95, 158, 160};
|
||||
COLOR DarkCyan{0, 139, 139};
|
||||
COLOR Teal{0, 128, 128};
|
||||
}
|
||||
namespace Blues {
|
||||
static const Color4 PowderBlue{176, 224, 230};
|
||||
static const Color4 LightBlue{173, 216, 230};
|
||||
static const Color4 LightSkyBlue{135, 206, 250};
|
||||
static const Color4 SkyBlue{135, 206, 235};
|
||||
static const Color4 DeepSkyBlue{0, 191, 255};
|
||||
static const Color4 LightSteelBlue{176, 196, 222};
|
||||
static const Color4 DodgerBlue{30, 144, 255};
|
||||
static const Color4 CornflowerBlue{100, 149, 237};
|
||||
static const Color4 SteelBlue{70, 130, 180};
|
||||
static const Color4 RoyalBlue{65, 105, 225};
|
||||
static const Color4 MediumBlue{0, 0, 205};
|
||||
static const Color4 DarkBlue{0, 0, 139};
|
||||
static const Color4 Navy{0, 0, 128};
|
||||
static const Color4 MidnightBlue{25, 25, 112};
|
||||
static const Color4 MediumSlateBlue{123, 104, 238};
|
||||
static const Color4 SlateBlue{106, 90, 205};
|
||||
static const Color4 DarkSlateBlue{72, 61, 139};
|
||||
COLOR PowderBlue{176, 224, 230};
|
||||
COLOR LightBlue{173, 216, 230};
|
||||
COLOR LightSkyBlue{135, 206, 250};
|
||||
COLOR SkyBlue{135, 206, 235};
|
||||
COLOR DeepSkyBlue{0, 191, 255};
|
||||
COLOR LightSteelBlue{176, 196, 222};
|
||||
COLOR DodgerBlue{30, 144, 255};
|
||||
COLOR CornflowerBlue{100, 149, 237};
|
||||
COLOR SteelBlue{70, 130, 180};
|
||||
COLOR RoyalBlue{65, 105, 225};
|
||||
COLOR MediumBlue{0, 0, 205};
|
||||
COLOR DarkBlue{0, 0, 139};
|
||||
COLOR Navy{0, 0, 128};
|
||||
COLOR MidnightBlue{25, 25, 112};
|
||||
COLOR MediumSlateBlue{123, 104, 238};
|
||||
COLOR SlateBlue{106, 90, 205};
|
||||
COLOR DarkSlateBlue{72, 61, 139};
|
||||
}
|
||||
|
||||
|
||||
namespace Purples {
|
||||
static const Color4 Lavender{230, 230, 250};
|
||||
static const Color4 Thistle{216, 191, 216};
|
||||
static const Color4 Plum{221, 160, 221};
|
||||
static const Color4 Violet{238, 160, 221};
|
||||
static const Color4 Orchid{218, 112, 214};
|
||||
static const Color4 Fuchsia{255, 0, 255};
|
||||
static const Color4 Magenta{255, 0, 255};
|
||||
static const Color4 MediumOrchid{186, 85, 211};
|
||||
static const Color4 MediumPurple{147, 112, 219};
|
||||
static const Color4 BlueViolet{138, 43, 226};
|
||||
static const Color4 DarkViolet{148, 0, 211};
|
||||
static const Color4 DarkOrchid{153, 50, 204};
|
||||
static const Color4 DarkMagenta{139, 0, 128};
|
||||
static const Color4 Purple{128, 0, 128};
|
||||
static const Color4 Indigo{75, 0, 130};
|
||||
COLOR Lavender{230, 230, 250};
|
||||
COLOR Thistle{216, 191, 216};
|
||||
COLOR Plum{221, 160, 221};
|
||||
COLOR Violet{238, 160, 221};
|
||||
COLOR Orchid{218, 112, 214};
|
||||
COLOR Fuchsia{255, 0, 255};
|
||||
COLOR Magenta{255, 0, 255};
|
||||
COLOR MediumOrchid{186, 85, 211};
|
||||
COLOR MediumPurple{147, 112, 219};
|
||||
COLOR BlueViolet{138, 43, 226};
|
||||
COLOR DarkViolet{148, 0, 211};
|
||||
COLOR DarkOrchid{153, 50, 204};
|
||||
COLOR DarkMagenta{139, 0, 128};
|
||||
COLOR Purple{128, 0, 128};
|
||||
COLOR Indigo{75, 0, 130};
|
||||
}
|
||||
namespace Pinks {
|
||||
static const Color4 Pink{255, 129, 203};
|
||||
static const Color4 LightPink{255, 182, 193};
|
||||
static const Color4 HotPink{255, 105, 180};
|
||||
static const Color4 DeepPink{255, 20, 147};
|
||||
static const Color4 PaleVioletRed{219, 112, 147};
|
||||
static const Color4 MediumVioletRed{199, 21, 133};
|
||||
COLOR Pink{255, 129, 203};
|
||||
COLOR LightPink{255, 182, 193};
|
||||
COLOR HotPink{255, 105, 180};
|
||||
COLOR DeepPink{255, 20, 147};
|
||||
COLOR PaleVioletRed{219, 112, 147};
|
||||
COLOR MediumVioletRed{199, 21, 133};
|
||||
}
|
||||
namespace Whites {
|
||||
static const Color4 Snow{255, 250, 250};
|
||||
static const Color4 Honeydew{240, 255, 240};
|
||||
static const Color4 MintCream{245, 255, 250};
|
||||
static const Color4 Azure{240, 255, 255};
|
||||
static const Color4 AliceBlue{240, 248, 255};
|
||||
static const Color4 GhostWhite{248, 248, 255};
|
||||
static const Color4 WhiteSmoke{245, 245, 245};
|
||||
static const Color4 SeaShell{255, 245, 238};
|
||||
static const Color4 Beige{245, 245, 220};
|
||||
static const Color4 OldLace{253, 245, 230};
|
||||
static const Color4 FloralWhite{255, 250, 240};
|
||||
static const Color4 Ivory{255, 255, 240};
|
||||
static const Color4 AntiqueWhite{250, 240, 215};
|
||||
static const Color4 Linen{250, 240, 230};
|
||||
static const Color4 LavenderBlush{255, 240, 245};
|
||||
static const Color4 MistyRose{255, 228, 255};
|
||||
COLOR Snow{255, 250, 250};
|
||||
COLOR Honeydew{240, 255, 240};
|
||||
COLOR MintCream{245, 255, 250};
|
||||
COLOR Azure{240, 255, 255};
|
||||
COLOR AliceBlue{240, 248, 255};
|
||||
COLOR GhostWhite{248, 248, 255};
|
||||
COLOR WhiteSmoke{245, 245, 245};
|
||||
COLOR SeaShell{255, 245, 238};
|
||||
COLOR Beige{245, 245, 220};
|
||||
COLOR OldLace{253, 245, 230};
|
||||
COLOR FloralWhite{255, 250, 240};
|
||||
COLOR Ivory{255, 255, 240};
|
||||
COLOR AntiqueWhite{250, 240, 215};
|
||||
COLOR Linen{250, 240, 230};
|
||||
COLOR LavenderBlush{255, 240, 245};
|
||||
COLOR MistyRose{255, 228, 255};
|
||||
}
|
||||
namespace Grays {
|
||||
static const Color4 Gainsboro{220, 220, 220};
|
||||
static const Color4 LightGray{211, 211, 211};
|
||||
static const Color4 Silver{192, 192, 192};
|
||||
static const Color4 DimGray{105, 105, 105};
|
||||
static const Color4 LightSlateGray{119, 136, 153};
|
||||
static const Color4 SlateGray{112, 128, 144};
|
||||
static const Color4 DarkSlateGray{47, 79, 79};
|
||||
COLOR Gainsboro{220, 220, 220};
|
||||
COLOR LightGray{211, 211, 211};
|
||||
COLOR Silver{192, 192, 192};
|
||||
COLOR DimGray{105, 105, 105};
|
||||
COLOR LightSlateGray{119, 136, 153};
|
||||
COLOR SlateGray{112, 128, 144};
|
||||
COLOR DarkSlateGray{47, 79, 79};
|
||||
}
|
||||
namespace Browns {
|
||||
static const Color4 CornSilk{255, 248, 220};
|
||||
static const Color4 BlanchedAlmond{255, 235, 205};
|
||||
static const Color4 Bisque{255, 228, 196};
|
||||
static const Color4 NavajoWhite{255, 222, 173};
|
||||
static const Color4 Wheat{254, 222, 179};
|
||||
static const Color4 BurlyWood{222, 184, 135};
|
||||
static const Color4 Tan{210, 180, 140};
|
||||
static const Color4 RosyBrown{188, 143, 143};
|
||||
static const Color4 SandyBrown{244, 164, 96};
|
||||
static const Color4 GoldenRod{218, 165, 32};
|
||||
static const Color4 Peru{205, 133, 63};
|
||||
static const Color4 Chocolate{210, 105, 30};
|
||||
static const Color4 SaddleBrown{139, 69, 19};
|
||||
static const Color4 Sienna{160, 82, 45};
|
||||
static const Color4 Brown{164, 42, 42};
|
||||
static const Color4 Maroon{128, 0, 0};
|
||||
COLOR CornSilk{255, 248, 220};
|
||||
COLOR BlanchedAlmond{255, 235, 205};
|
||||
COLOR Bisque{255, 228, 196};
|
||||
COLOR NavajoWhite{255, 222, 173};
|
||||
COLOR Wheat{254, 222, 179};
|
||||
COLOR BurlyWood{222, 184, 135};
|
||||
COLOR Tan{210, 180, 140};
|
||||
COLOR RosyBrown{188, 143, 143};
|
||||
COLOR SandyBrown{244, 164, 96};
|
||||
COLOR GoldenRod{218, 165, 32};
|
||||
COLOR Peru{205, 133, 63};
|
||||
COLOR Chocolate{210, 105, 30};
|
||||
COLOR SaddleBrown{139, 69, 19};
|
||||
COLOR Sienna{160, 82, 45};
|
||||
COLOR Brown{164, 42, 42};
|
||||
COLOR Maroon{128, 0, 0};
|
||||
}
|
||||
|
||||
}
|
101
include/mcolor.h
101
include/mcolor.h
@@ -7,106 +7,35 @@
|
||||
#include <cstdint>
|
||||
#include <format>
|
||||
#include <vector>
|
||||
#include "Color3.hpp"
|
||||
#include "Color4.hpp"
|
||||
#include "Colors.hpp"
|
||||
#include "AnsiEscapeCodes.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::ansiColors
|
||||
{
|
||||
enum class Colors : 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 {
|
||||
std::string toEscapeCode(Color4 c, bool bg=false);
|
||||
|
||||
struct rgbColor
|
||||
{
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
std::string toEscapeCode(AnsiColor c);
|
||||
|
||||
namespace mcolor::rgbColors
|
||||
{
|
||||
// Basically default ugly standard UNIX colors for now
|
||||
static const rgbColor BLACK = {0,0,0};
|
||||
static const rgbColor RED = {170, 0, 0};
|
||||
static const rgbColor GREEN = {0, 170, 0};
|
||||
static const rgbColor YELLOW = {170, 170, 0};
|
||||
static const rgbColor BLUE = {0, 0, 170};
|
||||
static const rgbColor MAGENTA = {170, 0, 170};
|
||||
static const rgbColor CYAN = {0, 170, 170};
|
||||
static const rgbColor WHITE = {170, 170, 170};
|
||||
static const rgbColor DEFAULT = {170, 170, 170};
|
||||
|
||||
static const rgbColor BRIGHT_BLACK = {8,5, 85,};
|
||||
static const rgbColor BRIGHT_RED = {85, 85, 255};
|
||||
static const rgbColor BRIGHT_GREEN = {85, 255, 85};
|
||||
static const rgbColor BRIGHT_YELLOW = {85, 255, 255};
|
||||
static const rgbColor BRIGHT_BLUE = {255, 85, 85};
|
||||
static const rgbColor BRIGHT_MAGENTA = {255, 85, 255};
|
||||
static const rgbColor BRIGHT_CYAN = {255, 255, 85};
|
||||
static const rgbColor BRIGHT_WHITE = {255, 255, 255};
|
||||
}
|
||||
|
||||
namespace mcolor
|
||||
{
|
||||
std::string toEscapeCode(rgbColor c, bool bg=false);
|
||||
|
||||
std::string toEscapeCode(ansiColors::Colors 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();
|
||||
#endif
|
||||
|
||||
|
||||
void printAnsiColorTable();
|
||||
|
||||
std::vector<uint8_t> createRGBScale(uint8_t startValue = 200, uint8_t increment = 5);
|
||||
|
||||
std::vector<rgbColor> redScaler(rgbColor c);
|
||||
std::vector<Color4> redScaler(Color4 c);
|
||||
|
||||
std::vector<rgbColor> greenScaler(rgbColor c);
|
||||
std::vector<Color4> greenScaler(Color4 c);
|
||||
|
||||
std::vector<rgbColor> blueScaler(rgbColor c);
|
||||
std::vector<Color4> blueScaler(Color4 c);
|
||||
|
||||
std::vector<rgbColor> RGBColorScale(rgbColor startingColor, std::vector<rgbColor> (*scaler)(rgbColor));
|
||||
std::vector<Color4> RGBColorScale(Color4 startingColor, std::vector<Color4> (*scaler)(Color4));
|
||||
|
||||
void printRGBScale(std::vector<rgbColor> cs);
|
||||
void printRGBScale(std::vector<Color4> cs);
|
||||
|
||||
void printRGBConsoleTest();
|
||||
}
|
||||
|
34
main.cpp
34
main.cpp
@@ -2,15 +2,43 @@
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <mcolor.h>
|
||||
#include <Color4.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()
|
||||
{
|
||||
#ifdef WIN32
|
||||
mcolor::windowsSaneify();
|
||||
#endif
|
||||
mcolor::windowsSaneify();
|
||||
|
||||
|
||||
// TODO: Demo Color Space Math Operations
|
||||
|
||||
// TODO: Demo Color Representation Conversions
|
||||
|
||||
// TODO: Demo Color output in console.
|
||||
|
||||
mcolor::printBuiltinColorList();
|
||||
mcolor::printAnsiColorTable();
|
||||
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;
|
||||
}
|
||||
|
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);
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
#include <Color3.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
u8 Color3::RedChannel() const { return r; }
|
||||
|
||||
@@ -15,7 +16,17 @@ float Color3::GreenChannelNormalized() const { return static_cast<float>(g) / 25
|
||||
Color3::Color3(u8 R, u8 G, u8 B) : r(R), g(G), b(B) {}
|
||||
|
||||
Color3 Color3::FromHex(const std::string &hexCode) {
|
||||
u8 r, g, b;
|
||||
std::sscanf(hexCode.c_str(), "#%02x%02x%02x", &r, &g, &b);
|
||||
return {r, g, b};
|
||||
}
|
||||
// TODO: Support hex codes without the #
|
||||
// TODO: Support 9-character hex codes (with alpha), but raise a warning that suggests using Color4 instead.
|
||||
if (hexCode.length() == 7) {
|
||||
u8 r, g, b;
|
||||
std::sscanf(hexCode.c_str(), "#%02hhx%02hhx%02hhx", &r, &g, &b);
|
||||
return {r, g, b};
|
||||
}
|
||||
|
||||
throw std::invalid_argument("Invalid hex code");
|
||||
}
|
||||
|
||||
u8 *Color3::ptr() { return &r;}
|
||||
|
||||
const u8 *Color3::ptr() const { return &r;}
|
||||
|
457
src/Color4.cpp
457
src/Color4.cpp
@@ -1,11 +1,142 @@
|
||||
#include <Color4.hpp>
|
||||
#include <format>
|
||||
#include <ColorFormats.hpp>
|
||||
|
||||
Color4::Color4(u8 red, u8 green, u8 blue, u8 alpha) : r(red), g(green), b(blue), a(alpha) {}
|
||||
#if !defined(WIN32)
|
||||
// For some reason this causes crash with exit code: -1073741819 on winblows.
|
||||
std::vector<Color4> list;
|
||||
#endif
|
||||
|
||||
std::string toEscapeCode(Color4 c, bool bg){
|
||||
if (bg)
|
||||
return std::format("\033[48;2;{};{};{}m", c.r, c.g, c.b);
|
||||
|
||||
return std::format("\033[38;2;{};{};{}m", c.r, c.g, c.b);
|
||||
}
|
||||
|
||||
void mcolor::printBuiltinColorList() {
|
||||
#if !defined(WIN32)
|
||||
int i = 0;
|
||||
for (const Color4& color : list) {
|
||||
std::cout << toEscapeCode(color) << i << ": " << "Hello, world!" << std::endl;
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Color4::Color4(const RGB &rgb, u8 alpha): Color4(rgb.r, rgb.g, rgb.b, alpha) {}
|
||||
|
||||
Color4::Color4(const RGBA &rgba): Color4(rgba.r, rgba.g, rgba.b, rgba.a) {}
|
||||
|
||||
Color4::Color4(const RGBf &rgb, float alpha): Color4(rgb.r * 255, rgb.g * 255, rgb.b * 255, alpha * 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) {
|
||||
|
||||
float hue = hsv.h;
|
||||
float saturation = hsv.s;
|
||||
float value = hsv.v;
|
||||
|
||||
float hh, p, q, t, ff;
|
||||
long i;
|
||||
float rn, gn, bn;
|
||||
|
||||
if (saturation <= 0.0) { // < is bogus, just shuts up warnings.
|
||||
r = value*255;
|
||||
g = value*255;
|
||||
b = value*255;
|
||||
return;
|
||||
//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;
|
||||
}
|
||||
this->r = rn * 255;
|
||||
this->g = gn * 255;
|
||||
this->b = bn * 255;
|
||||
this->a = alpha * 255;
|
||||
//return Color4(RGBAf{rn, gn, bn, 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) {
|
||||
#if !defined(WIN32)
|
||||
list.push_back(*this);
|
||||
#endif
|
||||
}
|
||||
|
||||
Color4 Color4::FromColor3(const Color3 &color3, u8 alpha) {return Color4(color3, alpha);}
|
||||
|
||||
Color4 Color4::FromHex(const std::string &hexCode, u8 alpha) {
|
||||
// TODO: Support hex codes without the #
|
||||
// TODO: Support 9-character hex codes (with alpha), but raise a warning that suggests using FromHexA explicitly instead.
|
||||
if (hexCode.length() == 7) {
|
||||
u8 r, g, b;
|
||||
std::sscanf(hexCode.c_str(), "#%02hhx%02hhx%02hhx", &r, &g, &b);
|
||||
return {r, g, b, alpha};
|
||||
}
|
||||
|
||||
if (hexCode.length() == 9) {
|
||||
u8 r, g, b, a;
|
||||
std::sscanf(hexCode.c_str(), "#%02hhx%02hhx%02hhx%02hhx", &r, &g, &b, &a);
|
||||
return {r, g, b, a};
|
||||
}
|
||||
|
||||
throw std::invalid_argument("Invalid hex code");
|
||||
}
|
||||
|
||||
Color4 Color4::FromHexA(const std::string &hexACode) {
|
||||
if (hexACode.length() == 9) {
|
||||
u8 r, g, b, a;
|
||||
std::sscanf(hexACode.c_str(), "#%02hhx%02hhx%02hhx%02hhx", &r, &g, &b, &a);
|
||||
return {r, g, b, a};
|
||||
}
|
||||
|
||||
throw std::invalid_argument("Invalid hex code");
|
||||
}
|
||||
|
||||
u8 Color4::RedChannel() const { return r;}
|
||||
|
||||
u8 Color4::GreenChannel() const { return g;}
|
||||
@@ -14,6 +145,14 @@ u8 Color4::BlueChannel() const {return b;}
|
||||
|
||||
u8 Color4::AlphaChannel() const {return a;}
|
||||
|
||||
u8 Color4::R() const { return AlphaChannel(); }
|
||||
|
||||
u8 Color4::G() const { return GreenChannel(); }
|
||||
|
||||
u8 Color4::B() const { return BlueChannel(); }
|
||||
|
||||
u8 Color4::A() const { return AlphaChannel(); }
|
||||
|
||||
float Color4::RedChannelNormalized() const {return static_cast<float>(r/255.f); }
|
||||
|
||||
float Color4::GreenChannelNormalized() const {return static_cast<float>(g/255.f); }
|
||||
@@ -21,8 +160,314 @@ float Color4::GreenChannelNormalized() const {return static_cast<float>(g/255.f)
|
||||
float Color4::BlueChannelNormalized() const {return static_cast<float>(b/255.f); }
|
||||
|
||||
float Color4::AlphaChannelNormalized() const {return static_cast<float>(a/255.f); }
|
||||
Color4 Color4::FromHex(const std::string &hexCode, u8 alpha) {
|
||||
u8 r, g, b;
|
||||
std::sscanf(hexCode.c_str(), "#%02x%02x%02x", &r, &g, &b);
|
||||
return {r, g, b, alpha};
|
||||
}
|
||||
|
||||
float Color4::RN() const { return RedChannelNormalized(); }
|
||||
|
||||
float Color4::GN() const { return GreenChannelNormalized(); }
|
||||
|
||||
float Color4::BN() const { return BlueChannelNormalized(); }
|
||||
|
||||
float Color4::AN() const { return AlphaChannelNormalized(); }
|
||||
|
||||
|
||||
Color4 Color4::FromNormalized(float red, float green, float blue, float alpha) {
|
||||
return {
|
||||
static_cast<u8>(red * 255),
|
||||
static_cast<u8>(green * 255),
|
||||
static_cast<u8>(blue * 255),
|
||||
static_cast<u8>(alpha * 255)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Color4 Color4::Lerp(const Color4 &rhs, float t) const {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return FromNormalized(
|
||||
std::lerp(RN(), rhs.RN(), t),
|
||||
std::lerp(GN(), rhs.GN(), t),
|
||||
std::lerp(BN(), rhs.BN(), t),
|
||||
std::lerp(AN(), rhs.AN(), t)
|
||||
);
|
||||
}
|
||||
|
||||
Color4 Color4::Lerp2(const Color4& rhs, float t) const {
|
||||
return Color4(
|
||||
std::lerp(R(), rhs.R(), t),
|
||||
std::lerp(G(), rhs.G(), t),
|
||||
std::lerp(B(), rhs.B(), t),
|
||||
std::lerp(A(), rhs.A(), t)
|
||||
);
|
||||
}
|
||||
|
||||
Color4 Color4::Lerp2(const Color4 &lhs, const Color4 &rhs, float t) {
|
||||
return lhs.Lerp2(rhs, t);
|
||||
}
|
||||
|
||||
Color4 Color4::LerpByHSVA(const Color4 &rhs, float t) const {
|
||||
HSVA a = this->ToHSVA();
|
||||
HSVA b = rhs.ToHSVA();
|
||||
|
||||
// Hue interpolation
|
||||
float h;
|
||||
float d = b.h - a.h;
|
||||
|
||||
if (a.h > b.h) {
|
||||
auto h3 = b.h; // b.h2?
|
||||
b.h = a.h;
|
||||
a.h = h3;
|
||||
|
||||
d = -d;
|
||||
t = 1 - t;
|
||||
}
|
||||
|
||||
if (d > 0.5f) { // 180 deg
|
||||
a.h = a.h + 1; // 360 deg
|
||||
h = std::fmod(a.h + t * (b.h - a.h), 1.f);
|
||||
}
|
||||
|
||||
if (d <= 0.5f) { // 180 deg
|
||||
h = a.h + t * d;
|
||||
}
|
||||
|
||||
return FromHSV(
|
||||
h,
|
||||
std::lerp(a.s, b.s, t),
|
||||
std::lerp(a.v, b.v, t),
|
||||
std::lerp(a.a, b.a, t));
|
||||
}
|
||||
|
||||
Color4 Color4::Lerp(const Color4 &lhs, const Color4 &rhs, float t) {
|
||||
return lhs.Lerp(rhs, t);
|
||||
}
|
||||
|
||||
u8 *Color4::ptr() { return (&r);}
|
||||
|
||||
const u8 *Color4::ptr() const { return (&r);}
|
||||
|
||||
HSV Color4::ToHSV() const {
|
||||
float rn = RN();
|
||||
float gn = GN();
|
||||
float bn = BN();
|
||||
auto Cmax = std::max(std::max(rn, gn), bn); // TODO: Replace with initializer list.
|
||||
auto Cmin = std::min(std::max(rn, gn), bn); // TODO: Replace with initializer list.
|
||||
|
||||
float delta = Cmax - Cmin;
|
||||
|
||||
float hue = 0.f;
|
||||
|
||||
if (Cmax == rn) hue = 60.f * std::fmod((gn - bn) / delta, 6.0);
|
||||
if (Cmax == gn) hue = 60.f * ((gn - rn) / delta) + 2;
|
||||
if (Cmax == bn) hue = 60.f * ((rn - gn)/ delta) + 4;
|
||||
|
||||
float saturation = 0.f;
|
||||
|
||||
if (Cmax == 0) saturation = 0.f;
|
||||
else saturation = delta / Cmax;
|
||||
|
||||
float value = Cmax;
|
||||
|
||||
return {hue, saturation, value};
|
||||
}
|
||||
|
||||
HSVA Color4::ToHSVA() const {
|
||||
auto hsv = ToHSV();
|
||||
return {hsv.h, hsv.s, hsv.v, AN()};
|
||||
}
|
||||
|
||||
HSL Color4::ToHSL() const
|
||||
{
|
||||
float rn = RN();
|
||||
float gn = GN();
|
||||
float bn = BN();
|
||||
|
||||
float max = std::max(std::max(rn, gn), bn);
|
||||
float min = std::min(std::min(rn, gn), bn);
|
||||
|
||||
float delta = max - min;
|
||||
|
||||
float L = (min + max) / 2.f;
|
||||
float S = 0;
|
||||
|
||||
if (max == min)
|
||||
S = 0;
|
||||
if (L > 0.5f)
|
||||
S = (delta) * (2.f - max - min);
|
||||
if (L <= 0.5f)
|
||||
S = (max - min) / (max + min);
|
||||
|
||||
float H = 0;
|
||||
|
||||
if (rn == max)
|
||||
H = (gn - bn) / (delta);
|
||||
if (gn == max)
|
||||
H = 2.f + (bn-rn) / (max-min);
|
||||
if (bn == max)
|
||||
H = 4.f + (rn-gn) / (max-min);
|
||||
|
||||
H *= 60;
|
||||
|
||||
if (H < 0.f)
|
||||
H += 360.f;
|
||||
|
||||
return {H,S,L};
|
||||
}
|
||||
|
||||
HSLA Color4::ToHSLA() const
|
||||
{
|
||||
HSL hsl = ToHSL();
|
||||
return {hsl.h, hsl.s, hsl.l, AN()};
|
||||
}
|
||||
|
||||
LCH Color4::ToLCH() const {
|
||||
// TODO: Implement
|
||||
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) {}
|
||||
|
123
src/mcolor.cpp
123
src/mcolor.cpp
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace mcolor
|
||||
{
|
||||
std::string toEscapeCode(rgbColor c, bool bg)
|
||||
std::string toEscapeCode(Color4 c, bool bg)
|
||||
{
|
||||
if (bg)
|
||||
return std::format("\033[48;2;{};{};{}m", c.r, c.g, c.b);
|
||||
@@ -20,13 +20,13 @@ namespace mcolor
|
||||
return std::format("\033[38;2;{};{};{}m", c.r, c.g, c.b);
|
||||
}
|
||||
|
||||
std::string toEscapeCode(ansiColors::Colors c)
|
||||
std::string toEscapeCode(AnsiColor c)
|
||||
{
|
||||
// Type casting is annoying just saying, but I want to be special about this for some reason
|
||||
return std::format("\033[{}m", static_cast<typename std::underlying_type<ansiColors::Colors>::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.
|
||||
* 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.
|
||||
*/
|
||||
void windowsSaneify() {
|
||||
#ifdef WIN32
|
||||
HANDLE handleOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD consoleMode;
|
||||
GetConsoleMode( handleOut, &consoleMode);
|
||||
@@ -44,56 +45,56 @@ namespace mcolor
|
||||
consoleMode |= DISABLE_NEWLINE_AUTO_RETURN;
|
||||
SetConsoleMode( handleOut , consoleMode );
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void printAnsiColorTable()
|
||||
{
|
||||
std::vector<mcolor::ansiColors::Colors> ansifg = {
|
||||
mcolor::ansiColors::Colors::FG_BLACK,
|
||||
mcolor::ansiColors::Colors::FG_RED,
|
||||
mcolor::ansiColors::Colors::FG_GREEN,
|
||||
mcolor::ansiColors::Colors::FG_YELLOW,
|
||||
mcolor::ansiColors::Colors::FG_BLUE,
|
||||
mcolor::ansiColors::Colors::FG_MAGENTA,
|
||||
mcolor::ansiColors::Colors::FG_CYAN,
|
||||
mcolor::ansiColors::Colors::FG_WHITE,
|
||||
|
||||
void printAnsiColorTable() {
|
||||
std::vector<AnsiColor> ansifg = {
|
||||
AnsiColor::FG_BLACK,
|
||||
AnsiColor::FG_RED,
|
||||
AnsiColor::FG_GREEN,
|
||||
AnsiColor::FG_YELLOW,
|
||||
AnsiColor::FG_BLUE,
|
||||
AnsiColor::FG_MAGENTA,
|
||||
AnsiColor::FG_CYAN,
|
||||
AnsiColor::FG_WHITE,
|
||||
};
|
||||
|
||||
std::vector<mcolor::ansiColors::Colors> ansibg = {
|
||||
mcolor::ansiColors::Colors::BG_BLACK,
|
||||
mcolor::ansiColors::Colors::BG_RED,
|
||||
mcolor::ansiColors::Colors::BG_GREEN,
|
||||
mcolor::ansiColors::Colors::BG_YELLOW,
|
||||
mcolor::ansiColors::Colors::BG_BLUE,
|
||||
mcolor::ansiColors::Colors::BG_MAGENTA,
|
||||
mcolor::ansiColors::Colors::BG_CYAN,
|
||||
mcolor::ansiColors::Colors::BG_WHITE,
|
||||
std::vector<AnsiColor> ansibg = {
|
||||
AnsiColor::BG_BLACK,
|
||||
AnsiColor::BG_RED,
|
||||
AnsiColor::BG_GREEN,
|
||||
AnsiColor::BG_YELLOW,
|
||||
AnsiColor::BG_BLUE,
|
||||
AnsiColor::BG_MAGENTA,
|
||||
AnsiColor::BG_CYAN,
|
||||
AnsiColor::BG_WHITE,
|
||||
};
|
||||
|
||||
std::vector<mcolor::ansiColors::Colors> ansifg_bright = {
|
||||
mcolor::ansiColors::Colors::FG_BRIGHT_BLACK,
|
||||
mcolor::ansiColors::Colors::FG_BRIGHT_RED,
|
||||
mcolor::ansiColors::Colors::FG_BRIGHT_GREEN,
|
||||
mcolor::ansiColors::Colors::FG_BRIGHT_YELLOW,
|
||||
mcolor::ansiColors::Colors::FG_BRIGHT_BLUE,
|
||||
mcolor::ansiColors::Colors::FG_BRIGHT_MAGENTA,
|
||||
mcolor::ansiColors::Colors::FG_BRIGHT_CYAN,
|
||||
mcolor::ansiColors::Colors::FG_BRIGHT_WHITE,
|
||||
std::vector<AnsiColor> ansifg_bright = {
|
||||
AnsiColor::FG_BRIGHT_BLACK,
|
||||
AnsiColor::FG_BRIGHT_RED,
|
||||
AnsiColor::FG_BRIGHT_GREEN,
|
||||
AnsiColor::FG_BRIGHT_YELLOW,
|
||||
AnsiColor::FG_BRIGHT_BLUE,
|
||||
AnsiColor::FG_BRIGHT_MAGENTA,
|
||||
AnsiColor::FG_BRIGHT_CYAN,
|
||||
AnsiColor::FG_BRIGHT_WHITE,
|
||||
};
|
||||
|
||||
std::vector<mcolor::ansiColors::Colors> ansibg_bright = {
|
||||
mcolor::ansiColors::Colors::BG_BRIGHT_BLACK,
|
||||
mcolor::ansiColors::Colors::BG_BRIGHT_RED,
|
||||
mcolor::ansiColors::Colors::BG_BRIGHT_GREEN,
|
||||
mcolor::ansiColors::Colors::BG_BRIGHT_YELLOW,
|
||||
mcolor::ansiColors::Colors::BG_BRIGHT_BLUE,
|
||||
mcolor::ansiColors::Colors::BG_BRIGHT_MAGENTA,
|
||||
mcolor::ansiColors::Colors::BG_BRIGHT_CYAN,
|
||||
mcolor::ansiColors::Colors::BG_BRIGHT_WHITE,
|
||||
std::vector<AnsiColor> ansibg_bright = {
|
||||
AnsiColor::BG_BRIGHT_BLACK,
|
||||
AnsiColor::BG_BRIGHT_RED,
|
||||
AnsiColor::BG_BRIGHT_GREEN,
|
||||
AnsiColor::BG_BRIGHT_YELLOW,
|
||||
AnsiColor::BG_BRIGHT_BLUE,
|
||||
AnsiColor::BG_BRIGHT_MAGENTA,
|
||||
AnsiColor::BG_BRIGHT_CYAN,
|
||||
AnsiColor::BG_BRIGHT_WHITE,
|
||||
};
|
||||
|
||||
std::vector<mcolor::ansiColors::Colors> all;
|
||||
std::vector<AnsiColor> all;
|
||||
all.insert(all.end(), ansifg.begin(), ansifg.end());
|
||||
all.insert(all.end(), ansibg.begin(), ansibg.end());
|
||||
all.insert(all.end(), ansifg_bright.begin(), ansifg_bright.end());
|
||||
@@ -101,8 +102,8 @@ namespace mcolor
|
||||
|
||||
for (const auto i : all)
|
||||
{
|
||||
auto n = static_cast<typename std::underlying_type<mcolor::ansiColors::Colors>::type>(i);
|
||||
std::cout << mcolor::toEscapeCode(i) << unsigned(n) << mcolor::toEscapeCode(mcolor::ansiColors::Colors::RESET);
|
||||
auto n = static_cast<typename std::underlying_type<AnsiColor>::type>(i);
|
||||
std::cout << mcolor::toEscapeCode(i) << unsigned(n) << mcolor::toEscapeCode(AnsiColor::RESET);
|
||||
|
||||
if (n == 37 || n == 47 || n == 97 || n == 107)
|
||||
std::cout << std::endl;
|
||||
@@ -119,48 +120,48 @@ namespace mcolor
|
||||
return scale;
|
||||
}
|
||||
|
||||
std::vector<rgbColor> redScaler(rgbColor c)
|
||||
std::vector<Color4> redScaler(Color4 c)
|
||||
{
|
||||
std::vector<rgbColor> scale;
|
||||
std::vector<Color4> scale;
|
||||
auto nscale = createRGBScale(c.r);
|
||||
for (auto const i : nscale)
|
||||
{
|
||||
scale.push_back(rgbColor(i, c.g, c.b));
|
||||
scale.push_back(Color4(i, c.g, c.b));
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
std::vector<rgbColor> greenScaler(rgbColor c)
|
||||
std::vector<Color4> greenScaler(Color4 c)
|
||||
{
|
||||
std::vector<rgbColor> scale;
|
||||
std::vector<Color4> scale;
|
||||
auto nscale = createRGBScale(c.g);
|
||||
for (auto const i : nscale)
|
||||
{
|
||||
scale.push_back(rgbColor(c.r, i, c.b));
|
||||
scale.push_back(Color4(c.r, i, c.b));
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
std::vector<rgbColor> blueScaler(rgbColor c)
|
||||
std::vector<Color4> blueScaler(Color4 c)
|
||||
{
|
||||
std::vector<rgbColor> scale;
|
||||
std::vector<Color4> scale;
|
||||
auto nscale = createRGBScale(c.b);
|
||||
for (auto const i : nscale)
|
||||
{
|
||||
scale.push_back(rgbColor(c.r, c.g, i));
|
||||
scale.push_back(Color4(c.r, c.g, i));
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
std::vector<rgbColor> RGBColorScale(rgbColor startingColor, std::vector<rgbColor> (*scaler)(rgbColor))
|
||||
std::vector<Color4> RGBColorScale(Color4 startingColor, std::vector<Color4> (*scaler)(Color4))
|
||||
{
|
||||
return scaler(startingColor);
|
||||
}
|
||||
|
||||
void printRGBScale(std::vector<rgbColor> cs)
|
||||
void printRGBScale(std::vector<Color4> cs)
|
||||
{
|
||||
for (auto i : cs) {
|
||||
std::cout << mcolor::toEscapeCode(i) << mcolor::toEscapeCode(i, true) << ":3" << mcolor::toEscapeCode(mcolor::ansiColors::Colors::RESET);
|
||||
std::cout << mcolor::toEscapeCode(i) << mcolor::toEscapeCode(i, true) << ":3" << mcolor::toEscapeCode(AnsiColor::RESET);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
@@ -179,9 +180,9 @@ namespace mcolor
|
||||
*/
|
||||
void printRGBConsoleTest()
|
||||
{
|
||||
auto redScale = RGBColorScale(rgbColor(), redScaler);
|
||||
auto greenScale = RGBColorScale(rgbColor(), greenScaler);
|
||||
auto blueScale = RGBColorScale(rgbColor(), blueScaler);
|
||||
auto redScale = RGBColorScale(Color4(), redScaler);
|
||||
auto greenScale = RGBColorScale(Color4(), greenScaler);
|
||||
auto blueScale = RGBColorScale(Color4(), blueScaler);
|
||||
|
||||
printRGBScale(redScale);
|
||||
printRGBScale(greenScale);
|
||||
|
Reference in New Issue
Block a user