mirror of https://github.com/polybar/polybar.git
feat(color_util): Utility functions for color handling
This commit is contained in:
parent
e62b545d1c
commit
26c308cc19
|
@ -0,0 +1,97 @@
|
|||
#pragma once
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
LEMONBUDDY_NS
|
||||
|
||||
namespace color_util {
|
||||
template <typename ChannelType = uint8_t, typename ValueType = uint32_t>
|
||||
struct color {
|
||||
using type = color<ChannelType, ValueType>;
|
||||
union {
|
||||
struct {
|
||||
ChannelType red;
|
||||
ChannelType green;
|
||||
ChannelType blue;
|
||||
ChannelType alpha;
|
||||
} bits;
|
||||
|
||||
ValueType value = 0U;
|
||||
} colorspace;
|
||||
|
||||
explicit color(ValueType v) {
|
||||
colorspace.value = v;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
auto make_24bit(T&& value) {
|
||||
return color<uint8_t, uint32_t>(forward<T>(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto make_32bit(T&& value) {
|
||||
return color<uint16_t, uint32_t>(forward<T>(value));
|
||||
}
|
||||
|
||||
template <typename ValueType = uint32_t>
|
||||
uint8_t alpha(const color<ValueType> c) {
|
||||
return ((c.colorspace.value >> 24) << 8) | ((c.colorspace.value >> 24));
|
||||
}
|
||||
|
||||
template <typename T = uint8_t, typename ValueType = uint32_t>
|
||||
T red(const color<ValueType> c) {
|
||||
uint8_t r = c.colorspace.value >> 16;
|
||||
if (std::is_same<T, uint8_t>::value)
|
||||
return r << 8 / 0xFF;
|
||||
if (std::is_same<T, uint16_t>::value)
|
||||
return r << 8 | r << 8 / 0xFF;
|
||||
}
|
||||
|
||||
template <typename T = uint8_t, typename ValueType = uint32_t>
|
||||
T green(const color<ValueType> c) {
|
||||
uint8_t g = c.colorspace.value >> 8;
|
||||
if (std::is_same<T, uint8_t>::value)
|
||||
return g << 8 / 0xFF;
|
||||
if (std::is_same<T, uint16_t>::value)
|
||||
return g << 8 | g << 8 / 0xFF;
|
||||
}
|
||||
|
||||
template <typename T = uint8_t, typename ValueType = uint32_t>
|
||||
T blue(const color<ValueType> c) {
|
||||
uint8_t b = c.colorspace.value;
|
||||
if (std::is_same<T, uint8_t>::value)
|
||||
return b << 8 / 0xFF;
|
||||
if (std::is_same<T, uint16_t>::value)
|
||||
return b << 8 | b << 8 / 0xFF;
|
||||
}
|
||||
|
||||
string hex(const color<uint8_t, uint32_t> value) {
|
||||
// clang-format off
|
||||
return string_util::from_stream(stringstream()
|
||||
<< "#"
|
||||
<< std::setw(6)
|
||||
<< std::setfill('0')
|
||||
<< std::hex
|
||||
<< std::uppercase
|
||||
<< (value.colorspace.value & 0x00FFFFFF));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
string hex(const color<uint16_t, uint32_t> value) {
|
||||
// clang-format off
|
||||
return string_util::from_stream(stringstream()
|
||||
<< "#"
|
||||
<< std::setw(8)
|
||||
<< std::setfill('0')
|
||||
<< std::hex
|
||||
<< std::uppercase
|
||||
<< value.colorspace.value);
|
||||
// clang-format on
|
||||
}
|
||||
}
|
||||
|
||||
LEMONBUDDY_NS_END
|
|
@ -12,6 +12,7 @@ function(unit_test file)
|
|||
add_test(unit_test.${testname} unit_test.${testname})
|
||||
endfunction()
|
||||
|
||||
unit_test("utils/color")
|
||||
unit_test("utils/math")
|
||||
unit_test("utils/memory")
|
||||
unit_test("utils/string")
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#include "common/test.hpp"
|
||||
#include "utils/color.hpp"
|
||||
|
||||
int main() {
|
||||
using namespace lemonbuddy;
|
||||
|
||||
"rgb"_test = []{
|
||||
auto color = color_util::make_24bit(0x123456);
|
||||
expect(color_util::alpha(color) == 0);
|
||||
expect(color_util::red<uint8_t>(color) == 0x12);
|
||||
expect(color_util::green<uint8_t>(color) == 0x34);
|
||||
expect(color_util::blue<uint8_t>(color) == 0x56);
|
||||
};
|
||||
|
||||
"rgba"_test = []{
|
||||
auto color = color_util::make_32bit(0xCC123456);
|
||||
expect(color_util::alpha(color) == 0xCC);
|
||||
expect(color_util::red<uint16_t>(color) == 0x1212);
|
||||
expect(color_util::green<uint16_t>(color) == 0x3434);
|
||||
expect(color_util::blue<uint16_t>(color) == 0x5656);
|
||||
};
|
||||
|
||||
"hex"_test = [] {
|
||||
auto colorA = color_util::make_24bit(0x123456);
|
||||
expect(color_util::hex(colorA) == "#123456");
|
||||
auto colorB = color_util::make_32bit(0xCC123456);
|
||||
expect(color_util::hex(colorB) == "#CC123456");
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue