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