26#include <unordered_map>
42float RColor::GetPaletteOrdinal()
const
45 throw std::runtime_error(
"This color does not represent a palette ordinal!");
52 throw std::runtime_error(
"This color does not represent a palette ordinal!");
59 static RColor ParseRGBToColor(
const std::string &strval,
const std::string &
name)
61 auto rgbalen = strval.length() - 1;
62 if (rgbalen != 3 && rgbalen != 4 && rgbalen != 6 && rgbalen != 8) {
64 <<
" with value \"" << strval
65 <<
"\": expect '#' followed by 3, 4, 6 or 8 hex digits (#rgb, #rgba, #rrggbbaa or #rrggbb).";
69 long long rgbaLL = std::stoll(strval.substr(1), &pos, 16);
70 if (pos != 3 && pos != 4 && pos != 6 && pos != 8) {
71 R__ERROR_HERE(
"Graf2d") <<
"Invalid value while parsing default style value for RColor " <<
name
72 <<
" with value \"" << strval
73 <<
"\": expect '#' followed by 3, 4, 6 or 8 hex digits (#rgb, #rgba, #rrggbbaa or #rrggbb).";
77 R__WARNING_HERE(
"Graf2d") <<
"Leftover characters while parsing default style value for RColor " <<
name
78 <<
" with value \"" << strval <<
"\", remainder: \"" << strval.substr(pos - 1) <<
"\"";
81 std::array<float, 4> rgba = {0., 0., 0., 1.};
82 const bool haveAlpha = pos == 4 || pos == 8;
84 const int bitsPerChannel = (pos > 4) ? 8 : 4;
85 const int bitMask = (1 << bitsPerChannel) - 1;
86 const float bitMaskFloat =
static_cast<float>(bitMask);
87 for (
int i = haveAlpha ? 3 : 2; i >= 0; --i) {
88 rgba[i] = (rgbaLL & bitMask) / bitMaskFloat;
89 rgbaLL >>= bitsPerChannel;
94 RColor ParseColorNameToColor(
const std::string &strval,
const std::string &
name)
96 std::string nameLow = strval;
97 std::transform(nameLow.begin(), nameLow.end(), nameLow.begin(),
100 [](
char c) { return std::tolower(static_cast<unsigned char>(c)); });
101 using namespace std::string_literals;
102 static const std::unordered_map<std::string, RColor> mapNamesToColor {
111 auto itMap = mapNamesToColor.find(nameLow);
112 if (itMap == mapNamesToColor.end()) {
114 <<
" with value \"" << strval <<
"\": unknown color name.";
117 return itMap->second;
134 if (strval[0] ==
'#') {
135 return ParseRGBToColor(strval,
name);
137 return ParseColorNameToColor(strval,
name);
147 std::string ret(
"#");
150 auto toHex = [](
int i) {
return i > 9 ?
'A' - 10 + i :
'0' + i; };
151 for (
auto &component: arr) {
152 int comp8Bit =
static_cast<int>(std::round(255 * component));
153 ret.push_back(toHex(comp8Bit / 16));
154 ret.push_back(toHex(comp8Bit % 16));
#define R__ERROR_HERE(GROUP)
#define R__WARNING_HERE(GROUP)
Used to signal that this color shall be automatically chosen by the drawing routines,...
A color: Red|Green|Blue|Alpha, or a position in a RPalette.
static constexpr RGBA kInvisible
bool AssertNotPalettePos() const
throw an exception if the color isn't specified as kRGBA or kAuto, the two cases where asking for RBG...
float GetAlpha() const
For RGBA or auto colors, get the alpha component (0..1).
@ kPalettePos
The color is defined as a value in the RFrame's RPalette.
float GetRed() const
For RGBA or auto colors, get the red component (0..1).
static constexpr AutoTag kAuto
float GetBlue() const
For RGBA or auto colors, get the blue component (0..1).
EKind fKind
How the color is defined.
std::array< float, 4 > RGBA
static constexpr RGBA kWhite
float GetGreen() const
For RGBA or auto colors, get the green component (0..1).
static constexpr RGBA kBlue
static constexpr RGBA kGreen
static constexpr RGBA kBlack
static constexpr RGBA kRed
float fRedOrPalettePos
The "R" in RGBA (0 <= R <= 1), or the palette pos if fKind is kPalettePos.
std::string ToAttributeString(const RColor &val)
Return a std::string representation of a RColor, suitable as input to ColorFromString().
RColor FromAttributeString(const std::string &str, const std::string &name, RColor *)
Initialize a RColor from a string value.
static constexpr double s