17#include <unordered_map>
22 : fColors(
points), fInterpolate(interpolate), fNormalized(knownNormalized)
25 throw std::runtime_error(
"Must have at least two points to build a palette!");
29 if (!knownNormalized) {
31 double high =
fColors.back().fOrdinal;
32 double low =
fColors.front().fOrdinal;
33 double prec = (high - low) * 1
e-8;
35 auto reasonablyEqual = [&](
double val,
double expected) ->
bool {
return std::fabs(val - expected) < prec; };
36 fNormalized = reasonablyEqual(low, 0.) && reasonablyEqual(high, 1.);
41std::vector<RPalette::OrdinalAndColor> AddOrdinals(
const std::vector<RColor> &
points)
43 std::vector<RPalette::OrdinalAndColor> ret(
points.size());
45 return {1. / (
points.size() - 1) * (&col -
points.data()), col};
47 std::transform(
points.begin(),
points.end(), ret.begin(), addOneOrdinal);
64 constexpr float epsilon = 1
e-8;
65 if (ordinal <
fColors.front().fOrdinal + epsilon)
68 if (ordinal >
fColors.back().fOrdinal - epsilon)
71 auto iColor2 = std::lower_bound(
fColors.begin(),
fColors.end(), ordinal);
72 auto iColor1 = iColor2 - 1;
74 auto diff1 = ordinal - iColor1->fOrdinal;
75 auto diff2 = iColor2->fOrdinal - ordinal;
77 if ((diff1 < -epsilon) || (diff2 < -epsilon)) {
83 return iColor1->fColor;
86 return iColor2->fColor;
89 auto dist = diff1 + diff2;
90 auto rgba1 = iColor1->fColor.AsRGBA();
91 auto rgba2 = iColor2->fColor.AsRGBA();
92 if ((dist > epsilon) && (rgba1.size() > 2) && (rgba2.size() > 2)) {
93 if (rgba1.size() == 4)
94 rgba2.resize(4, 0xff);
95 else if (rgba2.size() == 4)
96 rgba1.resize(4, 0xff);
98 for (
unsigned i = 0; i < rgba1.size(); ++i)
99 rgba1[i] = (uint8_t) std::lround( (diff2*rgba1[i] + diff1*rgba2[i]) / dist);
102 res.
SetRGB(rgba1[0], rgba1[1], rgba1[2]);
103 if (rgba1.size() == 4)
112 return (diff2 < diff1) ? iColor2->
fColor : iColor1->fColor;
116using GlobalPalettes_t = std::unordered_map<std::string, RPalette>;
117GlobalPalettes_t CreateDefaultPalettes()
119 GlobalPalettes_t ret;
131GlobalPalettes_t &GetGlobalPalettes()
133 static GlobalPalettes_t globalPalettes = CreateDefaultPalettes();
134 return globalPalettes;
140 GetGlobalPalettes()[std::string(
name)] = palette;
145 static const RPalette sNoPaletteWithThatName;
147 auto iGlobalPalette = GetGlobalPalettes().find(std::string(
name));
148 if (iGlobalPalette == GetGlobalPalettes().end())
149 return sNoPaletteWithThatName;
150 return iGlobalPalette->second;
#define R__LOG_ERROR(...)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
static R__DLLEXPORT constexpr RGB_t kRed
void SetRGB(const RGB_t &rgb)
Set r/g/b components of color.
std::string fColor
string representation of color
static R__DLLEXPORT constexpr RGB_t kWhite
void SetAlpha(uint8_t alpha)
Set alpha as value from range 0..255.
static R__DLLEXPORT constexpr RGB_t kBlack
static R__DLLEXPORT constexpr RGB_t kBlue
static void RegisterPalette(std::string_view name, const RPalette &palette)
Register a palette in the set of global palettes, making it available to GetPalette().
RColor GetColor(double ordinal)
Get the color associated with the ordinal value.
std::vector< OrdinalAndColor > fColors
Palette colors: the color points and their ordinal value.
static const RPalette & GetPalette(std::string_view name="")
Get a global palette by name.
bool fNormalized
Whether the palette's ordinal numbers are normalized.
bool IsGradient() const
Whether the palette is a smooth gradient generated by interpolating between the color points.
RLogChannel & GPadLog()
Log channel for GPad diagnostics.
An ordinal value and its associated color.