The Battle for Wesnoth  1.17.0-dev
color.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2021
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include <algorithm> // for max
18 #include <cstdint>
19 #include <ostream>
20 #include <string>
21 #include <utility>
22 
23 struct SDL_Color;
24 
25 //
26 // TODO: constexpr
27 //
28 
29 const uint32_t SDL_ALPHA_MASK = 0xFF000000;
30 const uint32_t SDL_RED_MASK = 0x00FF0000;
31 const uint32_t SDL_GREEN_MASK = 0x0000FF00;
32 const uint32_t SDL_BLUE_MASK = 0x000000FF;
33 
34 const uint32_t SDL_ALPHA_BITSHIFT = 24;
35 const uint32_t SDL_RED_BITSHIFT = 16;
36 const uint32_t SDL_GREEN_BITSHIFT = 8;
37 const uint32_t SDL_BLUE_BITSHIFT = 0;
38 
39 const uint32_t RGBA_ALPHA_MASK = 0x000000FF;
40 const uint32_t RGBA_RED_MASK = 0xFF000000;
41 const uint32_t RGBA_GREEN_MASK = 0x00FF0000;
42 const uint32_t RGBA_BLUE_MASK = 0x0000FF00;
43 
44 const uint32_t RGBA_ALPHA_BITSHIFT = 0;
45 const uint32_t RGBA_RED_BITSHIFT = 24;
46 const uint32_t RGBA_GREEN_BITSHIFT = 16;
47 const uint32_t RGBA_BLUE_BITSHIFT = 8;
48 
49 const uint8_t ALPHA_OPAQUE = 255;
50 
51 struct color_t
52 {
54  : r(255)
55  , g(255)
56  , b(255)
57  , a(ALPHA_OPAQUE)
58  {}
59 
60  color_t(uint8_t r_val, uint8_t g_val, uint8_t b_val, uint8_t a_val = ALPHA_OPAQUE)
61  : r(r_val)
62  , g(g_val)
63  , b(b_val)
64  , a(a_val)
65  {}
66 
67  // Implemented in sdl/utils.cpp to avoid dependency nightmares
68  explicit color_t(const SDL_Color& c);
69 
70  /**
71  * Creates a new color_t object from a string variable in "R,G,B,A" format.
72  * An empty string results in white. Otherwise, omitting components other than
73  * alpha is an error.
74  *
75  * @param c A string variable, in "R,G,B,A" format.
76  * @return A new color_t object.
77  *
78  * @throw std::invalid_argument if the string is not correctly formatted
79  */
80  static color_t from_rgba_string(const std::string& c);
81 
82  /**
83  * Creates a new opaque color_t object from a string variable in "R,G,B" format.
84  * An empty string results in white. Otherwise, omitting components is an error.
85  *
86  * @param c A string variable, in "R,G,B" format.
87  * @return A new color_t object.
88  *
89  * @throw std::invalid_argument if the string is not correctly formatted
90  */
91  static color_t from_rgb_string(const std::string& c);
92 
93  /**
94  * Creates a new color_t object from a string variable in hex format.
95  *
96  * @param c A string variable, in rrggbb hex format.
97  * @return A new color_t object.
98  *
99  * @throw std::invalid_argument if the string is not correctly formatted
100  */
101  static color_t from_hex_string(const std::string& c);
102 
103  /**
104  * Creates a new color_t object from a uint32_t variable.
105  *
106  * @param c A uint32_t variable, in RGBA format.
107  * @return A new color_t object.
108  */
109  static color_t from_rgba_bytes(uint32_t c);
110 
111  /**
112  * Creates a new color_t object from a uint32_t variable.
113  *
114  * @param c A uint32_t variable, in ARGB format.
115  * @return A new color_t object.
116  */
117  static color_t from_argb_bytes(uint32_t c);
118 
119  /**
120  * Returns the stored color in rrggbb hex format.
121  *
122  * @return The string in hex format. The preceding '#' needed for pango markup
123  * is prepended.
124  */
125  std::string to_hex_string() const;
126 
127  /**
128  * Returns the stored color as a uint32_t, in RGBA format.
129  *
130  * @return The new uint32_t object.
131  */
132  uint32_t to_rgba_bytes() const
133  {
134  return
135  (static_cast<uint32_t>(r) << RGBA_RED_BITSHIFT) |
136  (static_cast<uint32_t>(g) << RGBA_GREEN_BITSHIFT) |
137  (static_cast<uint32_t>(b) << RGBA_BLUE_BITSHIFT) |
138  (static_cast<uint32_t>(a) << RGBA_ALPHA_BITSHIFT);
139  }
140 
141  /**
142  * Returns the stored color as a uint32_t, an ARGB format.
143  *
144  * @return The new uint32_t object.
145  */
146  uint32_t to_argb_bytes() const
147  {
148  return
149  (static_cast<uint32_t>(r) << SDL_RED_BITSHIFT) |
150  (static_cast<uint32_t>(g) << SDL_GREEN_BITSHIFT) |
151  (static_cast<uint32_t>(b) << SDL_BLUE_BITSHIFT) |
152  (static_cast<uint32_t>(a) << SDL_ALPHA_BITSHIFT);
153  }
154 
155  /**
156  * Returns the stored color as an "R,G,B,A" string
157  *
158  * @return The new color string.
159  */
160  std::string to_rgba_string() const;
161 
162  /**
163  * Returns the stored color as an "R,G,B" string
164  *
165  * @return The new color string.
166  */
167  std::string to_rgb_string() const;
168 
169  /**
170  * Returns the stored color as an color_t object.
171  *
172  * @return The new color_t object.
173  */
174  // Implemented in sdl/utils.cpp to avoid dependency nightmares
175  SDL_Color to_sdl() const;
176 
177  /** Red value */
178  uint8_t r;
179 
180  /** Green value */
181  uint8_t g;
182 
183  /** Blue value */
184  uint8_t b;
185 
186  /** Alpha value */
187  uint8_t a;
188 
189  bool null() const
190  {
191  return *this == null_color();
192  }
193 
194  bool operator==(const color_t& c) const
195  {
196  return r == c.r && g == c.g && b == c.b && a == c.a;
197  }
198 
199  bool operator!=(const color_t& c) const
200  {
201  return !(*this == c);
202  }
203 
204  color_t blend_add(const color_t& c) const
205  {
206  // Do some magic to detect integer overflow
207  // We want overflows to max out the component instead of wrapping.
208  // The static_cast is to silence narrowing conversion warnings etc
209  return {
210  static_cast<uint8_t>(r > 255 - c.r ? 255 : r + c.r),
211  static_cast<uint8_t>(g > 255 - c.g ? 255 : g + c.g),
212  static_cast<uint8_t>(b > 255 - c.b ? 255 : b + c.b),
213  static_cast<uint8_t>(a > 255 - c.a ? 255 : a + c.a),
214  };
215  }
216 
217  color_t blend_lighten(const color_t& c) const
218  {
219  return {
220  std::max<uint8_t>(r, c.r),
221  std::max<uint8_t>(g, c.g),
222  std::max<uint8_t>(b, c.b),
223  std::max<uint8_t>(a, c.a),
224  };
225  }
226 
227  color_t inverse() const {
228  return {
229  static_cast<uint8_t>(255 - r),
230  static_cast<uint8_t>(255 - g),
231  static_cast<uint8_t>(255 - b),
232  a
233  };
234  }
235 
236  /** Definition of a 'null' color - fully transparent black. */
238  {
239  return {0,0,0,0};
240  }
241 };
242 
243 inline std::ostream& operator<<(std::ostream& s, const color_t& c)
244 {
245  s << static_cast<int>(c.r) << " "
246  << static_cast<int>(c.g) << " "
247  << static_cast<int>(c.b) << " "
248  << static_cast<int>(c.a) << std::endl;
249 
250  return s;
251 }
252 
253 namespace std
254 {
255  template<>
256  struct hash<color_t>
257  {
258  std::size_t operator()(const color_t& c) const noexcept
259  {
260  return c.to_rgba_bytes();
261  }
262  };
263 }
std::string to_rgba_string() const
Returns the stored color as an "R,G,B,A" string.
Definition: color.cpp:111
const uint32_t RGBA_ALPHA_MASK
Definition: color.hpp:39
const uint32_t RGBA_GREEN_BITSHIFT
Definition: color.hpp:46
const uint32_t SDL_BLUE_MASK
Definition: color.hpp:32
const uint32_t RGBA_BLUE_BITSHIFT
Definition: color.hpp:47
bool operator==(const color_t &c) const
Definition: color.hpp:194
const uint32_t SDL_ALPHA_MASK
Definition: color.hpp:29
const uint32_t SDL_GREEN_BITSHIFT
Definition: color.hpp:36
bool operator!=(const color_t &c) const
Definition: color.hpp:199
const uint32_t RGBA_RED_BITSHIFT
Definition: color.hpp:45
std::string to_rgb_string() const
Returns the stored color as an "R,G,B" string.
Definition: color.cpp:123
STL namespace.
const uint32_t RGBA_RED_MASK
Definition: color.hpp:40
SDL_Color to_sdl() const
Returns the stored color as an color_t object.
Definition: utils.cpp:2289
const uint32_t SDL_BLUE_BITSHIFT
Definition: color.hpp:37
color_t blend_add(const color_t &c) const
Definition: color.hpp:204
color_t(uint8_t r_val, uint8_t g_val, uint8_t b_val, uint8_t a_val=ALPHA_OPAQUE)
Definition: color.hpp:60
std::ostream & operator<<(std::ostream &s, const color_t &c)
Definition: color.hpp:243
const uint32_t SDL_RED_MASK
Definition: color.hpp:30
static color_t null_color()
Definition of a &#39;null&#39; color - fully transparent black.
Definition: color.hpp:237
const uint32_t RGBA_GREEN_MASK
Definition: color.hpp:41
static color_t from_hex_string(const std::string &c)
Creates a new color_t object from a string variable in hex format.
Definition: color.cpp:62
const uint32_t SDL_RED_BITSHIFT
Definition: color.hpp:35
uint8_t r
Red value.
Definition: color.hpp:178
uint8_t a
Alpha value.
Definition: color.hpp:187
color_t()
Definition: color.hpp:53
static color_t from_argb_bytes(uint32_t c)
Creates a new color_t object from a uint32_t variable.
Definition: color.cpp:88
std::size_t operator()(const color_t &c) const noexcept
Definition: color.hpp:258
color_t blend_lighten(const color_t &c) const
Definition: color.hpp:217
static map_location::DIRECTION s
std::string to_hex_string() const
Returns the stored color in rrggbb hex format.
Definition: color.cpp:98
static color_t from_rgba_bytes(uint32_t c)
Creates a new color_t object from a uint32_t variable.
Definition: color.cpp:78
bool null() const
Definition: color.hpp:189
uint32_t to_rgba_bytes() const
Returns the stored color as a uint32_t, in RGBA format.
Definition: color.hpp:132
const uint8_t ALPHA_OPAQUE
Definition: color.hpp:49
uint32_t to_argb_bytes() const
Returns the stored color as a uint32_t, an ARGB format.
Definition: color.hpp:146
const uint32_t RGBA_ALPHA_BITSHIFT
Definition: color.hpp:44
const uint32_t SDL_ALPHA_BITSHIFT
Definition: color.hpp:34
const uint32_t SDL_GREEN_MASK
Definition: color.hpp:31
uint8_t g
Green value.
Definition: color.hpp:181
uint8_t b
Blue value.
Definition: color.hpp:184
static color_t from_rgba_string(const std::string &c)
Creates a new color_t object from a string variable in "R,G,B,A" format.
Definition: color.cpp:21
mock_char c
color_t inverse() const
Definition: color.hpp:227
static color_t from_rgb_string(const std::string &c)
Creates a new opaque color_t object from a string variable in "R,G,B" format.
Definition: color.cpp:42
const uint32_t RGBA_BLUE_MASK
Definition: color.hpp:42