From 168817476f85e8dbc04c06691a73a7d75c4858d5 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 10 Mar 2022 21:17:17 +0800 Subject: ... --- src/platform/Color.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'src/platform/Color.cpp') 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 +#include #include #include #include @@ -245,4 +247,82 @@ std::optional 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 -- cgit v1.2.3