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 
36 namespace xlnt {
37 
41 class XLNT_API indexed_color
42 {
43 public:
44  //TODO: should this be explicit?
48  indexed_color(std::size_t index);
49 
53  std::size_t index() const;
54 
58  void index(std::size_t index);
59 
60 private:
64  std::size_t index_;
65 };
66 
70 class XLNT_API theme_color
71 {
72 public:
76  theme_color(std::size_t index);
77 
81  std::size_t index() const;
82 
86  void index(std::size_t index);
87 
88 private:
92  std::size_t index_;
93 };
94 
98 class XLNT_API rgb_color
99 {
100 public:
104  rgb_color(const std::string &hex_string);
105 
110  rgb_color(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a = 255);
111 
115  std::string hex_string() const;
116 
120  std::uint8_t red() const;
121 
125  std::uint8_t green() const;
126 
130  std::uint8_t blue() const;
131 
135  std::uint8_t alpha() const;
136 
140  std::array<std::uint8_t, 3> rgb() const;
141 
145  std::array<std::uint8_t, 4> rgba() const;
146 
147 private:
151  std::array<std::uint8_t, 4> rgba_;
152 };
153 
157 enum class color_type
158 {
159  indexed,
160  theme,
161  rgb
162 };
163 
167 class XLNT_API color
168 {
169 public:
173  static const color black();
174 
178  static const color white();
179 
183  static const color red();
184 
188  static const color darkred();
189 
193  static const color blue();
194 
198  static const color darkblue();
199 
203  static const color green();
204 
208  static const color darkgreen();
209 
213  static const color yellow();
214 
218  static const color darkyellow();
219 
223  color();
224 
228  color(const rgb_color &rgb);
229 
233  color(const indexed_color &indexed);
234 
238  color(const theme_color &theme);
239 
243  color_type type() const;
244 
248  bool auto_() const;
249 
253  void auto_(bool value);
254 
260  const rgb_color &rgb() const;
261 
267  rgb_color &rgb();
268 
274  const indexed_color &indexed() const;
275 
281  indexed_color &indexed();
282 
288  const theme_color &theme() const;
289 
295  theme_color &theme();
296 
300  bool has_tint() const;
301 
305  double tint() const;
306 
310  void tint(double tint);
311 
315  bool operator==(const color &other) const;
316 
320  bool operator!=(const color &other) const;
321 
322 private:
326  void assert_type(color_type t) const;
327 
331  color_type type_;
332 
336  rgb_color rgb_;
337 
341  indexed_color indexed_;
342 
346  theme_color theme_;
347 
351  optional<double> tint_;
352 
356  bool auto_color = false;
357 };
358 
359 } // namespace xlnt
360 
361 namespace std {
362 
363 template<>
364 struct hash<xlnt::color>
365 {
366  size_t operator()(const xlnt::color& c) const
367  {
368  size_t seed = 0;
369  // Start by hashing the type to prevent collisions between different color types
370  // that might share an underlying value (e.g., theme(1) vs indexed(1)).
371  xlnt::detail::hash_combine(seed, static_cast<int>(c.type()));
372 
373  // Hash auto color flag
374  xlnt::detail::hash_combine(seed, c.auto_());
375 
376  // Hash tint if present
377  if (c.has_tint())
378  {
379  xlnt::detail::hash_combine(seed, c.tint());
380  }
381 
382  switch (c.type())
383  {
384  case xlnt::color_type::indexed:
385  xlnt::detail::hash_combine(seed, c.indexed().index());
386  break;
387  case xlnt::color_type::theme:
388  xlnt::detail::hash_combine(seed, c.theme().index());
389  break;
390  case xlnt::color_type::rgb:
391  {
392  const auto& rgb = c.rgb();
393  xlnt::detail::hash_combine(seed, rgb.red());
394  xlnt::detail::hash_combine(seed, rgb.green());
395  xlnt::detail::hash_combine(seed, rgb.blue());
396  xlnt::detail::hash_combine(seed, rgb.alpha());
397  break;
398  }
399  }
400  return seed;
401  }
402 };
403 
404 } // 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:167
color_type
Some colors are references to colors rather than having a particular RGB value.
Definition: color.hpp:157
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:41
bool has_tint() const
Returns true if tint is set
A theme color encapsulates a color derived from the theme.
Definition: color.hpp:70
An RGB color describes a color in terms of its red, green, blue, and alpha components.
Definition: color.hpp:98
color_type type() const
Returns the type of this color