Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RColor.hxx
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
3  * All rights reserved. *
4  * *
5  * For the licensing terms see $ROOTSYS/LICENSE. *
6  * For the list of contributors see $ROOTSYS/README/CREDITS. *
7  *************************************************************************/
8 
9 #ifndef ROOT7_RColor
10 #define ROOT7_RColor
11 
12 #include <ROOT/RAttrBase.hxx>
13 
14 #include <array>
15 
16 
17 namespace ROOT {
18 namespace Experimental {
19 
20 // TODO: see also imagemagick's C++ interface for RColor operations!
21 // https://www.imagemagick.org/api/magick++-classes.php
22 
23 /** \class RColor
24 \ingroup GpadROOT7
25 \brief The color class
26 \author Axel Naumann <axel@cern.ch>
27 \author Sergey Linev <S.Linev@gsi.de>
28 \date 2017-09-26
29 \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
30 */
31 
32 class RColor : public RAttrBase {
33 
34  R__ATTR_CLASS(RColor, "color_", AddString("rgb", "").AddString("a", "").AddString("name", "").AddBool("auto", false));
35 
36  using RGB_t = std::array<int, 3>;
37 
38 private:
39 
40  static std::string toHex(int v);
41 
42  /** Set RGB values as floats, each from 0..1. Real color values will be stored in hex format */
43  RColor &SetRGBFloat(float r, float g, float b)
44  {
45  return SetRGB(int(r*255),int(g*255),int(b*255));
46  }
47 
48  bool GetRGBFloat(float &r, float &g, float &b) const;
49 
50  int GetColorComponent(int indx) const;
51 
52 public:
53 
54  /** Construct color with provided r,g,b values */
55  RColor(int r, int g, int b) : RColor() { SetRGB(r, g, b); }
56 
57  /** Construct color with provided r,g,b and alpha values */
58  RColor(int r, int g, int b, float alpha) : RColor()
59  {
60  SetRGB(r, g, b);
61  SetAlpha(alpha);
62  }
63 
64  /** Construct color with provided RGB_t value */
65  RColor(const RGB_t &rgb) : RColor() { SetRGB(rgb); }
66 
67  /** Set r/g/b/ components of color as hex code, default for the color */
68  RColor &SetRGB(const RGB_t &rgb) { return SetRGB(rgb[0], rgb[1], rgb[2]); }
69 
70  /** Set r/g/b/ components of color as hex code, default for the color */
71  RColor &SetRGB(int r, int g, int b) { return SetHex(toHex(r) + toHex(g) + toHex(b)); }
72 
73  /** Set color as hex string like 00FF00 */
74  RColor &SetHex(const std::string &_hex)
75  {
76  SetValue("rgb", _hex);
77  return *this;
78  }
79 
80  /** Return color as hex string like 00FF00 */
81  std::string GetHex() const { return GetValue<std::string>("rgb"); }
82 
83  bool GetRGB(int &r, int &g, int &b) const;
84 
85  /** Returns red color component 0..255 */
86  int GetRed() const { return GetColorComponent(0); }
87 
88  /** Returns green color component 0..255 */
89  int GetGreen() const { return GetColorComponent(1); }
90 
91  /** Returns blue color component 0..255 */
92  int GetBlue() const { return GetColorComponent(2); }
93 
94  /** Clear RGB color value (if any) */
95  void ClearRGB()
96  {
97  ClearValue("rgb");
98  }
99 
100  /** Set color as plain SVG name like "white" or "lightblue". Clears RGB component before */
101  RColor &SetName(const std::string &_name)
102  {
103  ClearRGB();
104  SetValue("name", _name);
105  return *this;
106  }
107 
108  /** Returns color as plain SVG name like "white" or "lightblue" */
109  std::string GetName() const { return GetValue<std::string>("name"); }
110 
111  /** Clear color plain SVG name (if any) */
112  void ClearName() { ClearValue("name"); }
113 
114  /** Returns color alpha (opacity) as float from 0. to 1. */
115  float GetAlpha() const
116  {
117  auto hex = GetAlphaHex();
118  if (hex.empty())
119  return 1.;
120  return std::strtol(hex.c_str(), nullptr, 16) / 255.;
121  }
122 
123  /** Returns color alpha (opacity) as hex string like FF. Default is empty */
124  std::string GetAlphaHex() const { return GetValue<std::string>("a"); }
125 
126  /** Returns true if color alpha (opacity) was specified */
127  bool HasAlpha() const { return HasValue("a"); }
128 
129  /** Set color alpha (opacity) value - from 0 to 1 */
130  RColor &SetAlpha(float _alpha) { return SetAlphaHex(toHex((int)(_alpha * 255))); }
131 
132  /** Set color alpha (opacity) value as hex string */
133  RColor &SetAlphaHex(const std::string &_alfa)
134  {
135  SetValue("a", _alfa);
136  return *this;
137  }
138 
139  /** Clear alpha value of the color */
140  void ClearAlpha() { ClearValue("a"); }
141 
142  /** Returns true if color should get auto value when primitive drawing is performed */
143  bool IsAuto() const { return GetValue<bool>("auto"); }
144 
145  /** Set automatic mode for RColor, will be assigned before primitive painted on the canvas */
146  RColor &SetAuto(bool on = true)
147  {
148  SetValue("auto", on);
149  return *this;
150  }
151 
152  /** Clear auto flag of the RColor */
153  void ClearAuto() { ClearValue("auto"); }
154 
155  /** Return the Hue, Light, Saturation (HLS) definition of this RColor */
156  bool GetHLS(float &hue, float &light, float &satur) const;
157 
158  /** Set the Red Green and Blue (RGB) values from the Hue, Light, Saturation (HLS). */
159  RColor &SetHLS(float hue, float light, float satur);
160 
161  /** Returns color value as it will be used in SVG drawing
162  * It either include hex format #66FF66 or just plain SVG name */
163  std::string AsSVG() const
164  {
165  auto hex = GetHex();
166  if (!hex.empty())
167  return std::string("#") + hex + GetAlphaHex();
168 
169 
170  // check that alpha is not specified
171  return GetName();
172  }
173 
174  void Clear()
175  {
176  ClearRGB();
177  ClearName();
178  ClearAlpha();
179  ClearAuto();
180  }
181 
182  static constexpr RGB_t kRed{{255, 0, 0}};
183  static constexpr RGB_t kGreen{{0, 255, 0}};
184  static constexpr RGB_t kBlue{{0, 0, 255}};
185  static constexpr RGB_t kWhite{{255, 255, 255}};
186  static constexpr RGB_t kBlack{{0, 0, 0}};
187  static constexpr double kTransparent{0.};
188  static constexpr double kOpaque{1.};
189 
190  friend bool operator==(const RColor &lhs, const RColor &rhs)
191  {
192  // auto flag is not taken into account when comparing colors
193  return (lhs.GetHex() == rhs.GetHex()) && (lhs.GetName() == rhs.GetName()) &&
194  (lhs.GetAlphaHex() == rhs.GetAlphaHex()); // && (lhs.IsAuto() == rhs.IsAuto());
195  }
196 };
197 
198 } // namespace Experimental
199 } // namespace ROOT
200 
201 #endif