diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfaces.c | 90 |
1 files changed, 49 insertions, 41 deletions
diff --git a/src/xfaces.c b/src/xfaces.c index 308509a0267..c4a4e1c94f3 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -820,10 +820,10 @@ load_pixmap (struct frame *f, Lisp_Object name) | |||
| 820 | Color Handling | 820 | Color Handling |
| 821 | ***********************************************************************/ | 821 | ***********************************************************************/ |
| 822 | 822 | ||
| 823 | /* Parse hex color component at S ending right before E. | 823 | /* Parse hex color component specification that starts at S and ends |
| 824 | Set *DST to the value normalized so that the maximum for the | 824 | right before E. Set *DST to the parsed value normalized so that |
| 825 | number of digits given becomes 65535, and return true on success, | 825 | the maximum value for the number of hex digits given becomes 65535, |
| 826 | false otherwise. */ | 826 | and return true on success, false otherwise. */ |
| 827 | static bool | 827 | static bool |
| 828 | parse_hex_color_comp (const char *s, const char *e, unsigned short *dst) | 828 | parse_hex_color_comp (const char *s, const char *e, unsigned short *dst) |
| 829 | { | 829 | { |
| @@ -849,8 +849,9 @@ parse_hex_color_comp (const char *s, const char *e, unsigned short *dst) | |||
| 849 | return true; | 849 | return true; |
| 850 | } | 850 | } |
| 851 | 851 | ||
| 852 | /* Parse floating-point color component at S ending right before E. | 852 | /* Parse floating-point color component specification that starts at S |
| 853 | Return the number if in the range [0,1]; otherwise -1. */ | 853 | and ends right before E. Return the parsed number if in the range |
| 854 | [0,1]; otherwise return -1. */ | ||
| 854 | static double | 855 | static double |
| 855 | parse_float_color_comp (const char *s, const char *e) | 856 | parse_float_color_comp (const char *s, const char *e) |
| 856 | { | 857 | { |
| @@ -859,48 +860,54 @@ parse_float_color_comp (const char *s, const char *e) | |||
| 859 | return (end == e && x >= 0 && x <= 1) ? x : -1; | 860 | return (end == e && x >= 0 && x <= 1) ? x : -1; |
| 860 | } | 861 | } |
| 861 | 862 | ||
| 862 | /* Parse S as a numeric color specification and set *R, *G and *B. | 863 | /* Parse SPEC as a numeric color specification and set *R, *G and *B. |
| 863 | Return true on success, false on failure. | 864 | Return true on success, false on failure. |
| 864 | Recognized formats: | ||
| 865 | 865 | ||
| 866 | "#RGB", with R, G and B hex strings of equal length, 1-4 digits each | 866 | Recognized formats of SPEC: |
| 867 | "rgb:R/G/B", with R, G and B hex strings, 1-4 digits each | ||
| 868 | "rgbi:R/G/B", with R, G and B numbers in [0,1] | ||
| 869 | 867 | ||
| 870 | The result is normalized to a maximum value of 65535 per component. */ | 868 | "#RGB", with R, G and B hex strings of equal length, 1-4 digits each. |
| 869 | "rgb:R/G/B", with R, G and B hex strings, 1-4 digits each. | ||
| 870 | "rgbi:R/G/B", with R, G and B numbers in [0,1]. | ||
| 871 | |||
| 872 | If the function succeeds, it assigns to each of the components *R, | ||
| 873 | *G, and *B a value normalized to be in the [0, 65535] range. If | ||
| 874 | the function fails, some or all of the components remain unassigned. */ | ||
| 871 | bool | 875 | bool |
| 872 | parse_color_spec (const char *s, | 876 | parse_color_spec (const char *spec, |
| 873 | unsigned short *r, unsigned short *g, unsigned short *b) | 877 | unsigned short *r, unsigned short *g, unsigned short *b) |
| 874 | { | 878 | { |
| 875 | int len = strlen (s); | 879 | int len = strlen (spec); |
| 876 | if (s[0] == '#') | 880 | if (spec[0] == '#') |
| 877 | { | 881 | { |
| 878 | if ((len - 1) % 3 == 0) | 882 | if ((len - 1) % 3 == 0) |
| 879 | { | 883 | { |
| 880 | int n = (len - 1) / 3; | 884 | int n = (len - 1) / 3; |
| 881 | return ( parse_hex_color_comp (s + 1 + 0 * n, s + 1 + 1 * n, r) | 885 | return ( parse_hex_color_comp (spec + 1 + 0 * n, |
| 882 | && parse_hex_color_comp (s + 1 + 1 * n, s + 1 + 2 * n, g) | 886 | spec + 1 + 1 * n, r) |
| 883 | && parse_hex_color_comp (s + 1 + 2 * n, s + 1 + 3 * n, b)); | 887 | && parse_hex_color_comp (spec + 1 + 1 * n, |
| 888 | spec + 1 + 2 * n, g) | ||
| 889 | && parse_hex_color_comp (spec + 1 + 2 * n, | ||
| 890 | spec + 1 + 3 * n, b)); | ||
| 884 | } | 891 | } |
| 885 | } | 892 | } |
| 886 | else if (strncmp (s, "rgb:", 4) == 0) | 893 | else if (strncmp (spec, "rgb:", 4) == 0) |
| 887 | { | 894 | { |
| 888 | char *sep1, *sep2; | 895 | char *sep1, *sep2; |
| 889 | return ((sep1 = strchr (s + 4, '/')) != NULL | 896 | return ((sep1 = strchr (spec + 4, '/')) != NULL |
| 890 | && (sep2 = strchr (sep1 + 1, '/')) != NULL | 897 | && (sep2 = strchr (sep1 + 1, '/')) != NULL |
| 891 | && parse_hex_color_comp (s + 4, sep1, r) | 898 | && parse_hex_color_comp (spec + 4, sep1, r) |
| 892 | && parse_hex_color_comp (sep1 + 1, sep2, g) | 899 | && parse_hex_color_comp (sep1 + 1, sep2, g) |
| 893 | && parse_hex_color_comp (sep2 + 1, s + len, b)); | 900 | && parse_hex_color_comp (sep2 + 1, spec + len, b)); |
| 894 | } | 901 | } |
| 895 | else if (strncmp (s, "rgbi:", 5) == 0) | 902 | else if (strncmp (spec, "rgbi:", 5) == 0) |
| 896 | { | 903 | { |
| 897 | char *sep1, *sep2; | 904 | char *sep1, *sep2; |
| 898 | double red, green, blue; | 905 | double red, green, blue; |
| 899 | if ((sep1 = strchr (s + 5, '/')) != NULL | 906 | if ((sep1 = strchr (spec + 5, '/')) != NULL |
| 900 | && (sep2 = strchr (sep1 + 1, '/')) != NULL | 907 | && (sep2 = strchr (sep1 + 1, '/')) != NULL |
| 901 | && (red = parse_float_color_comp (s + 5, sep1)) >= 0 | 908 | && (red = parse_float_color_comp (spec + 5, sep1)) >= 0 |
| 902 | && (green = parse_float_color_comp (sep1 + 1, sep2)) >= 0 | 909 | && (green = parse_float_color_comp (sep1 + 1, sep2)) >= 0 |
| 903 | && (blue = parse_float_color_comp (sep2 + 1, s + len)) >= 0) | 910 | && (blue = parse_float_color_comp (sep2 + 1, spec + len)) >= 0) |
| 904 | { | 911 | { |
| 905 | *r = lrint (red * 65535); | 912 | *r = lrint (red * 65535); |
| 906 | *g = lrint (green * 65535); | 913 | *g = lrint (green * 65535); |
| @@ -911,25 +918,26 @@ parse_color_spec (const char *s, | |||
| 911 | return false; | 918 | return false; |
| 912 | } | 919 | } |
| 913 | 920 | ||
| 914 | DEFUN ("internal-color-values-from-color-spec", | 921 | DEFUN ("color-values-from-color-spec", |
| 915 | Finternal_color_values_from_color_spec, | 922 | Fcolor_values_from_color_spec, |
| 916 | Sinternal_color_values_from_color_spec, | 923 | Scolor_values_from_color_spec, |
| 917 | 1, 1, 0, | 924 | 1, 1, 0, |
| 918 | doc: /* Parse STRING as a numeric color and return (RED GREEN BLUE). | 925 | doc: /* Parse color SPEC as a numeric color and return (RED GREEN BLUE). |
| 919 | Recognised formats for STRING are: | 926 | This function recognises the following formats for SPEC: |
| 927 | |||
| 928 | #RGB, where R, G and B are hex numbers of equal length, 1-4 digits each. | ||
| 929 | rgb:R/G/B, where R, G, and B are hex numbers, 1-4 digits each. | ||
| 930 | rgbi:R/G/B, where R, G and B are floating-point numbers in [0,1]. | ||
| 920 | 931 | ||
| 921 | #RGB, where R, G and B are hex numbers of equal length, 1-4 digits each | 932 | If SPEC is not in one of the above forms, return nil. |
| 922 | rgb:R/G/B, where R, G, and B are hex numbers, 1-4 digits each | ||
| 923 | rgbi:R/G/B, where R, G and B are floating-point numbers in [0,1] | ||
| 924 | 933 | ||
| 925 | The result is normalized to a maximum value of 65535 per component, | 934 | Each of the 3 integer members of the resulting list, RED, GREEN, and BLUE, |
| 926 | forming a list of three integers in [0,65535]. | 935 | is normalized to have its value in [0,65535]. */) |
| 927 | If STRING is not in one of the above forms, return nil. */) | 936 | (Lisp_Object spec) |
| 928 | (Lisp_Object string) | ||
| 929 | { | 937 | { |
| 930 | CHECK_STRING (string); | 938 | CHECK_STRING (spec); |
| 931 | unsigned short r, g, b; | 939 | unsigned short r, g, b; |
| 932 | return (parse_color_spec (SSDATA (string), &r, &g, &b) | 940 | return (parse_color_spec (SSDATA (spec), &r, &g, &b) |
| 933 | ? list3i (r, g, b) | 941 | ? list3i (r, g, b) |
| 934 | : Qnil); | 942 | : Qnil); |
| 935 | } | 943 | } |
| @@ -7133,5 +7141,5 @@ clear the face cache, see `clear-face-cache'. */); | |||
| 7133 | defsubr (&Sinternal_face_x_get_resource); | 7141 | defsubr (&Sinternal_face_x_get_resource); |
| 7134 | defsubr (&Sx_family_fonts); | 7142 | defsubr (&Sx_family_fonts); |
| 7135 | #endif | 7143 | #endif |
| 7136 | defsubr (&Sinternal_color_values_from_color_spec); | 7144 | defsubr (&Scolor_values_from_color_spec); |
| 7137 | } | 7145 | } |