11 using namespace ROOT::Experimental;
13 constexpr RColor::RGB_t RColor::kRed;
14 constexpr RColor::RGB_t RColor::kGreen;
15 constexpr RColor::RGB_t RColor::kBlue;
16 constexpr RColor::RGB_t RColor::kWhite;
17 constexpr RColor::RGB_t RColor::kBlack;
18 constexpr
double RColor::kTransparent;
19 constexpr
double RColor::kOpaque;
24 std::string RColor::toHex(
int v)
26 static const char *digits =
"0123456789ABCDEF";
32 std::string res(2,
'0');
33 res[0] = digits[v >> 4];
34 res[1] = digits[v & 0xf];
42 bool RColor::GetRGB(
int &r,
int &g,
int &b)
const
45 if (hex.length() != 6)
48 r = std::stoi(hex.substr(0,2),
nullptr, 16);
49 g = std::stoi(hex.substr(2,2),
nullptr, 16);
50 b = std::stoi(hex.substr(4,2),
nullptr, 16);
59 int RColor::GetColorComponent(
int indx)
const
63 return hex.length() == 6 ? std::stoi(hex.substr(indx * 2, 2),
nullptr, 16) : 0;
70 bool RColor::GetRGBFloat(
float &r,
float &g,
float &b)
const
73 if (!GetRGB(ri,gi,bi))
85 bool RColor::GetHLS(
float &hue,
float &light,
float &satur)
const
87 float red, green, blue;
88 if (!GetRGBFloat(red,green,blue))
91 hue = light = satur = 0.;
93 float rnorm, gnorm, bnorm, minval, maxval, msum, mdiff;
97 if (green < minval) minval = green;
98 if (blue < minval) minval = blue;
100 if (green > maxval) maxval = green;
101 if (blue > maxval) maxval = blue;
103 rnorm = gnorm = bnorm = 0;
104 mdiff = maxval - minval;
105 msum = maxval + minval;
107 if (maxval != minval) {
108 rnorm = (maxval - red)/mdiff;
109 gnorm = (maxval - green)/mdiff;
110 bnorm = (maxval - blue)/mdiff;
116 if (light < 0.5) satur = mdiff/msum;
117 else satur = mdiff/(2.0 - msum);
119 if (red == maxval) hue = 60.0 * (6.0 + bnorm - gnorm);
120 else if (green == maxval) hue = 60.0 * (2.0 + rnorm - bnorm);
121 else hue = 60.0 * (4.0 + gnorm - rnorm);
123 if (hue > 360) hue = hue - 360;
130 RColor &RColor::SetHLS(
float hue,
float light,
float satur)
132 float rh, rl, rs, rm1, rm2;
134 if (hue > 0) { rh = hue;
if (rh > 360) rh = 360; }
135 if (light > 0) { rl = light;
if (rl > 1) rl = 1; }
136 if (satur > 0) { rs = satur;
if (rs > 1) rs = 1; }
138 if (rl <= 0.5) rm2 = rl*(1.0 + rs);
139 else rm2 = rl + rs - rl*rs;
142 if (!rs) { SetRGBFloat(rl, rl, rl);
return *
this; }
144 auto toRGB = [rm1, rm2] (
float h) {
145 if (h > 360) h = h - 360;
146 if (h < 0) h = h + 360;
147 if (h < 60 )
return rm1 + (rm2-rm1)*h/60;
148 if (h < 180)
return rm2;
149 if (h < 240)
return rm1 + (rm2-rm1)*(240-h)/60;
153 return SetRGBFloat(toRGB(rh+120), toRGB(rh), toRGB(rh-120));