Logo ROOT  
Reference Guide
RColor.cxx
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (C) 1995-2017, 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#include "ROOT/RColor.hxx"
10
11using namespace ROOT::Experimental;
12
18constexpr double RColor::kTransparent;
19constexpr double RColor::kOpaque;
20
21///////////////////////////////////////////////////////////////////////////
22/// Converts integer from 0 to 255 into hex format with two digits like 00
23
24std::string RColor::toHex(int v)
25{
26 static const char *digits = "0123456789ABCDEF";
27 if (v < 0)
28 v = 0;
29 else if (v > 255)
30 v = 255;
31
32 std::string res(2,'0');
33 res[0] = digits[v >> 4];
34 res[1] = digits[v & 0xf];
35 return res;
36}
37
38///////////////////////////////////////////////////////////////////////////
39/// Decodes hex color value into RGB - each color component as integer from 0 to 255
40/// If color was not specified as hex, method returns false
41
42bool RColor::GetRGB(int &r, int &g, int &b) const
43{
44 auto hex = GetHex();
45 if (hex.length() != 6)
46 return false;
47
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);
51 return true;
52}
53
54///////////////////////////////////////////////////////////////////////////
55/// Decodes color component and returns integer from 0 to 255
56/// Values of indx 0: Red, 1: Green, 2: Blue
57/// If color was not specified as hex, method returns 0
58
59int RColor::GetColorComponent(int indx) const
60{
61 auto hex = GetHex();
62
63 return hex.length() == 6 ? std::stoi(hex.substr(indx * 2, 2), nullptr, 16) : 0;
64}
65
66///////////////////////////////////////////////////////////////////////////
67/// Decodes hex color value into RGB - each color component as float from 0. to 1.
68/// If color was not specified as hex, method returns false
69
70bool RColor::GetRGBFloat(float &r, float &g, float &b) const
71{
72 int ri, gi, bi;
73 if (!GetRGB(ri,gi,bi))
74 return false;
75 r = ri/255.;
76 g = gi/255.;
77 b = bi/255.;
78 return true;
79}
80
81///////////////////////////////////////////////////////////////////////////
82/// Returns the Hue, Light, Saturation (HLS) definition of this RColor
83/// If color was not specified as hex, method returns false
84
85bool RColor::GetHLS(float &hue, float &light, float &satur) const
86{
87 float red, green, blue;
88 if (!GetRGBFloat(red,green,blue))
89 return false;
90
91 hue = light = satur = 0.;
92
93 float rnorm, gnorm, bnorm, minval, maxval, msum, mdiff;
94 minval = maxval =0 ;
95
96 minval = red;
97 if (green < minval) minval = green;
98 if (blue < minval) minval = blue;
99 maxval = red;
100 if (green > maxval) maxval = green;
101 if (blue > maxval) maxval = blue;
102
103 rnorm = gnorm = bnorm = 0;
104 mdiff = maxval - minval;
105 msum = maxval + minval;
106 light = 0.5 * msum;
107 if (maxval != minval) {
108 rnorm = (maxval - red)/mdiff;
109 gnorm = (maxval - green)/mdiff;
110 bnorm = (maxval - blue)/mdiff;
111 } else {
112 satur = hue = 0;
113 return true;
114 }
115
116 if (light < 0.5) satur = mdiff/msum;
117 else satur = mdiff/(2.0 - msum);
118
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);
122
123 if (hue > 360) hue = hue - 360;
124 return true;
125}
126
127///////////////////////////////////////////////////////////////////////////
128/// Set the color value from the Hue, Light, Saturation (HLS).
129
130RColor &RColor::SetHLS(float hue, float light, float satur)
131{
132 float rh, rl, rs, rm1, rm2;
133 rh = rl = rs = 0;
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; }
137
138 if (rl <= 0.5) rm2 = rl*(1.0 + rs);
139 else rm2 = rl + rs - rl*rs;
140 rm1 = 2.0*rl - rm2;
141
142 if (!rs) { SetRGBFloat(rl, rl, rl); return *this; }
143
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;
150 return rm1;
151 };
152
153 return SetRGBFloat(toRGB(rh+120), toRGB(rh), toRGB(rh-120));
154}
ROOT::R::TRInterface & r
Definition: Object.C:4
#define b(i)
Definition: RSha256.hxx:100
#define g(i)
Definition: RSha256.hxx:105
#define h(i)
Definition: RSha256.hxx:106
@ kRed
Definition: Rtypes.h:64
@ kBlack
Definition: Rtypes.h:63
@ kGreen
Definition: Rtypes.h:64
@ kWhite
Definition: Rtypes.h:63
@ kBlue
Definition: Rtypes.h:64
The color class.
Definition: RColor.hxx:32
int GetColorComponent(int indx) const
Decodes color component and returns integer from 0 to 255 Values of indx 0: Red, 1: Green,...
Definition: RColor.cxx:59
bool GetRGB(int &r, int &g, int &b) const
Decodes hex color value into RGB - each color component as integer from 0 to 255 If color was not spe...
Definition: RColor.cxx:42
RColor & SetRGBFloat(float r, float g, float b)
Set RGB values as floats, each from 0..1.
Definition: RColor.hxx:43
bool GetHLS(float &hue, float &light, float &satur) const
Return the Hue, Light, Saturation (HLS) definition of this RColor.
Definition: RColor.cxx:85
bool GetRGBFloat(float &r, float &g, float &b) const
Decodes hex color value into RGB - each color component as float from 0.
Definition: RColor.cxx:70
std::string GetHex() const
Return color as hex string like 00FF00.
Definition: RColor.hxx:81
RColor & SetHLS(float hue, float light, float satur)
Set the Red Green and Blue (RGB) values from the Hue, Light, Saturation (HLS).
Definition: RColor.cxx:130
std::array< int, 3 > RGB_t
Definition: RColor.hxx:36