35static void hsv2rgb(
double h,
double s,
double v,
36 double *r,
double *g,
double *b)
53 t = v * (1 -
s * (1 - f));
91static void rgb2hsv(
double r,
double g,
double b,
92 double *h,
double *
s,
double *v)
95 double rgbmin, rgbmax;
97 double ht = 0.0, st = 0.0;
99 rgbmin = fmin(r, fmin(g, b));
100 rgbmax = fmax(r, fmax(g, b));
103 st = (rgbmax - rgbmin) / rgbmax;
106 rc = (rgbmax - r) / (rgbmax - rgbmin);
107 gc = (rgbmax - g) / (rgbmax - rgbmin);
108 bc = (rgbmax - b) / (rgbmax - rgbmin);
169#define DFLT_SCHEME "X11/"
170#define DFLT_SCHEME_LEN ((sizeof(DFLT_SCHEME)-1)/sizeof(char))
171#define ISNONDFLT(s) ((s) && *(s) && strncasecmp(DFLT_SCHEME, s, DFLT_SCHEME_LEN-1))
176 if (!strcmp(
str,
"black"))
return strdup(
str);
177 if (!strcmp(
str,
"white"))
return strdup(
str);
178 if (!strcmp(
str,
"lightgrey"))
return strdup(
str);
181 const char *
const c2 =
str + 1;
182 const char *
const ss = strchr(c2,
'/');
205 double H,
S,
V,
A, R,
G,
B;
206 unsigned int r, g, b;
208 color->type = target_type;
211 for (; *
str ==
' ';
str++);
217 bool is_rgb = sscanf(p,
"#%2x%2x%2x%2x", &r, &g, &b, &a) >= 3;
219 is_rgb = strlen(p) == 4 && sscanf(p,
"#%1x%1x%1x", &r, &g, &b) == 3;
227 switch (target_type) {
229 R = (double) r / 255.0;
230 G = (double) g / 255.0;
231 B = (double) b / 255.0;
232 A = (double) a / 255.0;
234 color->u.HSVA[0] = H;
240 color->u.rgba[0] = (
unsigned char)r;
241 color->u.rgba[1] = (
unsigned char)g;
242 color->u.rgba[2] = (
unsigned char)b;
243 color->u.rgba[3] = (
unsigned char)a;
246 color->u.rrggbbaa[0] = (int)(r * 65535 / 255);
247 color->u.rrggbbaa[1] = (int)(g * 65535 / 255);
248 color->u.rrggbbaa[2] = (int)(b * 65535 / 255);
249 color->u.rrggbbaa[3] = (int)(a * 65535 / 255);
252 color->u.RGBA[0] = (double) r / 255.0;
253 color->u.RGBA[1] = (double) g / 255.0;
254 color->u.RGBA[2] = (double) b / 255.0;
255 color->u.RGBA[3] = (double) a / 255.0;
277 H = fmax(fmin(H, 1.0), 0.0);
278 S = fmax(fmin(
S, 1.0), 0.0);
279 V = fmax(fmin(
V, 1.0), 0.0);
280 A = fmax(fmin(
A, 1.0), 0.0);
281 switch (target_type) {
283 color->u.HSVA[0] = H;
290 color->u.rgba[0] = (
unsigned char)(R * 255);
291 color->u.rgba[1] = (
unsigned char)(
G * 255);
292 color->u.rgba[2] = (
unsigned char)(
B * 255);
293 color->u.rgba[3] = (
unsigned char)(
A * 255);
297 color->u.rrggbbaa[0] = (int) (R * 65535);
298 color->u.rrggbbaa[1] = (int) (
G * 65535);
299 color->u.rrggbbaa[2] = (int) (
B * 65535);
300 color->u.rrggbbaa[3] = (int) (
A * 65535);
304 color->u.RGBA[0] = R;
331 switch (target_type) {
333 color->u.HSVA[0] = (double)known->
h / 255.0;
334 color->u.HSVA[1] = (double)known->
s / 255.0;
335 color->u.HSVA[2] = (double)known->
v / 255.0;
336 color->u.HSVA[3] = (double)known->
a / 255.0;
339 color->u.rgba[0] = known->
r;
340 color->u.rgba[1] = known->
g;
341 color->u.rgba[2] = known->
b;
342 color->u.rgba[3] = known->
a;
345 color->u.rrggbbaa[0] = known->
r * 65535 / 255;
346 color->u.rrggbbaa[1] = known->
g * 65535 / 255;
347 color->u.rrggbbaa[2] = known->
b * 65535 / 255;
348 color->u.rrggbbaa[3] = known->
a * 65535 / 255;
351 color->u.RGBA[0] = known->
r / 255.0;
352 color->u.RGBA[1] = known->
g / 255.0;
353 color->u.RGBA[2] = known->
b / 255.0;
354 color->u.RGBA[3] = known->
a / 255.0;
368 switch (target_type) {
371 color->u.HSVA[3] = 1.0;
375 color->u.rgba[3] = 255;
378 color->u.rrggbbaa[0] =
color->u.rrggbbaa[1] =
color->u.rrggbbaa[2] = 0;
379 color->u.rrggbbaa[3] = 65535;
383 color->u.RGBA[3] = 1.0;
static void agxbfree(agxbuf *xb)
free any malloced resources
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
static WUR char * agxbuse(agxbuf *xb)
static int agxbputc(agxbuf *xb, char c)
add character to buffer
Memory allocation wrappers that exit on failure.
static char * gv_strdup(const char *original)
#define COLOR_MALLOC_FAIL
require define api prefix
replacements for ctype.h functions
static bool gv_isdigit(int c)
Arithmetic helper functions.
static bool is_exactly_equal(double a, double b)
are two values precisely the same?
static void color(Agraph_t *g)
textitem scanner parser str
static char * resolveColor(const char *str)
static char * fullColor(agxbuf *xb, const char *prefix, const char *str)
static void hsv2rgb(double h, double s, double v, double *r, double *g, double *b)
char * setColorScheme(const char *s)
static void rgb2hsv(double r, double g, double b, double *h, double *s, double *v)
static char * colorscheme
static bool on_heap(const subtree_t *tree)
is this subtree stored in an STheap?
static char * canon(graph_t *g, char *s)
platform abstraction for case-insensitive string functions