24 template <
class T,
class U>
27 if(v > std::numeric_limits<T>::max())
28 return std::numeric_limits<T>::max();
29 else if(v < std::numeric_limits<T>::min())
30 return std::numeric_limits<T>::min();
32 return static_cast<T
>(v);
41 template <
typename T,
typename Enable =
void>
struct ColorTraits;
46 typename std::enable_if<std::is_floating_point<T>::value,
48 static constexpr
bool isFloatingPoint =
true;
49 static constexpr T maxColor = 1.f;
55 typename std::enable_if<std::is_integral<T>::value,
57 static constexpr
bool isFloatingPoint =
false;
58 static constexpr T maxColor = std::numeric_limits<T>::max();
66 template <
typename T,
bool Alpha>
79 : r(r), g(g), b(b), a(a) {}
92 ColorImpl(T r, T g, T b) : r(r), g(g), b(b) {}
93 ColorImpl() : r(T(0)), g(T(0)), b(T(0)) {}
98 template <
typename T,
bool A = false>
102 static constexpr
bool alpha = A;
103 static constexpr
int size = (A ? 4 *
sizeof(T) : 3 *
sizeof(T));
108 for(
int i = 0; i <
sizeof(this->data)/
sizeof(this->data[0]); ++i) {
109 same = same && (this->data[i] == other.data[i]);
115 return !(*
this == other);
118 T& operator[](std::size_t index) {
120 throw std::out_of_range(
"Invalid subscript");
121 return this->data[index];
124 T operator[](std::size_t index)
const {
126 throw std::out_of_range(
"Invalid subscript");
127 return this->data[index];
154 template <
typename Tout>
155 typename std::enable_if<std::is_integral<typename Tout::type>::value,
157 makeColor(
float r,
float g,
float b,
float a = 1.f) {
159 g * internal::ColorTraits<typename Tout::type>::maxColor,
160 b * internal::ColorTraits<typename Tout::type>::maxColor,
161 a * internal::ColorTraits<typename Tout::type>::maxColor);
163 template <
typename Tout>
164 typename std::enable_if<std::is_floating_point<typename Tout::type>::value,
166 makeColor(
float r,
float g,
float b,
float a = 1.f) {
167 return Tout(r, g, b, a);
174 template <
typename T>
175 float colorProportion(T v) {
176 return (v / static_cast<float>(internal::ColorTraits<T>::maxColor));
179 template <
typename Tout,
typename Tin>
180 Tout convertChannelType(Tin in) {
181 return colorProportion(in) * internal::ColorTraits<Tout>::maxColor;
191 template <
typename Tdst,
typename Tsrc>
192 typename std::enable_if<Tdst::A, Tdst>::type color_cast(Color<Tsrc, true> in) {
193 return Tdst(convertChannelType<typename Tdst::type>(in.r),
194 convertChannelType<typename Tdst::type>(in.g),
195 convertChannelType<typename Tdst::type>(in.b),
196 convertChannelType<typename Tdst::type>(in.a));
198 template <
typename Tdst,
typename Tsrc>
199 typename std::enable_if<!Tdst::A, Tdst>::type color_cast(Color<Tsrc, true> in) {
200 return Tdst(convertChannelType<typename Tdst::type>(in.r),
201 convertChannelType<typename Tdst::type>(in.g),
202 convertChannelType<typename Tdst::type>(in.b));
204 template <
typename Tdst,
typename Tsrc>
205 Tdst color_cast(Color<Tsrc, false> in) {
206 return Tdst(convertChannelType<typename Tdst::type>(in.r),
207 convertChannelType<typename Tdst::type>(in.g),
208 convertChannelType<typename Tdst::type>(in.b));
218 template <
typename T>
219 Color<T, true> blendAdditive(Color<T, true> lh, Color<T, true> rh) {
220 float lha = lh.a / 255.f;
221 float rha = rh.a / 255.f;
224 return Color<T, true>(lh.r * lha + rh.r * rha,
225 lh.g * lha + rh.g * rha,
226 lh.b * lha + rh.b * rha,
237 template <
typename T>
238 Color<T, true> blendAlpha(Color<T, true> lh, Color<T, true> rh) {
239 float alpha = rh.a / 255.f;
240 float ainv = 1 - alpha;
243 return Color<T, true>(lh.r * ainv + rh.r * alpha,
244 lh.g * ainv + rh.g * alpha,
245 lh.b * ainv + rh.b * alpha,
246 lh.a * ainv + rh.a * alpha);
Definition: ColorCore.hpp:99
Definition: ColorCore.hpp:41
Definition: ColorCore.hpp:67