SHARE
TWEET

Untitled

a guest Apr 20th, 2019 59 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #pragma once
  2.  
  3. #include <cstdint>
  4. #include <utility>
  5. #include <type_traits>
  6.  
  7. #define ASSERT_SIZE(x, sz) static_assert(sizeof(x) == sz, "Wrong size in " #x)
  8. #define ASSERT_STANDARD_LAYOUT(x) static_assert(std::is_standard_layout_v<x>, #x "is not standard layout")
  9.  
  10. struct rgb565_t {
  11.     union {
  12.         struct {
  13.             uint16_t r: 5, g: 6, b: 5;
  14.         } __attribute__((packed));
  15.         uint16_t rgb;
  16.     };
  17.     inline rgb565_t(uint16_t raw): rgb(raw) { }
  18.     inline rgb565_t(uint8_t r, uint8_t g, uint8_t b): r(r), g(g), b(b) { }
  19. };
  20. ASSERT_SIZE(rgb565_t, 2);
  21. ASSERT_STANDARD_LAYOUT(rgb565_t);
  22.  
  23. struct rgba4444_t {
  24.     union {
  25.         struct {
  26.             uint16_t r: 4, g: 4, b: 4, a: 4;
  27.         } __attribute__((packed));
  28.         uint16_t rgba;
  29.     };
  30.     inline rgba4444_t(uint16_t raw): rgba(raw) { }
  31.     inline rgba4444_t(uint8_t r, uint8_t g, uint8_t b, uint8_t a): r(r), g(g), b(b), a(a) { }
  32. };
  33. ASSERT_SIZE(rgba4444_t, 2);
  34. ASSERT_STANDARD_LAYOUT(rgba4444_t);
  35.  
  36. template<typename T, typename=void>
  37. struct has_alpha : std::false_type { };
  38.  
  39. template<typename T>
  40. struct has_alpha<T, decltype(std::declval<T>().a, void())> : std::true_type { };
  41.  
  42. template<typename T>
  43. inline constexpr bool has_alpha_v = has_alpha<T>::value;
  44.  
  45. template<typename T>
  46. struct col_underlying_type { typedef decltype(T::r) type; };
  47.  
  48. template<typename T>
  49. using col_underlying_type_t = typename col_underlying_type<T>::type;
  50.  
  51. template<typename T>
  52. inline T MakeColor(col_underlying_type_t<T> raw) {
  53.     return T(raw);
  54. }
  55.  
  56. template<typename T>
  57. typename std::enable_if_t<!has_alpha_v<T>, T>
  58. inline MakeColor(decltype(T::r) r, decltype(T::g) g, decltype(T::b) b) {
  59.     return T(r, g, b);
  60. }
  61.  
  62. template<typename T>
  63. typename std::enable_if_t<has_alpha_v<T>, T>
  64. inline MakeColor(decltype(T::r) r, decltype(T::g) g, decltype(T::b) b, decltype(T::a) a=-1) {
  65.     return T(r, g, b, a);
  66. }
  67.  
  68. template<typename T>
  69. typename std::enable_if_t<!has_alpha_v<T>, T>
  70. inline make_color_min_alpha() {
  71.     return MakeColor<T>(0, 0, 0);
  72. }
  73.  
  74. template<typename T>
  75. typename std::enable_if_t<has_alpha_v<T>, T>
  76. inline make_color_min_alpha() {
  77.     return MakeColor<T>(0, 0, 0, 0);
  78. }
  79.  
  80. template<typename T>
  81. inline T make_color_max_alpha(decltype(T::r) r, decltype(T::g) g, decltype(T::b) b) {
  82.     return MakeColor<T>(r, g, b);
  83. }
  84.  
  85. template<typename T>
  86. inline T make_color_max_all() {
  87.     return MakeColor<T>(-1, -1, -1);
  88. }
  89.  
  90. #define BLEND_CHANNEL(x, y, a) (((a) * (x) + ((0xff - (a)) * (y))) / 0xff)
  91.  
  92. template<typename T>
  93. typename std::enable_if_t<!has_alpha_v<T>, T>
  94. inline Blend(T x, T y, uint8_t alpha) {
  95.     return MakeColor<T>(
  96.         BLEND_CHANNEL(x.r, y.r, alpha),
  97.         BLEND_CHANNEL(x.g, y.g, alpha),
  98.         BLEND_CHANNEL(x.b, y.b, alpha)
  99.     );
  100. }
  101.  
  102. template<typename T>
  103. typename std::enable_if_t<has_alpha_v<T>, T>
  104. inline Blend(T x, T y, uint8_t alpha) {
  105.     return MakeColor<T>(
  106.         BLEND_CHANNEL(x.r, y.r, alpha),
  107.         BLEND_CHANNEL(x.g, y.g, alpha),
  108.         BLEND_CHANNEL(x.b, y.b, alpha),
  109.         BLEND_CHANNEL(1,   y.a, alpha)
  110.     );
  111. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top