xlnt - community edition
color.hpp
1 // Copyright (c) 2014-2022 Thomas Fussell
2 // Copyright (c) 2010-2015 openpyxl
3 // Copyright (c) 2024-2026 xlnt-community
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE
22 //
23 // @license: http://www.opensource.org/licenses/mit-license.php
24 // @author: see AUTHORS file
25 
26 #pragma once
27 
28 #include <array>
29 #include <cstring>
30 #include <functional>
31 
32 #include <xlnt/xlnt_config.hpp>
33 #include <xlnt/utils/optional.hpp>
34 #include <xlnt/utils/hash_combine.hpp>
35 #include <xlnt/utils/value_with_default.h>
36 
37 namespace xlnt {
38 
39 namespace detail {
40 
41 class xlsx_producer;
42 
43 } // namespace detail
44 
48 class XLNT_API indexed_color
49 {
50 public:
51  //TODO: should this be explicit?
55  indexed_color(std::size_t index);
56 
60  std::size_t index() const;
61 
65  void index(std::size_t index);
66 
67 private:
71  std::size_t index_;
72 };
73 
77 class XLNT_API theme_color
78 {
79 public:
83  theme_color(std::size_t index);
84 
88  std::size_t index() const;
89 
93  void index(std::size_t index);
94 
95 private:
99  std::size_t index_;
100 };
101 
105 class XLNT_API rgb_color
106 {
107 public:
111  rgb_color(const std::string &hex_string);
112 
117  rgb_color(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a = 255);
118 
122  std::string hex_string() const;
123 
127  std::uint8_t red() const;
128 
132  std::uint8_t green() const;
133 
137  std::uint8_t blue() const;
138 
142  std::uint8_t alpha() const;
143 
147  std::array<std::uint8_t, 3> rgb() const;
148 
152  std::array<std::uint8_t, 4> rgba() const;
153 
154 private:
158  std::array<std::uint8_t, 4> rgba_;
159 };
160 
164 enum class color_type
165 {
166  indexed,
167  theme,
168  rgb
169 };
170 
174 class XLNT_API color
175 {
176 public:
180  static const color black();
181 
185  static const color white();
186 
190  static const color red();
191 
195  static const color darkred();
196 
200  static const color blue();
201 
205  static const color darkblue();
206 
210  static const color green();
211 
215  static const color darkgreen();
216 
220  static const color yellow();
221 
225  static const color darkyellow();
226 
230  color();
231 
235  color(const rgb_color &rgb);
236 
240  color(const indexed_color &indexed);
241 
245  color(const theme_color &theme);
246 
250  color_type type() const;
251 
255  bool auto_() const;
256 
260  void auto_(bool value);
261 
267  const rgb_color &rgb() const;
268 
274  rgb_color &rgb();
275 
281  const indexed_color &indexed() const;
282 
288  indexed_color &indexed();
289 
295  const theme_color &theme() const;
296 
302  theme_color &theme();
303 
307  bool has_tint() const;
308 
312  double tint() const;
313 
317  void tint(double tint);
318 
322  bool operator==(const color &other) const;
323 
327  bool operator!=(const color &other) const;
328 
329 private:
330  friend class detail::xlsx_producer;
331 
335  void assert_type(color_type t) const;
336 
340  color_type type_;
341 
345  rgb_color rgb_;
346 
350  indexed_color indexed_;
351 
355  theme_color theme_;
356 
361 
365  bool auto_color = false;
366 };
367 
368 } // namespace xlnt
369 
370 namespace std {
371 
372 template<>
373 struct hash<xlnt::color>
374 {
375  size_t operator()(const xlnt::color& c) const
376  {
377  size_t seed = 0;
378  // Start by hashing the type to prevent collisions between different color types
379  // that might share an underlying value (e.g., theme(1) vs indexed(1)).
380  xlnt::detail::hash_combine(seed, static_cast<int>(c.type()));
381 
382  // Hash auto color flag
383  xlnt::detail::hash_combine(seed, c.auto_());
384 
385  // Hash tint if present
386  if (c.has_tint())
387  {
388  xlnt::detail::hash_combine(seed, c.tint());
389  }
390 
391  switch (c.type())
392  {
393  case xlnt::color_type::indexed:
394  xlnt::detail::hash_combine(seed, c.indexed().index());
395  break;
396  case xlnt::color_type::theme:
397  xlnt::detail::hash_combine(seed, c.theme().index());
398  break;
399  case xlnt::color_type::rgb:
400  {
401  const auto& rgb = c.rgb();
402  xlnt::detail::hash_combine(seed, rgb.red());
403  xlnt::detail::hash_combine(seed, rgb.green());
404  xlnt::detail::hash_combine(seed, rgb.blue());
405  xlnt::detail::hash_combine(seed, rgb.alpha());
406  break;
407  }
408  }
409  return seed;
410  }
411 };
412 
413 } // namespace std
std::size_t index() const
Returns the index this color points to.
std::size_t index() const
Returns the index of the color in the theme this points to.
const rgb_color & rgb() const
Returns the internal indexed color representing this color. Assumes that this is an RGB color (to che...
Definition: cell_reference.hpp:288
const theme_color & theme() const
Returns the internal indexed color representing this color. Assumes that this is a theme color (to ch...
Enumerates the possible types a cell can be determined by it&#39;s current value.
Definition: cell.hpp:36
bool operator!=(std::nullptr_t, const cell &cell)
Returns true if this cell is initialized.
bool auto_() const
Returns true if this color has been set to auto
Colors can be applied to many parts of a cell&#39;s style.
Definition: color.hpp:174
color_type
Some colors are references to colors rather than having a particular RGB value.
Definition: color.hpp:164
Encapsulates a value with a default value
Definition: value_with_default.h:59
bool operator==(std::nullptr_t, const cell &cell)
Returns true if this cell is uninitialized.
A theme is a combination of fonts, colors, and effects. This isn&#39;t really supported yet...
Definition: theme.hpp:35
const indexed_color & indexed() const
Returns the internal indexed color representing this color. Assumes that this is an indexed color (to...
double tint() const
Returns the tint of this color.
An indexed color encapsulates a simple index to a color in the indexedColors of the stylesheet...
Definition: color.hpp:48
bool has_tint() const
Returns true if tint is set
A theme color encapsulates a color derived from the theme.
Definition: color.hpp:77
An RGB color describes a color in terms of its red, green, blue, and alpha components.
Definition: color.hpp:105
color_type type() const
Returns the type of this color