From 17a4be26060b00a867cbe54ee906fe03813470ec Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 20 Nov 2014 10:25:39 -0500 Subject: parse_color: support 24-bit RGB values Some terminals (like XTerm) allow full 24-bit RGB color specifications using an extension to the regular ANSI color scheme. Let's allow users to specify hex RGB colors, enabling the all-important feature of hot pink ref decorations: git log --format="%h%C(#ff69b4)%d%C(reset) %s" Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- color.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'color.c') diff --git a/color.c b/color.c index 3afda9d9dc..ae68792923 100644 --- a/color.c +++ b/color.c @@ -32,10 +32,13 @@ struct color { COLOR_UNSPECIFIED = 0, COLOR_NORMAL, COLOR_ANSI, /* basic 0-7 ANSI colors */ - COLOR_256 + COLOR_256, + COLOR_RGB } type; /* The numeric value for ANSI and 256-color modes */ unsigned char value; + /* 24-bit RGB color values */ + unsigned char red, green, blue; }; /* @@ -47,6 +50,16 @@ static int match_word(const char *word, int len, const char *match) return !strncasecmp(word, match, len) && !match[len]; } +static int get_hex_color(const char *in, unsigned char *out) +{ + unsigned int val; + val = (hexval(in[0]) << 4) | hexval(in[1]); + if (val & ~0xff) + return -1; + *out = val; + return 0; +} + static int parse_color(struct color *out, const char *name, int len) { /* Positions in array must match ANSI color codes */ @@ -64,6 +77,16 @@ static int parse_color(struct color *out, const char *name, int len) return 0; } + /* Try a 24-bit RGB value */ + if (len == 7 && name[0] == '#') { + if (!get_hex_color(name + 1, &out->red) && + !get_hex_color(name + 3, &out->green) && + !get_hex_color(name + 5, &out->blue)) { + out->type = COLOR_RGB; + return 0; + } + } + /* Then pick from our human-readable color names... */ for (i = 0; i < ARRAY_SIZE(color_names); i++) { if (match_word(name, len, color_names[i])) { @@ -140,6 +163,10 @@ static char *color_output(char *out, const struct color *c, char type) case COLOR_256: out += sprintf(out, "%c8;5;%d", type, c->value); break; + case COLOR_RGB: + out += sprintf(out, "%c8;2;%d;%d;%d", type, + c->red, c->green, c->blue); + break; } return out; } -- cgit v1.2.3