29 a = arr.size() >= 4 ? arr[3] : 1.0f;
33 throw std::invalid_argument(
"Array must have at least 3 elements");
39 if (size >= 3 && arr !=
nullptr)
44 a = size >= 4 ? arr[3] : 1.0f;
48 throw std::invalid_argument(
"Array must have at least 3 elements");
68 return r == rhs.
r &&
g == rhs.
g &&
b == rhs.
b &&
a == rhs.
a;
82 r = lhs.
r + alpha * (rhs.
r - lhs.
r);
83 g = lhs.
g + alpha * (rhs.
g - lhs.
g);
84 b = lhs.
b + alpha * (rhs.
b - lhs.
b);
85 a = lhs.
a + alpha * (rhs.
a - lhs.
a);
91 const Color* source = src ? src :
this;
92 r = std::pow(source->
r, 2.2f);
93 g = std::pow(source->
g, 2.2f);
94 b = std::pow(source->
b, 2.2f);
101 const Color* source = src ? src :
this;
102 r = std::pow(source->
r, 1.0f / 2.2f);
103 g = std::pow(source->
g, 1.0f / 2.2f);
104 b = std::pow(source->
b, 1.0f / 2.2f);
119 if (hex.empty() || hex[0] !=
'#')
121 throw std::invalid_argument(
"Invalid hex color format");
124 std::string hexStr = hex.substr(1);
125 uint32_t i = std::stoul(hexStr,
nullptr, 16);
127 std::array<uint8_t, 4> bytes;
128 if (hexStr.length() > 6)
130 auto bytes32 = intToBytes32(i);
131 bytes[0] = bytes32[0];
132 bytes[1] = bytes32[1];
133 bytes[2] = bytes32[2];
134 bytes[3] = bytes32[3];
138 auto bytes24 = intToBytes24(i);
139 bytes[0] = bytes24[0];
140 bytes[1] = bytes24[1];
141 bytes[2] = bytes24[2];
145 set(bytes[0] / 255.0f, bytes[1] / 255.0f, bytes[2] / 255.0f, bytes[3] / 255.0f);
151 if (arr.size() > offset)
r = arr[offset];
152 if (arr.size() > offset + 1)
g = arr[offset + 1];
153 if (arr.size() > offset + 2)
b = arr[offset + 2];
154 if (arr.size() > offset + 3)
a = arr[offset + 3];
160 if (arr && size > offset)
r = arr[offset];
161 if (arr && size > offset + 1)
g = arr[offset + 1];
162 if (arr && size > offset + 2)
b = arr[offset + 2];
163 if (arr && size > offset + 3)
a = arr[offset + 3];
170 if (asArray ||
r > 1.0f ||
g > 1.0f ||
b > 1.0f)
172 std::ostringstream oss;
173 oss << std::fixed << std::setprecision(3);
174 oss <<
r <<
", " <<
g <<
", " <<
b <<
", " <<
a;
178 auto roundToByte = [](
float value) -> uint8_t
180 return static_cast<uint8_t
>(std::round(clamp(value, 0.0f, 1.0f) * 255.0f));
183 uint8_t rByte = roundToByte(
r);
184 uint8_t gByte = roundToByte(
g);
185 uint8_t bByte = roundToByte(
b);
187 std::ostringstream oss;
188 oss <<
"#" << std::hex << std::setfill(
'0');
189 oss << std::setw(2) << static_cast<int>(rByte);
190 oss << std::setw(2) << static_cast<int>(gByte);
191 oss << std::setw(2) << static_cast<int>(bByte);
195 uint8_t aByte = roundToByte(
a);
196 oss << std::setw(2) << static_cast<int>(aByte);
202 std::vector<float>
Color::toArray(std::vector<float> arr,
const size_t offset,
const bool alpha)
const
205 if (
const size_t requiredSize = offset + (alpha ? 4 : 3); arr.size() < requiredSize)
207 arr.resize(requiredSize);
227 if (
const size_t requiredSize = offset + (alpha ? 4 : 3); size < requiredSize)
251 std::array<uint8_t, 3> Color::intToBytes24(uint32_t i)
253 uint8_t
r = (i >> 16) & 0xFF;
254 uint8_t
g = (i >> 8) & 0xFF;
255 uint8_t
b = i & 0xFF;
259 std::array<uint8_t, 4> Color::intToBytes32(uint32_t i)
261 const uint8_t
r = (i >> 24) & 0xFF;
262 uint8_t
g = (i >> 16) & 0xFF;
263 uint8_t
b = (i >> 8) & 0xFF;
264 uint8_t
a = i & 0xFF;
268 float Color::clamp(
float value,
float min,
float max)
270 if (value >= max)
return max;
271 if (value <= min)
return min;
RGBA color with floating-point components in [0, 1].
Color(const float r=0.0f, const float g=0.0f, const float b=0.0f, const float a=1.0f)
Color & lerp(const Color &lhs, const Color &rhs, float alpha)
std::string toString(bool alpha=false, bool asArray=false) const
static const Color YELLOW
Color & mulScalar(float scalar)
static const Color MAGENTA
Color & copy(const Color &rhs)
bool operator!=(const Color &other) const
bool operator==(const Color &other) const
bool equals(const Color &rhs) const
Color & gamma(const Color *src=nullptr)
std::vector< float > toArray(std::vector< float > arr={}, size_t offset=0, bool alpha=true) const
Color & linear(const Color *src=nullptr)
Color & fromString(const std::string &hex)
Color & fromArray(const std::vector< float > &arr, size_t offset=0)
Color & set(float r, float g, float b, float a=1.0f)