All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Beat Bolli" <bb@drbeat.li>
To: git@vger.kernel.org
Cc: Jeff King <peff@peff.net>, Junio C Hamano <gitster@pobox.com>,
	Beat Bolli <dev+git@drbeat.li>
Subject: [PATCH v2 3/3] color: add support for 12-bit RGB colors
Date: Thu,  2 May 2024 13:03:31 +0200	[thread overview]
Message-ID: <20240502110331.6347-4-dev+git@drbeat.li> (raw)
In-Reply-To: <20240502110331.6347-1-dev+git@drbeat.li>

RGB color parsing currently supports 24-bit values in the form #RRGGBB.

As in Cascading Style Sheets (CSS [1]), also allow to specify an RGB color
using only three digits with #RGB.

In this shortened form, each of the digits is – again, as in CSS –
duplicated to convert the color to 24 bits, e.g. #f1b specifies the same
color as #ff11bb.

In color.h, remove the '0x' prefix in the example to match the actual
syntax.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color

Signed-off-by: Beat Bolli <dev+git@drbeat.li>
---
 Documentation/config.txt |  3 ++-
 color.c                  | 21 ++++++++++++++-------
 color.h                  |  3 ++-
 t/t4026-color.sh         | 10 ++++++----
 4 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 70b448b13262..6f649c997c0f 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -316,7 +316,8 @@ terminals, this is usually not the same as setting to "white black".
 Colors may also be given as numbers between 0 and 255; these use ANSI
 256-color mode (but note that not all terminals may support this).  If
 your terminal supports it, you may also specify 24-bit RGB values as
-hex, like `#ff0ab3`.
+hex, like `#ff0ab3`, or 12-bit RGB values like `#f1b`, which is
+equivalent to the 24-bit color `#ff11bb`.
 +
 The accepted attributes are `bold`, `dim`, `ul`, `blink`, `reverse`,
 `italic`, and `strike` (for crossed-out or "strikethrough" letters).
diff --git a/color.c b/color.c
index f663c06ac4ed..227a5ab2f42e 100644
--- a/color.c
+++ b/color.c
@@ -64,12 +64,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)
+static int get_hex_color(const char **inp, int width, unsigned char *out)
 {
+	const char *in = *inp;
 	unsigned int val;
-	val = (hexval(in[0]) << 4) | hexval(in[1]);
+
+	assert(width == 1 || width == 2);
+	val = (hexval(in[0]) << 4) | hexval(in[width - 1]);
 	if (val & ~0xff)
 		return -1;
+	*inp += width;
 	*out = val;
 	return 0;
 }
@@ -135,11 +139,14 @@ 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)) {
+	/* Try a 24- or 12-bit RGB value prefixed with '#' */
+	if ((len == 7 || len == 4) && name[0] == '#') {
+		int width_per_color = (len == 7) ? 2 : 1;
+		const char *color = name + 1;
+
+		if (!get_hex_color(&color, width_per_color, &out->red) &&
+		    !get_hex_color(&color, width_per_color, &out->green) &&
+		    !get_hex_color(&color, width_per_color, &out->blue)) {
 			out->type = COLOR_RGB;
 			return 0;
 		}
diff --git a/color.h b/color.h
index bb28343be210..7ed259a35bb4 100644
--- a/color.h
+++ b/color.h
@@ -112,7 +112,8 @@ int want_color_fd(int fd, int var);
  * Translate a Git color from 'value' into a string that the terminal can
  * interpret and store it into 'dst'. The Git color values are of the form
  * "foreground [background] [attr]" where fore- and background can be a color
- * name ("red"), a RGB code (#0xFF0000) or a 256-color-mode from the terminal.
+ * name ("red"), a RGB code (#FF0000 or #F00) or a 256-color-mode from the
+ * terminal.
  */
 int color_parse(const char *value, char *dst);
 int color_parse_mem(const char *value, int len, char *dst);
diff --git a/t/t4026-color.sh b/t/t4026-color.sh
index c41138031989..b05f2a9b6075 100755
--- a/t/t4026-color.sh
+++ b/t/t4026-color.sh
@@ -96,8 +96,8 @@ test_expect_success '256 colors' '
 	color "254 bold 255" "[1;38;5;254;48;5;255m"
 '
 
-test_expect_success '24-bit colors' '
-	color "#ff00ff black" "[38;2;255;0;255;40m"
+test_expect_success 'RGB colors' '
+	color "#ff00ff #0f0" "[38;2;255;0;255;48;2;0;255;0m"
 '
 
 test_expect_success '"default" foreground' '
@@ -146,13 +146,15 @@ test_expect_success 'non-hex character in RGB color' '
 	invalid_color "#12x456" &&
 	invalid_color "#123x56" &&
 	invalid_color "#1234x6" &&
-	invalid_color "#12345x"
+	invalid_color "#12345x" &&
+	invalid_color "#x23" &&
+	invalid_color "#1x3" &&
+	invalid_color "#12x"
 '
 
 test_expect_success 'wrong number of letters in RGB color' '
 	invalid_color "#1" &&
 	invalid_color "#23" &&
-	invalid_color "#456" &&
 	invalid_color "#789a" &&
 	invalid_color "#bcdef" &&
 	invalid_color "#1234567"
-- 
2.44.0


  parent reply	other threads:[~2024-05-02 11:04 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-29 16:48 [PATCH 0/3] color: add support for 12-bit RGB colors Beat Bolli
2024-04-29 16:48 ` [PATCH 1/3] t/t4026-color: remove an extra double quote character Beat Bolli
2024-04-30 10:59   ` Jeff King
2024-04-29 16:48 ` [PATCH 2/3] t/t4026-color: add test coverage for invalid RGB colors Beat Bolli
2024-04-29 16:48 ` [PATCH 3/3] color: add support for 12-bit " Beat Bolli
2024-04-29 17:23   ` Junio C Hamano
2024-04-29 17:42     ` Beat Bolli
2024-04-30 10:57   ` Jeff King
2024-04-30 17:31     ` Junio C Hamano
2024-04-30 18:41       ` Junio C Hamano
2024-04-30 19:01         ` Junio C Hamano
2024-05-03 17:47           ` Jeff King
2024-04-29 21:37 ` [PATCH 0/3] " Taylor Blau
2024-05-02 11:03 ` [PATCH v2 " Beat Bolli
2024-05-02 11:03   ` [PATCH v2 1/3] t/t4026-color: remove an extra double quote character Beat Bolli
2024-05-02 11:03   ` [PATCH v2 2/3] t/t4026-color: add test coverage for invalid RGB colors Beat Bolli
2024-05-02 11:03   ` Beat Bolli [this message]
2024-05-02 16:29   ` [PATCH v2 0/3] color: add support for 12-bit " Junio C Hamano
2024-05-03 17:48   ` Jeff King
2024-05-03 19:31     ` Beat Bolli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240502110331.6347-4-dev+git@drbeat.li \
    --to=bb@drbeat.li \
    --cc=dev+git@drbeat.li \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.