aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPip Cet2019-07-22 02:40:35 +0000
committerEli Zaretskii2019-07-27 14:05:46 +0300
commit357399014acacc75bd1825fb2f498f1a4be7b362 (patch)
treefbbfbca7fed181b564f5814c6941297e6f5f0372
parente310843d9dc106187d0e45ef7f0b9cd90a881eec (diff)
downloademacs-357399014acacc75bd1825fb2f498f1a4be7b362.tar.gz
emacs-357399014acacc75bd1825fb2f498f1a4be7b362.zip
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.
-rw-r--r--doc/emacs/display.texi18
-rw-r--r--etc/NEWS7
-rw-r--r--lisp/term/tty-colors.el74
-rw-r--r--src/xterm.c33
4 files changed, 88 insertions, 44 deletions
diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index 0ce291335a9..8e842bea179 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -556,14 +556,14 @@ Font Lock mode.
556 556
557@node Colors 557@node Colors
558@section Colors for Faces 558@section Colors for Faces
559@cindex color name
560@cindex RGB triplet
561 559
562 Faces can have various foreground and background colors. When you 560 Faces can have various foreground and background colors. When you
563specify a color for a face---for instance, when customizing the face 561specify a color for a face---for instance, when customizing the face
564(@pxref{Face Customization})---you can use either a @dfn{color name} 562(@pxref{Face Customization})---you can use either a @dfn{color name}
565or an @dfn{RGB triplet}. 563or an @dfn{RGB triplet}.
566 564
565@subsection Color Names
566@cindex color name
567@findex list-colors-display 567@findex list-colors-display
568@vindex list-colors-sort 568@vindex list-colors-sort
569 A color name is a pre-defined name, such as @samp{dark orange} or 569 A color name is a pre-defined name, such as @samp{dark orange} or
@@ -578,12 +578,16 @@ such terminals. However, Emacs understands X11 color names even on
578text terminals; if a face is given a color specified by an X11 color 578text terminals; if a face is given a color specified by an X11 color
579name, it is displayed using the closest-matching terminal color. 579name, it is displayed using the closest-matching terminal color.
580 580
581@subsection RGB Triplets
582@cindex RGB triplet
581 An RGB triplet is a string of the form @samp{#RRGGBB}. Each of the 583 An RGB triplet is a string of the form @samp{#RRGGBB}. Each of the
582R, G, and B components is a hexadecimal number specifying the 584primary color components is represented by a hexadecimal number
583component's relative intensity, one to four digits long (usually two 585between @samp{00} (intensity 0) and @samp{FF} (the maximum intensity).
584digits are used). The components must have the same number of digits. 586It is also possible to use one, three, or four hex digits for each
585For hexadecimal values A to F, either upper or lower case are 587component, so @samp{red} can be represented as @samp{#F00},
586acceptable. 588@samp{#fff000000}, or @samp{#ffff00000000}. The components must have
589the same number of digits. For hexadecimal values A to F, either
590upper or lower case are acceptable.
587 591
588 The @kbd{M-x list-colors-display} command also shows the equivalent 592 The @kbd{M-x list-colors-display} command also shows the equivalent
589RGB triplet for each named color. For instance, @samp{medium sea 593RGB triplet for each named color. For instance, @samp{medium sea
diff --git a/etc/NEWS b/etc/NEWS
index 021e84c9a43..c970a3c55d1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -407,6 +407,12 @@ names in xref buffers.
407 407
408** New variable `file-size-function' controls how file sizes are displayed. 408** New variable `file-size-function' controls how file sizes are displayed.
409 409
410+++
411** Emacs now interprets RGB triplets like HTML, SVG, and CSS do.
412
413The X convention previously used differed slightly, particularly for
414RGB triplets with a single hexadecimal digit per component.
415
410 416
411* Editing Changes in Emacs 27.1 417* Editing Changes in Emacs 27.1
412 418
@@ -1509,7 +1515,6 @@ automatically updates. In the buffer, you can use 's q' or 's e' to
1509signal a thread with quit or error respectively, or get a snapshot 1515signal a thread with quit or error respectively, or get a snapshot
1510backtrace with 'b'. 1516backtrace with 'b'.
1511 1517
1512
1513** thingatpt.el 1518** thingatpt.el
1514 1519
1515--- 1520---
diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el
index 5af8170203e..43c1071ceb7 100644
--- a/lisp/term/tty-colors.el
+++ b/lisp/term/tty-colors.el
@@ -919,57 +919,63 @@ FRAME defaults to the selected frame."
919The result is a list of integer RGB values--(RED GREEN BLUE). 919The result is a list of integer RGB values--(RED GREEN BLUE).
920These values range from 0 to 65535; white is (65535 65535 65535). 920These values range from 0 to 65535; white is (65535 65535 65535).
921 921
922The returned value reflects the standard X definition of COLOR, 922The returned value reflects the standard Emacs definition of
923regardless of whether the terminal can display it, so the return value 923COLOR (see the info node `(emacs) Colors'), regardless of whether
924should be the same regardless of what display is being used." 924the terminal can display it, so the return value should be the
925same regardless of what display is being used."
925 (let ((len (length color))) 926 (let ((len (length color)))
926 (cond ((and (>= len 4) ;; X-style "#XXYYZZ" color spec 927 (cond ((and (>= len 4) ;; HTML/CSS/SVG-style "#XXYYZZ" color spec
927 (eq (aref color 0) ?#) 928 (eq (aref color 0) ?#)
928 (member (aref color 1) 929 (member (aref color 1)
929 '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 930 '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
930 ?a ?b ?c ?d ?e ?f))) 931 ?a ?b ?c ?d ?e ?f
931 ;; Translate the string "#XXYYZZ" into a list 932 ?A ?B ?C ?D ?E ?F)))
932 ;; of numbers (XX YY ZZ). If the primary colors 933 ;; Translate the string "#XXYYZZ" into a list of numbers
933 ;; are specified with less than 4 hex digits, 934 ;; (XX YY ZZ), scaling each to the {0..65535} range. This
934 ;; the used digits represent the most significant 935 ;; follows the HTML color convention, where both "#fff" and
935 ;; bits of the value (e.g. #XYZ = #X000Y000Z000). 936 ;; "#ffffff" represent the same color, white.
936 (let* ((ndig (/ (- len 1) 3)) 937 (let* ((ndig (/ (- len 1) 3))
938 (maxval (1- (ash 1 (* 4 ndig))))
937 (i1 1) 939 (i1 1)
938 (i2 (+ i1 ndig)) 940 (i2 (+ i1 ndig))
939 (i3 (+ i2 ndig))) 941 (i3 (+ i2 ndig))
942 (i4 (+ i3 ndig)))
940 (list 943 (list
941 (ash 944 (/ (* (string-to-number
942 (string-to-number (substring color i1 i2) 16) 945 (substring color i1 i2) 16)
943 (* 4 (- 4 ndig))) 946 65535)
944 (ash 947 maxval)
945 (string-to-number (substring color i2 i3) 16) 948 (/ (* (string-to-number
946 (* 4 (- 4 ndig))) 949 (substring color i2 i3) 16)
947 (ash 950 65535)
948 (string-to-number (substring color i3) 16) 951 maxval)
949 (* 4 (- 4 ndig)))))) 952 (/ (* (string-to-number
950 ((and (>= len 9) ;; X-style RGB:xx/yy/zz color spec 953 (substring color i3 i4) 16)
954 65535)
955 maxval))))
956 ((and (>= len 9) ;; X-style rgb:xx/yy/zz color spec
951 (string= (substring color 0 4) "rgb:")) 957 (string= (substring color 0 4) "rgb:"))
952 ;; Translate the string "RGB:XX/YY/ZZ" into a list 958 ;; Translate the string "rgb:XX/YY/ZZ" into a list of
953 ;; of numbers (XX YY ZZ). If fewer than 4 hex 959 ;; numbers (XX YY ZZ), scaling each to the {0..65535}
954 ;; digits are used, they represent the fraction 960 ;; range. "rgb:F/F/F" is white.
955 ;; of the maximum value (RGB:X/Y/Z = #XXXXYYYYZZZZ).
956 (let* ((ndig (/ (- len 3) 3)) 961 (let* ((ndig (/ (- len 3) 3))
957 (maxval (1- (ash 1 (* 4 (- ndig 1))))) 962 (maxval (1- (ash 1 (* 4 (- ndig 1)))))
958 (i1 4) 963 (i1 4)
959 (i2 (+ i1 ndig)) 964 (i2 (+ i1 ndig))
960 (i3 (+ i2 ndig))) 965 (i3 (+ i2 ndig))
966 (i4 (+ i3 ndig)))
961 (list 967 (list
962 (/ (* (string-to-number 968 (/ (* (string-to-number
963 (substring color i1 (- i2 1)) 16) 969 (substring color i1 (- i2 1)) 16)
964 255) 970 65535)
965 maxval) 971 maxval)
966 (/ (* (string-to-number 972 (/ (* (string-to-number
967 (substring color i2 (- i3 1)) 16) 973 (substring color i2 (- i3 1)) 16)
968 255) 974 65535)
969 maxval) 975 maxval)
970 (/ (* (string-to-number 976 (/ (* (string-to-number
971 (substring color i3) 16) 977 (substring color i3 (1- i4)) 16)
972 255) 978 65535)
973 maxval)))) 979 maxval))))
974 (t 980 (t
975 (cdr (assoc color color-name-rgb-alist)))))) 981 (cdr (assoc color color-name-rgb-alist))))))
@@ -977,9 +983,9 @@ should be the same regardless of what display is being used."
977(defun tty-color-translate (color &optional frame) 983(defun tty-color-translate (color &optional frame)
978 "Given a color COLOR, return the index of the corresponding TTY color. 984 "Given a color COLOR, return the index of the corresponding TTY color.
979 985
980COLOR must be a string that is either the color's name, or its X-style 986COLOR must be a string that is either the color's name, or its
981specification like \"#RRGGBB\" or \"RGB:rr/gg/bb\", where each primary. 987color triplet specification like \"#RRGGBB\" or \"rgb:RR/GG/BB\",
982color can be given with 1 to 4 hex digits. 988where each primary color can be given with 1 to 4 hex digits.
983 989
984If COLOR is a color name that is found among supported colors in 990If COLOR is a color name that is found among supported colors in
985`tty-color-alist', the associated index is returned. Otherwise, the 991`tty-color-alist', the associated index is returned. Otherwise, the
@@ -987,7 +993,7 @@ RGB values of the color, either as given by the argument or from
987looking up the name in `color-name-rgb-alist', are used to find the 993looking up the name in `color-name-rgb-alist', are used to find the
988supported color that is the best approximation for COLOR in the RGB 994supported color that is the best approximation for COLOR in the RGB
989space. 995space.
990If COLOR is neither a valid X RGB specification of the color, nor a 996If COLOR is neither a valid RGB specification of the color, nor a
991name of a color in `color-name-rgb-alist', the returned value is nil. 997name of a color in `color-name-rgb-alist', the returned value is nil.
992 998
993If FRAME is unspecified or nil, it defaults to the selected frame." 999If FRAME is unspecified or nil, it defaults to the selected frame."
diff --git a/src/xterm.c b/src/xterm.c
index c96aa74a7a6..75568a82a18 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2381,6 +2381,8 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
2381 x_query_colors (f, bgcolor, 1); 2381 x_query_colors (f, bgcolor, 1);
2382} 2382}
2383 2383
2384#define HEX_COLOR_NAME_LENGTH 32
2385
2384/* On frame F, translate the color name to RGB values. Use cached 2386/* On frame F, translate the color name to RGB values. Use cached
2385 information, if possible. 2387 information, if possible.
2386 2388
@@ -2398,9 +2400,36 @@ Status x_parse_color (struct frame *f, const char *color_name,
2398 2400
2399 if (color_name[0] == '#') 2401 if (color_name[0] == '#')
2400 { 2402 {
2401 /* The hex form is parsed directly by XParseColor without 2403 /* Don't pass #RGB strings directly to XParseColor, because that
2404 follows the X convention of zero-extending each channel
2405 value: #f00 means #f00000. We want the convention of scaling
2406 channel values, so #f00 means #ff0000, just as it does for
2407 HTML, SVG, and CSS.
2408
2409 So we translate #f00 to rgb:f/0/0, which X handles
2410 differently. */
2411 char rgb_color_name[HEX_COLOR_NAME_LENGTH];
2412 int len = strlen (color_name);
2413 int digits_per_channel;
2414 if (len == 4)
2415 digits_per_channel = 1;
2416 else if (len == 7)
2417 digits_per_channel = 2;
2418 else if (len == 10)
2419 digits_per_channel = 3;
2420 else if (len == 13)
2421 digits_per_channel = 4;
2422 else
2423 return 0;
2424
2425 snprintf (rgb_color_name, sizeof rgb_color_name, "rgb:%.*s/%.*s/%.*s",
2426 digits_per_channel, color_name + 1,
2427 digits_per_channel, color_name + digits_per_channel + 1,
2428 digits_per_channel, color_name + 2 * digits_per_channel + 1);
2429
2430 /* The rgb form is parsed directly by XParseColor without
2402 talking to the X server. No need for caching. */ 2431 talking to the X server. No need for caching. */
2403 return XParseColor (dpy, cmap, color_name, color); 2432 return XParseColor (dpy, cmap, rgb_color_name, color);
2404 } 2433 }
2405 2434
2406 for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry; 2435 for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;