polybar-dwm/include/components/x11/color.hpp
2016-10-10 14:52:57 +02:00

93 lines
1.8 KiB
C++

#pragma once
#include <iomanip>
#include "common.hpp"
#include "utils/string.hpp"
LEMONBUDDY_NS
union rgba {
struct {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
};
uint32_t v;
};
class color;
static map<string, color> g_colorstore;
class color {
public:
explicit color(string hex) : m_hex(string_util::upper(hex)) {
m_rgba.v = static_cast<uint32_t>(strtoul(&hex[1], nullptr, 16));
// premultiply alpha
m_rgba.r = m_rgba.r * m_rgba.a / 255;
m_rgba.g = m_rgba.g * m_rgba.a / 255;
m_rgba.b = m_rgba.b * m_rgba.a / 255;
}
explicit color(uint32_t v) {
char buffer[7];
snprintf(buffer, sizeof(buffer), "%06x", v);
m_hex = "#" + string{buffer};
m_rgba.v = v;
}
uint32_t value() const {
return m_rgba.v;
}
string rgb() const {
// clang-format off
return string_util::from_stream(stringstream()
<< "#"
<< std::setw(6)
<< std::setfill('0')
<< std::hex
<< std::uppercase
<< (m_rgba.v & 0x00FFFFFF));
// clang-format on
}
string hex() const {
return m_hex;
}
static auto parse(string input, color fallback) {
auto it = g_colorstore.find(input);
if (it != g_colorstore.end()) {
return it->second;
}
string hex{input};
if (hex.substr(0, 1) != "#")
hex = "#" + hex;
if (hex.length() == 4)
hex = {'#', hex[1], hex[1], hex[2], hex[2], hex[3], hex[3]};
if (hex.length() == 7)
hex = "#FF" + hex.substr(1);
if (hex.length() != 9)
return fallback;
color result{hex};
g_colorstore.emplace(input, result);
return result;
}
static auto parse(string input) {
static color none{0};
return parse(input, none);
}
protected:
rgba m_rgba;
string m_hex;
};
static color g_colorblack{"#ff000000"};
static color g_colorwhite{"#ffffffff"};
LEMONBUDDY_NS_END