unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
@ 2019-06-20 11:22 Pip Cet
  2019-06-21  1:54 ` Richard Stallman
  0 siblings, 1 reply; 20+ messages in thread
From: Pip Cet @ 2019-06-20 11:22 UTC (permalink / raw)
  To: 36304

This is a request for an incompatible change, which I think will
improve some matters significantly:

The Web convention, used by HTML and SVG, is that #fff is parsed as
#ffffff, and represents "white". The X convention, discouraged for
years, is to accept #fff as shorthand for #f0f0f0, and #ffffff as
shorthand for #ff00ff00ff00, with no way of specifying the whitest
color as six (or three) hex digits.

We're still using the X convention. It's time to switch. The HTML
convention is what virtually everyone would expect these days, it
allows specifying "white" concisely, and it's what we use in some
contexts, such as when rendering SVGs.

Not fixing this would result in somewhat hard-to-track-down color bugs
all over the place, particularly when combining images and text or
using non-X window systems or non-8-bit color depths (again, "#ffffff"
isn't the same as "white" on those!)

There's no reason, as far as I can see, to burden everyone with a
deficiency of one specific graphics backend, in perpetuity,
particularly since the colors will stay similar but not quite the
same.

This issue was discussed years ago as bug #8402, so feel free to mark
this as a duplicate if it helps.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-20 11:22 bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors Pip Cet
@ 2019-06-21  1:54 ` Richard Stallman
  2019-06-22 11:23   ` Pip Cet
  0 siblings, 1 reply; 20+ messages in thread
From: Richard Stallman @ 2019-06-21  1:54 UTC (permalink / raw)
  To: Pip Cet; +Cc: 36304

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > We're still using the X convention. It's time to switch. The HTML
  > convention is what virtually everyone would expect these days, it
  > allows specifying "white" concisely, and it's what we use in some
  > contexts, such as when rendering SVGs.

It seems plausible to me, speaking as a non-expert.

-- 
Dr Richard Stallman
President, Free Software Foundation (https://gnu.org, https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)







^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-21  1:54 ` Richard Stallman
@ 2019-06-22 11:23   ` Pip Cet
  2019-06-22 11:40     ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Pip Cet @ 2019-06-22 11:23 UTC (permalink / raw)
  To: rms; +Cc: 36304

[-- Attachment #1: Type: text/plain, Size: 2616 bytes --]

On Fri, Jun 21, 2019 at 1:54 AM Richard Stallman <rms@gnu.org> wrote:
>   > We're still using the X convention. It's time to switch. The HTML
>   > convention is what virtually everyone would expect these days, it
>   > allows specifying "white" concisely, and it's what we use in some
>   > contexts, such as when rendering SVGs.
>
> It seems plausible to me, speaking as a non-expert.

Here's a patch. I've read the documentation and it appears already to
have been updated by someone so it no longer links to the X
documentation.

* src/xterm.c (x_parse_color): Translate #RGB notation to rgb:R/G/B
  notation, which X handles slightly differently.
---
 src/xterm.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index 1acff2af0d..614774f6bc 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2381,6 +2381,8 @@ x_query_frame_background_color (struct frame *f,
XColor *bgcolor)
   x_query_colors (f, bgcolor, 1);
 }

+#define HEX_COLOR_NAME_LENGTH 32
+
 /* On frame F, translate the color name to RGB values.  Use cached
    information, if possible.

@@ -2398,9 +2400,35 @@ x_query_frame_background_color (struct frame
*f, XColor *bgcolor)

   if (color_name[0] == '#')
     {
-      /* The hex form is parsed directly by XParseColor without
+      /* Don't pass #RGB strings directly to XParseColor, because that
+     follows the old convention of zero-extending each channel
+     value: #f00 means #f00000. We want the new convention of
+     scaling channel values, so #f00 means #ff0000.
+
+     So we translate #f00 to rgb:f/0/0, which X handles
+     differently. */
+      char rgb_color_name[HEX_COLOR_NAME_LENGTH];
+      int len = strlen (color_name);
+      int digits_per_channel;
+      if (len == 4)
+    digits_per_channel = 1;
+      else if (len == 7)
+    digits_per_channel = 2;
+      else if (len == 10)
+    digits_per_channel = 3;
+      else if (len == 13)
+    digits_per_channel = 4;
+      else
+    return 0;
+
+      snprintf (rgb_color_name, sizeof rgb_color_name, "rgb:%.*s/%.*s/%.*s",
+        digits_per_channel, color_name + 1,
+        digits_per_channel, color_name + digits_per_channel + 1,
+        digits_per_channel, color_name + 2 * digits_per_channel + 1);
+
+      /* The rgb form is parsed directly by XParseColor without
      talking to the X server.  No need for caching.  */
-      return XParseColor (dpy, cmap, color_name, color);
+      return XParseColor (dpy, cmap, rgb_color_name, color);
     }

   for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
-- 
2.20.1

[-- Attachment #2: 0001-Change-color-convention-so-f00-means-the-same-as-ff0.patch --]
[-- Type: text/x-patch, Size: 2255 bytes --]

From b603f409f2f5d1ec7c1a6bcfd0cb27ea2565026e Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Sat, 22 Jun 2019 11:04:20 +0000
Subject: [PATCH] Change color convention so #f00 means the same as #ff0000.

* src/xterm.c (x_parse_color): Translate #RGB notation to rgb:R/G/B
  notation, which X handles slightly differently.
---
 src/xterm.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index 1acff2af0d..614774f6bc 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2381,6 +2381,8 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
   x_query_colors (f, bgcolor, 1);
 }
 
+#define HEX_COLOR_NAME_LENGTH 32
+
 /* On frame F, translate the color name to RGB values.  Use cached
    information, if possible.
 
@@ -2398,9 +2400,35 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
 
   if (color_name[0] == '#')
     {
-      /* The hex form is parsed directly by XParseColor without
+      /* Don't pass #RGB strings directly to XParseColor, because that
+	 follows the old convention of zero-extending each channel
+	 value: #f00 means #f00000. We want the new convention of
+	 scaling channel values, so #f00 means #ff0000.
+
+	 So we translate #f00 to rgb:f/0/0, which X handles
+	 differently. */
+      char rgb_color_name[HEX_COLOR_NAME_LENGTH];
+      int len = strlen (color_name);
+      int digits_per_channel;
+      if (len == 4)
+	digits_per_channel = 1;
+      else if (len == 7)
+	digits_per_channel = 2;
+      else if (len == 10)
+	digits_per_channel = 3;
+      else if (len == 13)
+	digits_per_channel = 4;
+      else
+	return 0;
+
+      snprintf (rgb_color_name, sizeof rgb_color_name, "rgb:%.*s/%.*s/%.*s",
+		digits_per_channel, color_name + 1,
+		digits_per_channel, color_name + digits_per_channel + 1,
+		digits_per_channel, color_name + 2 * digits_per_channel + 1);
+
+      /* The rgb form is parsed directly by XParseColor without
 	 talking to the X server.  No need for caching.  */
-      return XParseColor (dpy, cmap, color_name, color);
+      return XParseColor (dpy, cmap, rgb_color_name, color);
     }
 
   for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-22 11:23   ` Pip Cet
@ 2019-06-22 11:40     ` Eli Zaretskii
  2019-06-22 12:13       ` Pip Cet
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2019-06-22 11:40 UTC (permalink / raw)
  To: Pip Cet; +Cc: rms, 36304

> From: Pip Cet <pipcet@gmail.com>
> Date: Sat, 22 Jun 2019 11:23:35 +0000
> Cc: 36304@debbugs.gnu.org
> 
> Here's a patch. I've read the documentation and it appears already to
> have been updated by someone so it no longer links to the X
> documentation.
> 
> * src/xterm.c (x_parse_color): Translate #RGB notation to rgb:R/G/B
>   notation, which X handles slightly differently.

Can this change be limited to xterm.c alone?  I think we assume this
color handling also in xfaces.c and in lisp/term/tty-colors.el (and
perhaps elsewhere, where TTY colors are used/defined).  There's also
lisp/color.el.

Am I missing something?





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-22 11:40     ` Eli Zaretskii
@ 2019-06-22 12:13       ` Pip Cet
  2019-06-22 12:35         ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Pip Cet @ 2019-06-22 12:13 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rms, 36304

On Sat, Jun 22, 2019 at 11:40 AM Eli Zaretskii <eliz@gnu.org> wrote:
> > From: Pip Cet <pipcet@gmail.com>
> > Date: Sat, 22 Jun 2019 11:23:35 +0000
> > Cc: 36304@debbugs.gnu.org
> >
> > Here's a patch. I've read the documentation and it appears already to
> > have been updated by someone so it no longer links to the X
> > documentation.
> >
> > * src/xterm.c (x_parse_color): Translate #RGB notation to rgb:R/G/B
> >   notation, which X handles slightly differently.
>
> Can this change be limited to xterm.c alone?

It'd leave us inconsistently still using the X standard in some
places, but at first glance they appear to be documented to use the X
standard, so maybe that's not wrong.

> I think we assume this color handling also in xfaces.c

Only via tty-color-standard-values, as far as I can see.

> and in lisp/term/tty-colors.el (and perhaps elsewhere, where TTY colors are used/defined).

tty-color-standard-values is documented to use the X convention, and
it does. tty-color-desc is documented to return approximate results,
and it does; and it's only used for text terminals, right?

>  There's also lisp/color.el.

Anything in particular? As far as I can tell, the functions work
properly using the new convention with this patch, although I am sure
there are places that fail to deal with the 65280-as-maximum
convention that nsfns.m uses.

> Am I missing something?

I don't think so, but I don't see anything, so far, that needs
changing. I'm almost certain that some more places will need changing,
but how do we find them?





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-22 12:13       ` Pip Cet
@ 2019-06-22 12:35         ` Eli Zaretskii
  2019-06-22 14:41           ` Pip Cet
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2019-06-22 12:35 UTC (permalink / raw)
  To: Pip Cet; +Cc: rms, 36304

> From: Pip Cet <pipcet@gmail.com>
> Date: Sat, 22 Jun 2019 12:13:20 +0000
> Cc: rms@gnu.org, 36304@debbugs.gnu.org
> 
> On Sat, Jun 22, 2019 at 11:40 AM Eli Zaretskii <eliz@gnu.org> wrote:
> > > From: Pip Cet <pipcet@gmail.com>
> > > Date: Sat, 22 Jun 2019 11:23:35 +0000
> > > Cc: 36304@debbugs.gnu.org
> > >
> > > Here's a patch. I've read the documentation and it appears already to
> > > have been updated by someone so it no longer links to the X
> > > documentation.
> > >
> > > * src/xterm.c (x_parse_color): Translate #RGB notation to rgb:R/G/B
> > >   notation, which X handles slightly differently.
> >
> > Can this change be limited to xterm.c alone?
> 
> It'd leave us inconsistently still using the X standard in some
> places, but at first glance they appear to be documented to use the X
> standard, so maybe that's not wrong.

I'm not sure I understand what you mean by "the X standard".  Is that
the old or the new convention of how to interpret a given #RGB value?

> > I think we assume this color handling also in xfaces.c
> 
> Only via tty-color-standard-values, as far as I can see.
> 
> > and in lisp/term/tty-colors.el (and perhaps elsewhere, where TTY colors are used/defined).
> 
> tty-color-standard-values is documented to use the X convention, and
> it does. tty-color-desc is documented to return approximate results,
> and it does;

So we would need to change that as well, no?

> and it's only used for text terminals, right?

Yes, but we nowadays support text terminals that can display 24-bit
colors, and having their colors display differently from the same
color on X is just asking for bug reports.

> >  There's also lisp/color.el.
> 
> Anything in particular? As far as I can tell, the functions work
> properly using the new convention with this patch, although I am sure
> there are places that fail to deal with the 65280-as-maximum
> convention that nsfns.m uses.

If you convert a color to RGB and then back, is the result equal to
what you started with?  E.g., see

  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=29456#11

Or what about issues discussed in bug#25890 and bug#24273?

> > Am I missing something?
> 
> I don't think so, but I don't see anything, so far, that needs
> changing. I'm almost certain that some more places will need changing,
> but how do we find them?

By searching the code for "rgb" (case-insensitively)?  E.g., what does
parse_rgb_list return when the RGB value doesn't specify all the bits?
what about color_distance? etc.

My point is that the "old" interpretation of the #RGB values might
have seeped into more places than just that one xterm.c function, and
if we are going to change the interpretation, we should make sure we
do that consistently in all the affected places.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-22 12:35         ` Eli Zaretskii
@ 2019-06-22 14:41           ` Pip Cet
  2019-06-22 15:05             ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Pip Cet @ 2019-06-22 14:41 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rms, 36304

On Sat, Jun 22, 2019 at 12:36 PM Eli Zaretskii <eliz@gnu.org> wrote:
> > From: Pip Cet <pipcet@gmail.com>
> > Date: Sat, 22 Jun 2019 12:13:20 +0000
> > Cc: rms@gnu.org, 36304@debbugs.gnu.org
> >
> > It'd leave us inconsistently still using the X standard in some
> > places, but at first glance they appear to be documented to use the X
> > standard, so maybe that's not wrong.
>
> I'm not sure I understand what you mean by "the X standard".  Is that
> the old or the new convention of how to interpret a given #RGB value?

The old convention, of interpreting #f00 as #f00000.

> > > I think we assume this color handling also in xfaces.c
> >
> > Only via tty-color-standard-values, as far as I can see.
> >
> > > and in lisp/term/tty-colors.el (and perhaps elsewhere, where TTY colors are used/defined).
> >
> > tty-color-standard-values is documented to use the X convention, and
> > it does. tty-color-desc is documented to return approximate results,
> > and it does;
>
> So we would need to change that as well, no?

We could. I don't have an opinion either way.

> > and it's only used for text terminals, right?
>
> Yes, but we nowadays support text terminals that can display 24-bit
> colors, and having their colors display differently from the same
> color on X is just asking for bug reports.

Okay, let's change it, then.

> > >  There's also lisp/color.el.
> >
> > Anything in particular? As far as I can tell, the functions work
> > properly using the new convention with this patch, although I am sure
> > there are places that fail to deal with the 65280-as-maximum
> > convention that nsfns.m uses.
>
> If you convert a color to RGB and then back, is the result equal to
> what you started with?  E.g., see

On my system, yes.

>   https://debbugs.gnu.org/cgi/bugreport.cgi?bug=29456#11
>
> Or what about issues discussed in bug#25890 and bug#24273?

Thanks for pointing me to those. I don't think the situation gets any
worse for those, at least.

> > > Am I missing something?
> >
> > I don't think so, but I don't see anything, so far, that needs
> > changing. I'm almost certain that some more places will need changing,
> > but how do we find them?
>
> By searching the code for "rgb" (case-insensitively)?

I've done that, now. No new problems that I've seen, though
gtkutil.c's xg_get_pixbuf_from_surface confuses me.

> E.g., what does
> parse_rgb_list return when the RGB value doesn't specify all the bits?
> what about color_distance? etc.

Those two are fine, as far as I can see; I know that you meant to
provide only examples, but if you have any hints for finding places
that need changing, please let me know.

> My point is that the "old" interpretation of the #RGB values might
> have seeped into more places than just that one xterm.c function, and
> if we are going to change the interpretation, we should make sure we
> do that consistently in all the affected places.

I don't think there's a way we can be absolutely certain to have fixed
every potential problem, but we should try, yes.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-22 14:41           ` Pip Cet
@ 2019-06-22 15:05             ` Eli Zaretskii
  2019-06-22 15:33               ` Pip Cet
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2019-06-22 15:05 UTC (permalink / raw)
  To: Pip Cet; +Cc: rms, 36304

> From: Pip Cet <pipcet@gmail.com>
> Date: Sat, 22 Jun 2019 14:41:30 +0000
> Cc: rms@gnu.org, 36304@debbugs.gnu.org
> 
> > > > I think we assume this color handling also in xfaces.c
> > >
> > > Only via tty-color-standard-values, as far as I can see.
> > >
> > > > and in lisp/term/tty-colors.el (and perhaps elsewhere, where TTY colors are used/defined).
> > >
> > > tty-color-standard-values is documented to use the X convention, and
> > > it does. tty-color-desc is documented to return approximate results,
> > > and it does;
> >
> > So we would need to change that as well, no?
> 
> We could. I don't have an opinion either way.
> 
> > > and it's only used for text terminals, right?
> >
> > Yes, but we nowadays support text terminals that can display 24-bit
> > colors, and having their colors display differently from the same
> > color on X is just asking for bug reports.
> 
> Okay, let's change it, then.

Thanks.

> > My point is that the "old" interpretation of the #RGB values might
> > have seeped into more places than just that one xterm.c function, and
> > if we are going to change the interpretation, we should make sure we
> > do that consistently in all the affected places.
> 
> I don't think there's a way we can be absolutely certain to have fixed
> every potential problem, but we should try, yes.

Of course.  I only meant we should fix those we do find.  If the only
one is in tty-colors.el, then I guess that's it.  The rest will have
to be uncovered as people try using the new code.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-22 15:05             ` Eli Zaretskii
@ 2019-06-22 15:33               ` Pip Cet
  2019-06-28  8:12                 ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Pip Cet @ 2019-06-22 15:33 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rms, 36304

[-- Attachment #1: Type: text/plain, Size: 699 bytes --]

On Sat, Jun 22, 2019 at 3:05 PM Eli Zaretskii <eliz@gnu.org> wrote:
> > From: Pip Cet <pipcet@gmail.com>
> > Date: Sat, 22 Jun 2019 14:41:30 +0000
> > Cc: rms@gnu.org, 36304@debbugs.gnu.org
> > > > and it's only used for text terminals, right?
> > >
> > > Yes, but we nowadays support text terminals that can display 24-bit
> > > colors, and having their colors display differently from the same
> > > color on X is just asking for bug reports.
> > Okay, let's change it, then.
> Thanks.

While I was there, I've also made it accept upper-case hex digits
(previously, #0F0 was accepted but #F00 wasn't), and fixed the ranges
so rgb:f/f/f translates to (65535 65535 65535) rather than (255 255
255).

[-- Attachment #2: 0001-Use-CSS-convention-for-interpreting-colors.patch --]
[-- Type: text/x-patch, Size: 4090 bytes --]

From 6973cd4bc54aee7352b99afc774ee82af3c9482f Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Sat, 22 Jun 2019 15:31:00 +0000
Subject: [PATCH] Use CSS convention for interpreting colors.

* lisp/term/tty-colors.el (tty-color-standard-values): Change
  interpretation of #RGB strings to match CSS rather than X
  conventions. Allow upper-case digits. Fix rgb:R/G/B interpretation.
---
 lisp/term/tty-colors.el | 50 ++++++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el
index 307586f221..07bf47c042 100644
--- a/lisp/term/tty-colors.el
+++ b/lisp/term/tty-colors.el
@@ -919,40 +919,44 @@ tty-color-standard-values
 The result is a list of integer RGB values--(RED GREEN BLUE).
 These values range from 0 to 65535; white is (65535 65535 65535).
 
-The returned value reflects the standard X definition of COLOR,
+The returned value reflects the standard Emacs definition of COLOR,
 regardless of whether the terminal can display it, so the return value
 should be the same regardless of what display is being used."
   (let ((len (length color)))
-    (cond ((and (>= len 4) ;; X-style "#XXYYZZ" color spec
+    (cond ((and (>= len 4) ;; "#XXYYZZ" color spec
 		(eq (aref color 0) ?#)
 		(member (aref color 1)
 			'(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
-			     ?a ?b ?c ?d ?e ?f)))
+			     ?a ?b ?c ?d ?e ?f
+                             ?A ?B ?C ?D ?E ?F)))
 	   ;; Translate the string "#XXYYZZ" into a list
-	   ;; of numbers (XX YY ZZ).  If the primary colors
-	   ;; are specified with less than 4 hex digits,
-	   ;; the used digits represent the most significant
-	   ;; bits of the value (e.g. #XYZ = #X000Y000Z000).
+	   ;; of numbers (XX YY ZZ).  If fewer than 4 hex
+	   ;; digits are used, they represent the fraction
+	   ;; of the maximum value (#XYZ = #XXXXYYYYZZZZ).
 	   (let* ((ndig (/ (- len 1) 3))
+		  (maxval (1- (ash 1 (* 4 ndig))))
 		  (i1 1)
 		  (i2 (+ i1 ndig))
 		  (i3 (+ i2 ndig)))
 	     (list
-	      (ash
-	       (string-to-number (substring color i1 i2) 16)
-	       (* 4 (- 4 ndig)))
-	      (ash
-	       (string-to-number (substring color i2 i3) 16)
-	       (* 4 (- 4 ndig)))
-	      (ash
-	       (string-to-number (substring color i3) 16)
-	       (* 4 (- 4 ndig))))))
-	  ((and (>= len 9) ;; X-style RGB:xx/yy/zz color spec
+	      (/ (* (string-to-number
+		     (substring color i1 i2) 16)
+		    65535)
+		 maxval)
+	      (/ (* (string-to-number
+		     (substring color i2 i3) 16)
+		    65535)
+		 maxval)
+	      (/ (* (string-to-number
+		     (substring color i3) 16)
+		    65535)
+		 maxval))))
+	  ((and (>= len 9) ;; X-style rgb:xx/yy/zz color spec
 		(string= (substring color 0 4) "rgb:"))
-	   ;; Translate the string "RGB:XX/YY/ZZ" into a list
+	   ;; Translate the string "rgb:XX/YY/ZZ" into a list
 	   ;; of numbers (XX YY ZZ).  If fewer than 4 hex
 	   ;; digits are used, they represent the fraction
-	   ;; of the maximum value (RGB:X/Y/Z = #XXXXYYYYZZZZ).
+	   ;; of the maximum value (rgb:X/Y/Z = #XXXXYYYYZZZZ).
 	   (let* ((ndig (/ (- len 3) 3))
 		  (maxval (1- (ash 1 (* 4 (- ndig 1)))))
 		  (i1 4)
@@ -961,15 +965,15 @@ tty-color-standard-values
 	     (list
 	      (/ (* (string-to-number
 		     (substring color i1 (- i2 1)) 16)
-		    255)
+		    65535)
 		 maxval)
 	      (/ (* (string-to-number
 		     (substring color i2 (- i3 1)) 16)
-		    255)
+		    65535)
 		 maxval)
 	      (/ (* (string-to-number
 		     (substring color i3) 16)
-		    255)
+		    65535)
 		 maxval))))
 	  (t
 	   (cdr (assoc color color-name-rgb-alist))))))
@@ -978,7 +982,7 @@ tty-color-translate
   "Given a color COLOR, return the index of the corresponding TTY color.
 
 COLOR must be a string that is either the color's name, or its X-style
-specification like \"#RRGGBB\" or \"RGB:rr/gg/bb\", where each primary.
+specification like \"#RRGGBB\" or \"rgb:RR/GG/BB\", where each primary.
 color can be given with 1 to 4 hex digits.
 
 If COLOR is a color name that is found among supported colors in
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-22 15:33               ` Pip Cet
@ 2019-06-28  8:12                 ` Eli Zaretskii
  2019-06-28  9:28                   ` Pip Cet
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2019-06-28  8:12 UTC (permalink / raw)
  To: Pip Cet; +Cc: rms, 36304

> From: Pip Cet <pipcet@gmail.com>
> Date: Sat, 22 Jun 2019 15:33:14 +0000
> Cc: rms@gnu.org, 36304@debbugs.gnu.org
> 
> > > > Yes, but we nowadays support text terminals that can display 24-bit
> > > > colors, and having their colors display differently from the same
> > > > color on X is just asking for bug reports.
> > > Okay, let's change it, then.
> > Thanks.
> 
> While I was there, I've also made it accept upper-case hex digits
> (previously, #0F0 was accepted but #F00 wasn't), and fixed the ranges
> so rgb:f/f/f translates to (65535 65535 65535) rather than (255 255
> 255).

Thanks.

A few comments:

> * lisp/term/tty-colors.el (tty-color-standard-values): Change
>   interpretation of #RGB strings to match CSS rather than X
>   conventions. Allow upper-case digits. Fix rgb:R/G/B interpretation.

Our convention is to use two spaces between sentences in documentation
and comments.  That includes log entries.

> -The returned value reflects the standard X definition of COLOR,
> +The returned value reflects the standard Emacs definition of COLOR,

This should include some reference to where "standard Emacs
definition" of colors can be found.  For X, we didn't need that,
because X docs is not our responsibility, and there's a plenty out
there.

> -    (cond ((and (>= len 4) ;; X-style "#XXYYZZ" color spec
> +    (cond ((and (>= len 4) ;; "#XXYYZZ" color spec

Is #XXYYZZ no longer considered "X-style"?

>  	   ;; Translate the string "#XXYYZZ" into a list
> -	   ;; of numbers (XX YY ZZ).  If the primary colors
> -	   ;; are specified with less than 4 hex digits,
> -	   ;; the used digits represent the most significant
> -	   ;; bits of the value (e.g. #XYZ = #X000Y000Z000).
> +	   ;; of numbers (XX YY ZZ).  If fewer than 4 hex
> +	   ;; digits are used, they represent the fraction
> +	   ;; of the maximum value (#XYZ = #XXXXYYYYZZZZ).

IMO, this part makes the text confusing: "4 hex digits" can be
interpreted as referring to the entire XXYYZZ thing, whereas you
really mean the number of digits for each primary color R, G, and B.
Also, I envision people who will struggle with the exact meaning of
"the fraction of the maximum value".  Where the previous text and the
example could be easily generalized to understand how we interpret
#ABCDEF, the proposed text, by giving an example only for a single hex
digit per primary color, does not lend itself to such an easy
generalization.

Finally, this is just part of the patch, isn't it?  The xterm.c part
is not here, and neither are the documentation parts.  Did I miss
something?





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-28  8:12                 ` Eli Zaretskii
@ 2019-06-28  9:28                   ` Pip Cet
  2019-06-28  9:42                     ` Robert Pluim
  2019-06-28 12:33                     ` Eli Zaretskii
  0 siblings, 2 replies; 20+ messages in thread
From: Pip Cet @ 2019-06-28  9:28 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rms, 36304

[-- Attachment #1: Type: text/plain, Size: 1411 bytes --]

On Fri, Jun 28, 2019 at 8:13 AM Eli Zaretskii <eliz@gnu.org> wrote:
> > While I was there, I've also made it accept upper-case hex digits
> > (previously, #0F0 was accepted but #F00 wasn't), and fixed the ranges
> > so rgb:f/f/f translates to (65535 65535 65535) rather than (255 255
> > 255).
>
> Thanks.

Thanks for the very patient review. Sorry for making so many mistakes.

> > -    (cond ((and (>= len 4) ;; X-style "#XXYYZZ" color spec
> > +    (cond ((and (>= len 4) ;; "#XXYYZZ" color spec
>
> Is #XXYYZZ no longer considered "X-style"?

I would say no, since X's interpretation of #f00 is a little different
from the HTML/CSS/SVG interpretation.

> >          ;; Translate the string "#XXYYZZ" into a list
> > -        ;; of numbers (XX YY ZZ).  If the primary colors
> > -        ;; are specified with less than 4 hex digits,
> > -        ;; the used digits represent the most significant
> > -        ;; bits of the value (e.g. #XYZ = #X000Y000Z000).
> > +        ;; of numbers (XX YY ZZ).  If fewer than 4 hex
> > +        ;; digits are used, they represent the fraction
> > +        ;; of the maximum value (#XYZ = #XXXXYYYYZZZZ).
>
> IMO, this part makes the text confusing:

Thanks, you're absolutely right.

> Finally, this is just part of the patch, isn't it?  The xterm.c part
> is not here, and neither are the documentation parts.  Did I miss
> something?

Complete updated patch attached.

[-- Attachment #2: 0001-Use-the-CSS-convention-for-RGB-colors-bug-36304.patch --]
[-- Type: text/x-patch, Size: 8339 bytes --]

From 6387501e1252c77987b07fd38d54578badfe81af Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Fri, 28 Jun 2019 09:23:19 +0000
Subject: [PATCH] Use the CSS convention for #RGB colors (bug#36304).

* src/xterm.c (x_parse_color): Change interpretation of #RGB color
triplets to match CSS rather than X conventions.

* lisp/term/tty-colors.el (tty-color-standard-values): Change
interpretation of #RGB color triplets to match CSS rather than X
conventions.  Allow upper-case digits.  Fix rgb:R/G/B
interpretation.

* doc/emacs/display.texi (Colors): Specify the convention used for
"#RGB" color triplets.
---
 doc/emacs/display.texi  | 18 ++++++++-----
 lisp/term/tty-colors.el | 60 ++++++++++++++++++++++-------------------
 src/xterm.c             | 32 ++++++++++++++++++++--
 3 files changed, 73 insertions(+), 37 deletions(-)

diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index f92f7529ea..735f96fda4 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -556,14 +556,14 @@ Faces
 
 @node Colors
 @section Colors for Faces
-@cindex color name
-@cindex RGB triplet
 
   Faces can have various foreground and background colors.  When you
 specify a color for a face---for instance, when customizing the face
 (@pxref{Face Customization})---you can use either a @dfn{color name}
 or an @dfn{RGB triplet}.
 
+@subsection Color Names
+@cindex color name
 @findex list-colors-display
 @vindex list-colors-sort
   A color name is a pre-defined name, such as @samp{dark orange} or
@@ -578,12 +578,16 @@ Colors
 text terminals; if a face is given a color specified by an X11 color
 name, it is displayed using the closest-matching terminal color.
 
+@subsection RGB Triplets
+@cindex RGB triplet
   An RGB triplet is a string of the form @samp{#RRGGBB}.  Each of the
-R, G, and B components is a hexadecimal number specifying the
-component's relative intensity, one to four digits long (usually two
-digits are used).  The components must have the same number of digits.
-For hexadecimal values A to F, either upper or lower case are
-acceptable.
+primary color components is represented by a hexadecimal number
+between @samp{00} (intensity 0) and @samp{FF} (the maximum intensity).
+It is also possible to use one, three, or four hex digits for each
+component, so @samp{red} can be represented as @samp{#F00},
+@samp{#fff000000}, or @samp{#ffff00000000}.  The components must have
+the same number of digits.  For hexadecimal values A to F, either
+upper or lower case are acceptable.
 
   The @kbd{M-x list-colors-display} command also shows the equivalent
 RGB triplet for each named color.  For instance, @samp{medium sea
diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el
index 307586f221..db950d4eb4 100644
--- a/lisp/term/tty-colors.el
+++ b/lisp/term/tty-colors.el
@@ -919,40 +919,44 @@ tty-color-standard-values
 The result is a list of integer RGB values--(RED GREEN BLUE).
 These values range from 0 to 65535; white is (65535 65535 65535).
 
-The returned value reflects the standard X definition of COLOR,
-regardless of whether the terminal can display it, so the return value
-should be the same regardless of what display is being used."
+The returned value reflects the standard Emacs definition of
+COLOR (see `Colors for Faces' in the Emacs manual), regardless of
+whether the terminal can display it, so the return value should
+be the same regardless of what display is being used."
   (let ((len (length color)))
-    (cond ((and (>= len 4) ;; X-style "#XXYYZZ" color spec
+    (cond ((and (>= len 4) ;; "#XXYYZZ" color spec
 		(eq (aref color 0) ?#)
 		(member (aref color 1)
 			'(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
-			     ?a ?b ?c ?d ?e ?f)))
-	   ;; Translate the string "#XXYYZZ" into a list
-	   ;; of numbers (XX YY ZZ).  If the primary colors
-	   ;; are specified with less than 4 hex digits,
-	   ;; the used digits represent the most significant
-	   ;; bits of the value (e.g. #XYZ = #X000Y000Z000).
+			     ?a ?b ?c ?d ?e ?f
+                             ?A ?B ?C ?D ?E ?F)))
+	   ;; Translate the string "#XXYYZZ" into a list of numbers
+	   ;; (XX YY ZZ), scaling each to the {0..65535} range.  This
+	   ;; follows the CSS color convention, where both "#fff" and
+	   ;; "#ffffff" represent the same color, white.
 	   (let* ((ndig (/ (- len 1) 3))
+		  (maxval (1- (ash 1 (* 4 ndig))))
 		  (i1 1)
 		  (i2 (+ i1 ndig))
 		  (i3 (+ i2 ndig)))
 	     (list
-	      (ash
-	       (string-to-number (substring color i1 i2) 16)
-	       (* 4 (- 4 ndig)))
-	      (ash
-	       (string-to-number (substring color i2 i3) 16)
-	       (* 4 (- 4 ndig)))
-	      (ash
-	       (string-to-number (substring color i3) 16)
-	       (* 4 (- 4 ndig))))))
-	  ((and (>= len 9) ;; X-style RGB:xx/yy/zz color spec
+	      (/ (* (string-to-number
+		     (substring color i1 i2) 16)
+		    65535)
+		 maxval)
+	      (/ (* (string-to-number
+		     (substring color i2 i3) 16)
+		    65535)
+		 maxval)
+	      (/ (* (string-to-number
+		     (substring color i3) 16)
+		    65535)
+		 maxval))))
+	  ((and (>= len 9) ;; X-style rgb:xx/yy/zz color spec
 		(string= (substring color 0 4) "rgb:"))
-	   ;; Translate the string "RGB:XX/YY/ZZ" into a list
-	   ;; of numbers (XX YY ZZ).  If fewer than 4 hex
-	   ;; digits are used, they represent the fraction
-	   ;; of the maximum value (RGB:X/Y/Z = #XXXXYYYYZZZZ).
+	   ;; Translate the string "rgb:XX/YY/ZZ" into a list of
+	   ;; numbers (XX YY ZZ), scaling each to the {0..65535}
+	   ;; range.  "rgb:F/F/F" is white.
 	   (let* ((ndig (/ (- len 3) 3))
 		  (maxval (1- (ash 1 (* 4 (- ndig 1)))))
 		  (i1 4)
@@ -961,15 +965,15 @@ tty-color-standard-values
 	     (list
 	      (/ (* (string-to-number
 		     (substring color i1 (- i2 1)) 16)
-		    255)
+		    65535)
 		 maxval)
 	      (/ (* (string-to-number
 		     (substring color i2 (- i3 1)) 16)
-		    255)
+		    65535)
 		 maxval)
 	      (/ (* (string-to-number
 		     (substring color i3) 16)
-		    255)
+		    65535)
 		 maxval))))
 	  (t
 	   (cdr (assoc color color-name-rgb-alist))))))
@@ -978,7 +982,7 @@ tty-color-translate
   "Given a color COLOR, return the index of the corresponding TTY color.
 
 COLOR must be a string that is either the color's name, or its X-style
-specification like \"#RRGGBB\" or \"RGB:rr/gg/bb\", where each primary.
+specification like \"#RRGGBB\" or \"rgb:RR/GG/BB\", where each primary.
 color can be given with 1 to 4 hex digits.
 
 If COLOR is a color name that is found among supported colors in
diff --git a/src/xterm.c b/src/xterm.c
index 38bc17de97..171c7af0e6 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2381,6 +2381,8 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
   x_query_colors (f, bgcolor, 1);
 }
 
+#define HEX_COLOR_NAME_LENGTH 32
+
 /* On frame F, translate the color name to RGB values.  Use cached
    information, if possible.
 
@@ -2398,9 +2400,35 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
 
   if (color_name[0] == '#')
     {
-      /* The hex form is parsed directly by XParseColor without
+      /* Don't pass #RGB strings directly to XParseColor, because that
+	 follows the old convention of zero-extending each channel
+	 value: #f00 means #f00000.  We want the new convention of
+	 scaling channel values, so #f00 means #ff0000.
+
+	 So we translate #f00 to rgb:f/0/0, which X handles
+	 differently. */
+      char rgb_color_name[HEX_COLOR_NAME_LENGTH];
+      int len = strlen (color_name);
+      int digits_per_channel;
+      if (len == 4)
+	digits_per_channel = 1;
+      else if (len == 7)
+	digits_per_channel = 2;
+      else if (len == 10)
+	digits_per_channel = 3;
+      else if (len == 13)
+	digits_per_channel = 4;
+      else
+	return 0;
+
+      snprintf (rgb_color_name, sizeof rgb_color_name, "rgb:%.*s/%.*s/%.*s",
+		digits_per_channel, color_name + 1,
+		digits_per_channel, color_name + digits_per_channel + 1,
+		digits_per_channel, color_name + 2 * digits_per_channel + 1);
+
+      /* The rgb form is parsed directly by XParseColor without
 	 talking to the X server.  No need for caching.  */
-      return XParseColor (dpy, cmap, color_name, color);
+      return XParseColor (dpy, cmap, rgb_color_name, color);
     }
 
   for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-28  9:28                   ` Pip Cet
@ 2019-06-28  9:42                     ` Robert Pluim
  2019-06-28 10:00                       ` Pip Cet
  2019-06-28 12:33                     ` Eli Zaretskii
  1 sibling, 1 reply; 20+ messages in thread
From: Robert Pluim @ 2019-06-28  9:42 UTC (permalink / raw)
  To: Pip Cet; +Cc: rms, 36304

>>>>> On Fri, 28 Jun 2019 09:28:53 +0000, Pip Cet <pipcet@gmail.com> said:
    Pip> Complete updated patch attached.

As someone willfully and woefully ignorant of Emacs' colour handling,
I gave this patch a read, and I find it perfectly clear. One very
minor nit below (which was there before this patch)

    Pip> @@ -978,7 +982,7 @@ tty-color-translate
    Pip>    "Given a color COLOR, return the index of the corresponding TTY color.
 
    Pip>  COLOR must be a string that is either the color's name, or its X-style
    Pip> -specification like \"#RRGGBB\" or \"RGB:rr/gg/bb\", where each primary.
    Pip> +specification like \"#RRGGBB\" or \"rgb:RR/GG/BB\", where each primary.

Thereʼs an extra '.' at the end of this line.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-28  9:42                     ` Robert Pluim
@ 2019-06-28 10:00                       ` Pip Cet
  2019-06-28 13:07                         ` Andy Moreton
  0 siblings, 1 reply; 20+ messages in thread
From: Pip Cet @ 2019-06-28 10:00 UTC (permalink / raw)
  To: Robert Pluim; +Cc: rms, 36304

[-- Attachment #1: Type: text/plain, Size: 559 bytes --]

On Fri, Jun 28, 2019 at 9:42 AM Robert Pluim <rpluim@gmail.com> wrote:
>     Pip>  COLOR must be a string that is either the color's name, or its X-style
>     Pip> -specification like \"#RRGGBB\" or \"RGB:rr/gg/bb\", where each primary.
>     Pip> +specification like \"#RRGGBB\" or \"rgb:RR/GG/BB\", where each primary.
>
> Thereʼs an extra '.' at the end of this line.

Thanks!

I also spotted some more references to X in the docstrings.

Updated patch attached.  Please let me know if you notice anything
else in there that needs changing.

[-- Attachment #2: 0001-Use-the-CSS-convention-for-RGB-colors-bug-36304.patch --]
[-- Type: application/x-patch, Size: 9049 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-28  9:28                   ` Pip Cet
  2019-06-28  9:42                     ` Robert Pluim
@ 2019-06-28 12:33                     ` Eli Zaretskii
  2019-06-28 14:34                       ` Pip Cet
  1 sibling, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2019-06-28 12:33 UTC (permalink / raw)
  To: Pip Cet; +Cc: rms, 36304

> From: Pip Cet <pipcet@gmail.com>
> Date: Fri, 28 Jun 2019 09:28:53 +0000
> Cc: rms@gnu.org, 36304@debbugs.gnu.org
> 
> > > -    (cond ((and (>= len 4) ;; X-style "#XXYYZZ" color spec
> > > +    (cond ((and (>= len 4) ;; "#XXYYZZ" color spec
> >
> > Is #XXYYZZ no longer considered "X-style"?
> 
> I would say no, since X's interpretation of #f00 is a little different
> from the HTML/CSS/SVG interpretation.

Then maybe we want to refer to HTML/CSS/SVG?

> Complete updated patch attached.

LGTM, with one comment:

> +The returned value reflects the standard Emacs definition of
> +COLOR (see `Colors for Faces' in the Emacs manual), regardless of

Our convention is to say

  see the Info node `(emacs) Colors for Faces'

to refer to the Info manual.

Also, I think this change warrants an entry in NEWS.

Thanks.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-28 10:00                       ` Pip Cet
@ 2019-06-28 13:07                         ` Andy Moreton
  0 siblings, 0 replies; 20+ messages in thread
From: Andy Moreton @ 2019-06-28 13:07 UTC (permalink / raw)
  To: 36304

On Fri 28 Jun 2019, Pip Cet wrote:

> Updated patch attached.  Please let me know if you notice anything
> else in there that needs changing.

As this changes user-visible behaviour it should probably have a NEWS entry.

> @@ -2398,9 +2400,35 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
>  
>    if (color_name[0] == '#')
>      {
> -      /* The hex form is parsed directly by XParseColor without
> +      /* Don't pass #RGB strings directly to XParseColor, because that
> +	 follows the old convention of zero-extending each channel
> +	 value: #f00 means #f00000.  We want the new convention of
> +	 scaling channel values, so #f00 means #ff0000.
> +
> +	 So we translate #f00 to rgb:f/0/0, which X handles
> +	 differently. */

The use of "old" and "new" here is unclear.

Consider "old" -> "X" and "new" -> "emacs".

    AndyM







^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-28 12:33                     ` Eli Zaretskii
@ 2019-06-28 14:34                       ` Pip Cet
  2019-06-28 19:54                         ` Eli Zaretskii
  2019-06-28 21:27                         ` Andy Moreton
  0 siblings, 2 replies; 20+ messages in thread
From: Pip Cet @ 2019-06-28 14:34 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rms, 36304

[-- Attachment #1: Type: text/plain, Size: 350 bytes --]

> Then maybe we want to refer to HTML/CSS/SVG?

Sounds good.

> Our convention is to say
>
>   see the Info node `(emacs) Colors for Faces'
>
> to refer to the Info manual.

Thanks! I was looking for that syntax :-)

> Also, I think this change warrants an entry in NEWS.

Okay.

This patch also incorporates Andy's suggestions, and adds some tests.

[-- Attachment #2: 0001-Use-the-CSS-convention-for-RGB-colors-bug-36304.patch --]
[-- Type: text/x-patch, Size: 12018 bytes --]

From df155caedc7f6708808f0f6ab33b02e646684c70 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Fri, 28 Jun 2019 09:23:19 +0000
Subject: [PATCH] Use the CSS convention for #RGB colors (bug#36304).

* src/xterm.c (x_parse_color): Change interpretation of #RGB color
triplets to match CSS rather than X conventions.

* lisp/term/tty-colors.el (tty-color-standard-values): Change
interpretation of #RGB color triplets to match CSS rather than X
conventions.  Allow upper-case digits.  Fix rgb:R/G/B
interpretation.

* doc/emacs/display.texi (Colors): Specify the convention used for
"#RGB" color triplets.

* test/lisp/tty-colors-tests.el: New file.

* etc/NEWS: Mention the change.
---
 doc/emacs/display.texi        | 18 +++++----
 etc/NEWS                      |  5 +++
 lisp/term/tty-colors.el       | 74 +++++++++++++++++++----------------
 src/atimer.c                  |  2 +-
 src/xterm.c                   | 33 +++++++++++++++-
 test/lisp/tty-colors-tests.el | 38 ++++++++++++++++++
 6 files changed, 126 insertions(+), 44 deletions(-)
 create mode 100644 test/lisp/tty-colors-tests.el

diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index f92f7529ea..735f96fda4 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -556,14 +556,14 @@ Faces
 
 @node Colors
 @section Colors for Faces
-@cindex color name
-@cindex RGB triplet
 
   Faces can have various foreground and background colors.  When you
 specify a color for a face---for instance, when customizing the face
 (@pxref{Face Customization})---you can use either a @dfn{color name}
 or an @dfn{RGB triplet}.
 
+@subsection Color Names
+@cindex color name
 @findex list-colors-display
 @vindex list-colors-sort
   A color name is a pre-defined name, such as @samp{dark orange} or
@@ -578,12 +578,16 @@ Colors
 text terminals; if a face is given a color specified by an X11 color
 name, it is displayed using the closest-matching terminal color.
 
+@subsection RGB Triplets
+@cindex RGB triplet
   An RGB triplet is a string of the form @samp{#RRGGBB}.  Each of the
-R, G, and B components is a hexadecimal number specifying the
-component's relative intensity, one to four digits long (usually two
-digits are used).  The components must have the same number of digits.
-For hexadecimal values A to F, either upper or lower case are
-acceptable.
+primary color components is represented by a hexadecimal number
+between @samp{00} (intensity 0) and @samp{FF} (the maximum intensity).
+It is also possible to use one, three, or four hex digits for each
+component, so @samp{red} can be represented as @samp{#F00},
+@samp{#fff000000}, or @samp{#ffff00000000}.  The components must have
+the same number of digits.  For hexadecimal values A to F, either
+upper or lower case are acceptable.
 
   The @kbd{M-x list-colors-display} command also shows the equivalent
 RGB triplet for each named color.  For instance, @samp{medium sea
diff --git a/etc/NEWS b/etc/NEWS
index 864eb8c110..be37349084 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -398,6 +398,11 @@ mode they are described in the manual "(emacs) Display".
 +++
 ** 'progress-reporter-update' accepts a suffix string to display.
 
++++
+** Emacs now interprets RGB triplets like HTML, SVG, and CSS do.
+
+The X convention previously used differed slightly, particularly for
+RGB triplets with a single hexadecimal digit per component.
 
 \f
 * Editing Changes in Emacs 27.1
diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el
index 307586f221..fd4f34cb37 100644
--- a/lisp/term/tty-colors.el
+++ b/lisp/term/tty-colors.el
@@ -919,57 +919,63 @@ tty-color-standard-values
 The result is a list of integer RGB values--(RED GREEN BLUE).
 These values range from 0 to 65535; white is (65535 65535 65535).
 
-The returned value reflects the standard X definition of COLOR,
-regardless of whether the terminal can display it, so the return value
-should be the same regardless of what display is being used."
+The returned value reflects the standard Emacs definition of
+COLOR (see the info node `(emacs) Colors'), regardless of whether
+the terminal can display it, so the return value should be the
+same regardless of what display is being used."
   (let ((len (length color)))
-    (cond ((and (>= len 4) ;; X-style "#XXYYZZ" color spec
+    (cond ((and (>= len 4) ;; HTML/CSS/SVG-style "#XXYYZZ" color spec
 		(eq (aref color 0) ?#)
 		(member (aref color 1)
 			'(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
-			     ?a ?b ?c ?d ?e ?f)))
-	   ;; Translate the string "#XXYYZZ" into a list
-	   ;; of numbers (XX YY ZZ).  If the primary colors
-	   ;; are specified with less than 4 hex digits,
-	   ;; the used digits represent the most significant
-	   ;; bits of the value (e.g. #XYZ = #X000Y000Z000).
+			     ?a ?b ?c ?d ?e ?f
+                             ?A ?B ?C ?D ?E ?F)))
+	   ;; Translate the string "#XXYYZZ" into a list of numbers
+	   ;; (XX YY ZZ), scaling each to the {0..65535} range.  This
+	   ;; follows the HTML color convention, where both "#fff" and
+	   ;; "#ffffff" represent the same color, white.
 	   (let* ((ndig (/ (- len 1) 3))
+		  (maxval (1- (ash 1 (* 4 ndig))))
 		  (i1 1)
 		  (i2 (+ i1 ndig))
-		  (i3 (+ i2 ndig)))
+		  (i3 (+ i2 ndig))
+                  (i4 (+ i3 ndig)))
 	     (list
-	      (ash
-	       (string-to-number (substring color i1 i2) 16)
-	       (* 4 (- 4 ndig)))
-	      (ash
-	       (string-to-number (substring color i2 i3) 16)
-	       (* 4 (- 4 ndig)))
-	      (ash
-	       (string-to-number (substring color i3) 16)
-	       (* 4 (- 4 ndig))))))
-	  ((and (>= len 9) ;; X-style RGB:xx/yy/zz color spec
+	      (/ (* (string-to-number
+		     (substring color i1 i2) 16)
+		    65535)
+		 maxval)
+	      (/ (* (string-to-number
+		     (substring color i2 i3) 16)
+		    65535)
+		 maxval)
+	      (/ (* (string-to-number
+		     (substring color i3 i4) 16)
+		    65535)
+		 maxval))))
+	  ((and (>= len 9) ;; X-style rgb:xx/yy/zz color spec
 		(string= (substring color 0 4) "rgb:"))
-	   ;; Translate the string "RGB:XX/YY/ZZ" into a list
-	   ;; of numbers (XX YY ZZ).  If fewer than 4 hex
-	   ;; digits are used, they represent the fraction
-	   ;; of the maximum value (RGB:X/Y/Z = #XXXXYYYYZZZZ).
+	   ;; Translate the string "rgb:XX/YY/ZZ" into a list of
+	   ;; numbers (XX YY ZZ), scaling each to the {0..65535}
+	   ;; range.  "rgb:F/F/F" is white.
 	   (let* ((ndig (/ (- len 3) 3))
 		  (maxval (1- (ash 1 (* 4 (- ndig 1)))))
 		  (i1 4)
 		  (i2 (+ i1 ndig))
-		  (i3 (+ i2 ndig)))
+		  (i3 (+ i2 ndig))
+                  (i4 (+ i3 ndig)))
 	     (list
 	      (/ (* (string-to-number
 		     (substring color i1 (- i2 1)) 16)
-		    255)
+		    65535)
 		 maxval)
 	      (/ (* (string-to-number
 		     (substring color i2 (- i3 1)) 16)
-		    255)
+		    65535)
 		 maxval)
 	      (/ (* (string-to-number
-		     (substring color i3) 16)
-		    255)
+		     (substring color i3 (1- i4)) 16)
+		    65535)
 		 maxval))))
 	  (t
 	   (cdr (assoc color color-name-rgb-alist))))))
@@ -977,9 +983,9 @@ tty-color-standard-values
 (defun tty-color-translate (color &optional frame)
   "Given a color COLOR, return the index of the corresponding TTY color.
 
-COLOR must be a string that is either the color's name, or its X-style
-specification like \"#RRGGBB\" or \"RGB:rr/gg/bb\", where each primary.
-color can be given with 1 to 4 hex digits.
+COLOR must be a string that is either the color's name, or its
+color triplet specification like \"#RRGGBB\" or \"rgb:RR/GG/BB\",
+where each primary color can be given with 1 to 4 hex digits.
 
 If COLOR is a color name that is found among supported colors in
 `tty-color-alist', the associated index is returned.  Otherwise, the
@@ -987,7 +993,7 @@ tty-color-translate
 looking up the name in `color-name-rgb-alist', are used to find the
 supported color that is the best approximation for COLOR in the RGB
 space.
-If COLOR is neither a valid X RGB specification of the color, nor a
+If COLOR is neither a valid RGB specification of the color, nor a
 name of a color in `color-name-rgb-alist', the returned value is nil.
 
 If FRAME is unspecified or nil, it defaults to the selected frame."
diff --git a/src/atimer.c b/src/atimer.c
index 8387b8aa0e..b92d06b90a 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -1,4 +1,4 @@
-/* Asynchronous timers.
+  /* Asynchronous timers.
    Copyright (C) 2000-2019 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
diff --git a/src/xterm.c b/src/xterm.c
index 38bc17de97..b79312d748 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2381,6 +2381,8 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
   x_query_colors (f, bgcolor, 1);
 }
 
+#define HEX_COLOR_NAME_LENGTH 32
+
 /* On frame F, translate the color name to RGB values.  Use cached
    information, if possible.
 
@@ -2398,9 +2400,36 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
 
   if (color_name[0] == '#')
     {
-      /* The hex form is parsed directly by XParseColor without
+      /* Don't pass #RGB strings directly to XParseColor, because that
+	 follows the X convention of zero-extending each channel
+	 value: #f00 means #f00000.  We want the convention of scaling
+	 channel values, so #f00 means #ff0000, just as it does for
+	 HTML, SVG, and CSS.
+
+	 So we translate #f00 to rgb:f/0/0, which X handles
+	 differently. */
+      char rgb_color_name[HEX_COLOR_NAME_LENGTH];
+      int len = strlen (color_name);
+      int digits_per_channel;
+      if (len == 4)
+	digits_per_channel = 1;
+      else if (len == 7)
+	digits_per_channel = 2;
+      else if (len == 10)
+	digits_per_channel = 3;
+      else if (len == 13)
+	digits_per_channel = 4;
+      else
+	return 0;
+
+      snprintf (rgb_color_name, sizeof rgb_color_name, "rgb:%.*s/%.*s/%.*s",
+		digits_per_channel, color_name + 1,
+		digits_per_channel, color_name + digits_per_channel + 1,
+		digits_per_channel, color_name + 2 * digits_per_channel + 1);
+
+      /* The rgb form is parsed directly by XParseColor without
 	 talking to the X server.  No need for caching.  */
-      return XParseColor (dpy, cmap, color_name, color);
+      return XParseColor (dpy, cmap, rgb_color_name, color);
     }
 
   for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
diff --git a/test/lisp/tty-colors-tests.el b/test/lisp/tty-colors-tests.el
new file mode 100644
index 0000000000..0570d1bf5b
--- /dev/null
+++ b/test/lisp/tty-colors-tests.el
@@ -0,0 +1,38 @@
+;;; tty-colors-tests.el --- tests for tty-colors.el  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2019 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+\f
+;;; Code:
+(require 'ert)
+(require 'term/tty-colors)
+
+(ert-deftest tty-colors-test-standard-colors ()
+  (should (equal (tty-color-standard-values "white") '(65535 65535 65535)))
+  (should (equal (tty-color-standard-values "#F00") '(65535 0 0)))
+  (should (equal (tty-color-standard-values "#00FF00") '(0 65535 0)))
+  (should (equal (tty-color-standard-values "#00000000FFFF") '(0 0 65535)))
+  (should (equal (tty-color-standard-values "rgb:0/0/7") '(0 0 30583)))
+  (should (equal (tty-color-standard-values "rgb:0/ff/0") '(0 65535 0)))
+  (should (equal (tty-color-standard-values "rgb:ffFF/0000/0000") '(65535 0 0))))
+
+(provide 'term-tests)
+
+;;; term-tests.el ends here
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-28 14:34                       ` Pip Cet
@ 2019-06-28 19:54                         ` Eli Zaretskii
  2019-06-28 21:27                         ` Andy Moreton
  1 sibling, 0 replies; 20+ messages in thread
From: Eli Zaretskii @ 2019-06-28 19:54 UTC (permalink / raw)
  To: Pip Cet; +Cc: rms, 36304

> From: Pip Cet <pipcet@gmail.com>
> Date: Fri, 28 Jun 2019 14:34:03 +0000
> Cc: rms@gnu.org, 36304@debbugs.gnu.org
> 
> This patch also incorporates Andy's suggestions, and adds some tests.

LGTM, thanks.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-28 14:34                       ` Pip Cet
  2019-06-28 19:54                         ` Eli Zaretskii
@ 2019-06-28 21:27                         ` Andy Moreton
  2019-07-22  2:46                           ` Pip Cet
  1 sibling, 1 reply; 20+ messages in thread
From: Andy Moreton @ 2019-06-28 21:27 UTC (permalink / raw)
  To: 36304

On Fri 28 Jun 2019, Pip Cet wrote:

> This patch also incorporates Andy's suggestions, and adds some tests.

There is an unintended change to src/atimer.c, but otherwise looks good.

    AndyM






^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-06-28 21:27                         ` Andy Moreton
@ 2019-07-22  2:46                           ` Pip Cet
  2019-07-27 11:12                             ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Pip Cet @ 2019-07-22  2:46 UTC (permalink / raw)
  To: Andy Moreton; +Cc: 36304

[-- Attachment #1: Type: text/plain, Size: 306 bytes --]

On Fri, Jun 28, 2019 at 9:28 PM Andy Moreton <andrewjmoreton@gmail.com> wrote:
> On Fri 28 Jun 2019, Pip Cet wrote:
>
> > This patch also incorporates Andy's suggestions, and adds some tests.
>
> There is an unintended change to src/atimer.c, but otherwise looks good.

Rebased and revised patch attached.

[-- Attachment #2: 0001-Use-the-CSS-convention-for-RGB-colors-bug-36304.patch --]
[-- Type: text/x-patch, Size: 11940 bytes --]

From be8465a394466ed126b34c1b37cebf13ac5e4e61 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Mon, 22 Jul 2019 02:40:35 +0000
Subject: [PATCH] Use the CSS convention for #RGB colors (bug#36304)

* src/xterm.c (x_parse_color): Change interpretation of #RGB color
triplets to match CSS rather than X conventions.

* lisp/term/tty-colors.el (tty-color-standard-values): Change
interpretation of #RGB color triplets to match CSS rather than X
conventions.  Allow upper-case digits.  Fix rgb:R/G/B
interpretation.

* doc/emacs/display.texi (Colors): Specify the convention used for
"#RGB" color triplets.

* test/lisp/tty-colors-tests.el: New file.

* etc/NEWS: Mention the change.
---
 doc/emacs/display.texi        | 18 +++++----
 etc/NEWS                      |  7 +++-
 lisp/term/tty-colors.el       | 74 +++++++++++++++++++----------------
 src/xterm.c                   | 33 +++++++++++++++-
 test/lisp/tty-colors-tests.el | 38 ++++++++++++++++++
 5 files changed, 126 insertions(+), 44 deletions(-)
 create mode 100644 test/lisp/tty-colors-tests.el

diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index 0ce291335a..8e842bea17 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -556,14 +556,14 @@ Faces
 
 @node Colors
 @section Colors for Faces
-@cindex color name
-@cindex RGB triplet
 
   Faces can have various foreground and background colors.  When you
 specify a color for a face---for instance, when customizing the face
 (@pxref{Face Customization})---you can use either a @dfn{color name}
 or an @dfn{RGB triplet}.
 
+@subsection Color Names
+@cindex color name
 @findex list-colors-display
 @vindex list-colors-sort
   A color name is a pre-defined name, such as @samp{dark orange} or
@@ -578,12 +578,16 @@ Colors
 text terminals; if a face is given a color specified by an X11 color
 name, it is displayed using the closest-matching terminal color.
 
+@subsection RGB Triplets
+@cindex RGB triplet
   An RGB triplet is a string of the form @samp{#RRGGBB}.  Each of the
-R, G, and B components is a hexadecimal number specifying the
-component's relative intensity, one to four digits long (usually two
-digits are used).  The components must have the same number of digits.
-For hexadecimal values A to F, either upper or lower case are
-acceptable.
+primary color components is represented by a hexadecimal number
+between @samp{00} (intensity 0) and @samp{FF} (the maximum intensity).
+It is also possible to use one, three, or four hex digits for each
+component, so @samp{red} can be represented as @samp{#F00},
+@samp{#fff000000}, or @samp{#ffff00000000}.  The components must have
+the same number of digits.  For hexadecimal values A to F, either
+upper or lower case are acceptable.
 
   The @kbd{M-x list-colors-display} command also shows the equivalent
 RGB triplet for each named color.  For instance, @samp{medium sea
diff --git a/etc/NEWS b/etc/NEWS
index 41debac50e..62ea50b239 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -402,6 +402,12 @@ mode they are described in the manual "(emacs) Display".
 names in xref buffers.
 ** New variable `file-size-function' controls how file sizes are displayed
 
++++
+** Emacs now interprets RGB triplets like HTML, SVG, and CSS do.
+
+The X convention previously used differed slightly, particularly for
+RGB triplets with a single hexadecimal digit per component.
+
 \f
 * Editing Changes in Emacs 27.1
 
@@ -1477,7 +1483,6 @@ automatically updates.  In the buffer, you can use 's q' or 's e' to
 signal a thread with quit or error respectively, or get a snapshot
 backtrace with 'b'.
 
-
 ** thingatpt.el
 
 ---
diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el
index 5af8170203..43c1071ceb 100644
--- a/lisp/term/tty-colors.el
+++ b/lisp/term/tty-colors.el
@@ -919,57 +919,63 @@ tty-color-standard-values
 The result is a list of integer RGB values--(RED GREEN BLUE).
 These values range from 0 to 65535; white is (65535 65535 65535).
 
-The returned value reflects the standard X definition of COLOR,
-regardless of whether the terminal can display it, so the return value
-should be the same regardless of what display is being used."
+The returned value reflects the standard Emacs definition of
+COLOR (see the info node `(emacs) Colors'), regardless of whether
+the terminal can display it, so the return value should be the
+same regardless of what display is being used."
   (let ((len (length color)))
-    (cond ((and (>= len 4) ;; X-style "#XXYYZZ" color spec
+    (cond ((and (>= len 4) ;; HTML/CSS/SVG-style "#XXYYZZ" color spec
 		(eq (aref color 0) ?#)
 		(member (aref color 1)
 			'(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
-			     ?a ?b ?c ?d ?e ?f)))
-	   ;; Translate the string "#XXYYZZ" into a list
-	   ;; of numbers (XX YY ZZ).  If the primary colors
-	   ;; are specified with less than 4 hex digits,
-	   ;; the used digits represent the most significant
-	   ;; bits of the value (e.g. #XYZ = #X000Y000Z000).
+			     ?a ?b ?c ?d ?e ?f
+                             ?A ?B ?C ?D ?E ?F)))
+	   ;; Translate the string "#XXYYZZ" into a list of numbers
+	   ;; (XX YY ZZ), scaling each to the {0..65535} range.  This
+	   ;; follows the HTML color convention, where both "#fff" and
+	   ;; "#ffffff" represent the same color, white.
 	   (let* ((ndig (/ (- len 1) 3))
+		  (maxval (1- (ash 1 (* 4 ndig))))
 		  (i1 1)
 		  (i2 (+ i1 ndig))
-		  (i3 (+ i2 ndig)))
+		  (i3 (+ i2 ndig))
+                  (i4 (+ i3 ndig)))
 	     (list
-	      (ash
-	       (string-to-number (substring color i1 i2) 16)
-	       (* 4 (- 4 ndig)))
-	      (ash
-	       (string-to-number (substring color i2 i3) 16)
-	       (* 4 (- 4 ndig)))
-	      (ash
-	       (string-to-number (substring color i3) 16)
-	       (* 4 (- 4 ndig))))))
-	  ((and (>= len 9) ;; X-style RGB:xx/yy/zz color spec
+	      (/ (* (string-to-number
+		     (substring color i1 i2) 16)
+		    65535)
+		 maxval)
+	      (/ (* (string-to-number
+		     (substring color i2 i3) 16)
+		    65535)
+		 maxval)
+	      (/ (* (string-to-number
+		     (substring color i3 i4) 16)
+		    65535)
+		 maxval))))
+	  ((and (>= len 9) ;; X-style rgb:xx/yy/zz color spec
 		(string= (substring color 0 4) "rgb:"))
-	   ;; Translate the string "RGB:XX/YY/ZZ" into a list
-	   ;; of numbers (XX YY ZZ).  If fewer than 4 hex
-	   ;; digits are used, they represent the fraction
-	   ;; of the maximum value (RGB:X/Y/Z = #XXXXYYYYZZZZ).
+	   ;; Translate the string "rgb:XX/YY/ZZ" into a list of
+	   ;; numbers (XX YY ZZ), scaling each to the {0..65535}
+	   ;; range.  "rgb:F/F/F" is white.
 	   (let* ((ndig (/ (- len 3) 3))
 		  (maxval (1- (ash 1 (* 4 (- ndig 1)))))
 		  (i1 4)
 		  (i2 (+ i1 ndig))
-		  (i3 (+ i2 ndig)))
+		  (i3 (+ i2 ndig))
+                  (i4 (+ i3 ndig)))
 	     (list
 	      (/ (* (string-to-number
 		     (substring color i1 (- i2 1)) 16)
-		    255)
+		    65535)
 		 maxval)
 	      (/ (* (string-to-number
 		     (substring color i2 (- i3 1)) 16)
-		    255)
+		    65535)
 		 maxval)
 	      (/ (* (string-to-number
-		     (substring color i3) 16)
-		    255)
+		     (substring color i3 (1- i4)) 16)
+		    65535)
 		 maxval))))
 	  (t
 	   (cdr (assoc color color-name-rgb-alist))))))
@@ -977,9 +983,9 @@ tty-color-standard-values
 (defun tty-color-translate (color &optional frame)
   "Given a color COLOR, return the index of the corresponding TTY color.
 
-COLOR must be a string that is either the color's name, or its X-style
-specification like \"#RRGGBB\" or \"RGB:rr/gg/bb\", where each primary.
-color can be given with 1 to 4 hex digits.
+COLOR must be a string that is either the color's name, or its
+color triplet specification like \"#RRGGBB\" or \"rgb:RR/GG/BB\",
+where each primary color can be given with 1 to 4 hex digits.
 
 If COLOR is a color name that is found among supported colors in
 `tty-color-alist', the associated index is returned.  Otherwise, the
@@ -987,7 +993,7 @@ tty-color-translate
 looking up the name in `color-name-rgb-alist', are used to find the
 supported color that is the best approximation for COLOR in the RGB
 space.
-If COLOR is neither a valid X RGB specification of the color, nor a
+If COLOR is neither a valid RGB specification of the color, nor a
 name of a color in `color-name-rgb-alist', the returned value is nil.
 
 If FRAME is unspecified or nil, it defaults to the selected frame."
diff --git a/src/xterm.c b/src/xterm.c
index c96aa74a7a..75568a82a1 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2381,6 +2381,8 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
   x_query_colors (f, bgcolor, 1);
 }
 
+#define HEX_COLOR_NAME_LENGTH 32
+
 /* On frame F, translate the color name to RGB values.  Use cached
    information, if possible.
 
@@ -2398,9 +2400,36 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
 
   if (color_name[0] == '#')
     {
-      /* The hex form is parsed directly by XParseColor without
+      /* Don't pass #RGB strings directly to XParseColor, because that
+	 follows the X convention of zero-extending each channel
+	 value: #f00 means #f00000.  We want the convention of scaling
+	 channel values, so #f00 means #ff0000, just as it does for
+	 HTML, SVG, and CSS.
+
+	 So we translate #f00 to rgb:f/0/0, which X handles
+	 differently. */
+      char rgb_color_name[HEX_COLOR_NAME_LENGTH];
+      int len = strlen (color_name);
+      int digits_per_channel;
+      if (len == 4)
+	digits_per_channel = 1;
+      else if (len == 7)
+	digits_per_channel = 2;
+      else if (len == 10)
+	digits_per_channel = 3;
+      else if (len == 13)
+	digits_per_channel = 4;
+      else
+	return 0;
+
+      snprintf (rgb_color_name, sizeof rgb_color_name, "rgb:%.*s/%.*s/%.*s",
+		digits_per_channel, color_name + 1,
+		digits_per_channel, color_name + digits_per_channel + 1,
+		digits_per_channel, color_name + 2 * digits_per_channel + 1);
+
+      /* The rgb form is parsed directly by XParseColor without
 	 talking to the X server.  No need for caching.  */
-      return XParseColor (dpy, cmap, color_name, color);
+      return XParseColor (dpy, cmap, rgb_color_name, color);
     }
 
   for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
diff --git a/test/lisp/tty-colors-tests.el b/test/lisp/tty-colors-tests.el
new file mode 100644
index 0000000000..0570d1bf5b
--- /dev/null
+++ b/test/lisp/tty-colors-tests.el
@@ -0,0 +1,38 @@
+;;; tty-colors-tests.el --- tests for tty-colors.el  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2019 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+\f
+;;; Code:
+(require 'ert)
+(require 'term/tty-colors)
+
+(ert-deftest tty-colors-test-standard-colors ()
+  (should (equal (tty-color-standard-values "white") '(65535 65535 65535)))
+  (should (equal (tty-color-standard-values "#F00") '(65535 0 0)))
+  (should (equal (tty-color-standard-values "#00FF00") '(0 65535 0)))
+  (should (equal (tty-color-standard-values "#00000000FFFF") '(0 0 65535)))
+  (should (equal (tty-color-standard-values "rgb:0/0/7") '(0 0 30583)))
+  (should (equal (tty-color-standard-values "rgb:0/ff/0") '(0 65535 0)))
+  (should (equal (tty-color-standard-values "rgb:ffFF/0000/0000") '(65535 0 0))))
+
+(provide 'term-tests)
+
+;;; term-tests.el ends here
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors
  2019-07-22  2:46                           ` Pip Cet
@ 2019-07-27 11:12                             ` Eli Zaretskii
  0 siblings, 0 replies; 20+ messages in thread
From: Eli Zaretskii @ 2019-07-27 11:12 UTC (permalink / raw)
  To: Pip Cet; +Cc: andrewjmoreton, 36304-done

> From: Pip Cet <pipcet@gmail.com>
> Date: Mon, 22 Jul 2019 02:46:16 +0000
> Cc: 36304@debbugs.gnu.org
> 
> Rebased and revised patch attached.

Thanks, pushed to the master branch.

Note that the test file wasn't in the correct directory; I moved it.





^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2019-07-27 11:12 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-06-20 11:22 bug#36304: 27.0.50; request: switch to the superior HTML #RGB convention for colors Pip Cet
2019-06-21  1:54 ` Richard Stallman
2019-06-22 11:23   ` Pip Cet
2019-06-22 11:40     ` Eli Zaretskii
2019-06-22 12:13       ` Pip Cet
2019-06-22 12:35         ` Eli Zaretskii
2019-06-22 14:41           ` Pip Cet
2019-06-22 15:05             ` Eli Zaretskii
2019-06-22 15:33               ` Pip Cet
2019-06-28  8:12                 ` Eli Zaretskii
2019-06-28  9:28                   ` Pip Cet
2019-06-28  9:42                     ` Robert Pluim
2019-06-28 10:00                       ` Pip Cet
2019-06-28 13:07                         ` Andy Moreton
2019-06-28 12:33                     ` Eli Zaretskii
2019-06-28 14:34                       ` Pip Cet
2019-06-28 19:54                         ` Eli Zaretskii
2019-06-28 21:27                         ` Andy Moreton
2019-07-22  2:46                           ` Pip Cet
2019-07-27 11:12                             ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).