aboutsummaryrefslogtreecommitdiff
path: root/src/platform/Color.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/Color.cpp')
-rw-r--r--src/platform/Color.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/platform/Color.cpp b/src/platform/Color.cpp
index b39865a8..dd1736ca 100644
--- a/src/platform/Color.cpp
+++ b/src/platform/Color.cpp
@@ -1,5 +1,7 @@
#include "cru/platform/Color.h"
+#include <algorithm>
+#include <cmath>
#include <cstdint>
#include <gsl/gsl>
#include <optional>
@@ -245,4 +247,82 @@ std::optional<Color> GetPredefinedColorByName(StringView name) {
return std::nullopt;
}
}
+
+HslColor::HslColor(const Color& color) {
+ float rgb[3] = {color.red / 255.f, color.green / 255.f, color.blue / 255.f};
+ float& r = rgb[0];
+ float& g = rgb[1];
+ float& b = rgb[2];
+
+ int max_index = 0;
+ int min_index = 0;
+
+ if (r > g) {
+ max_index = r > b ? 0 : 2;
+ min_index = g < b ? 1 : 2;
+ } else {
+ max_index = g > b ? 1 : 2;
+ min_index = r < b ? 0 : 2;
+ }
+
+ float max = rgb[max_index];
+ float min = rgb[min_index];
+
+ float delta = max - min;
+
+ if (delta == 0) {
+ h = 0.f;
+ } else if (max_index == 0) {
+ h = 60.f * std::fmod((g - b) / delta, 6.f);
+ } else if (max_index == 1) {
+ h = 60.f * ((b - r) / delta + 2.f);
+ } else {
+ h = 60.f * ((r - g) / delta + 4.f);
+ }
+
+ l = (max + min) / 2.f;
+
+ s = delta == 0 ? 0 : delta / (1 - std::abs(2 * l - 1));
+
+ a = color.alpha / 255.f;
+}
+
+HslColor::operator Color() const {
+ Expects(h >= 0.f && h <= 360.f);
+ Expects(s >= 0.f && s <= 1.f);
+ Expects(l >= 0.f && l <= 1.f);
+
+ float c = (1 - std::abs(2 * l - 1)) * s;
+ float x = c * (1 - std::abs(std::fmod(h / 60.f, 2.f) - 1));
+ float m = l - c / 2;
+
+ float rgb[3] = {0.f, 0.f, 0.f};
+
+ if (h >= 0.f && h < 60.f) {
+ rgb[0] = c;
+ rgb[1] = x;
+ } else if (h >= 60.f && h < 120.f) {
+ rgb[0] = x;
+ rgb[1] = c;
+ } else if (h >= 120.f && h < 180.f) {
+ rgb[1] = c;
+ rgb[2] = x;
+ } else if (h >= 180.f && h < 240.f) {
+ rgb[1] = x;
+ rgb[2] = c;
+ } else if (h >= 240.f && h < 300.f) {
+ rgb[0] = x;
+ rgb[2] = c;
+ } else if (h >= 300.f && h < 360.f) {
+ rgb[0] = c;
+ rgb[2] = x;
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ rgb[i] += m;
+ rgb[i] *= 255.f;
+ }
+
+ return Color(rgb[0] + 0.5f, rgb[1] + 0.5f, rgb[2] + 0.5f, a * 255.f + 0.5f);
+}
} // namespace cru::platform