diff options
| author | Miles Bader | 2004-06-04 23:30:03 +0000 |
|---|---|---|
| committer | Miles Bader | 2004-06-04 23:30:03 +0000 |
| commit | 8e330b2257db682ec067cdd72d8e7a4580f97505 (patch) | |
| tree | 08a967c7ac797f88fe7b9aa2ec18ab2bd1439aa0 /src | |
| parent | bfd40f00f773024159ca04ee393030115393ac6a (diff) | |
| download | emacs-8e330b2257db682ec067cdd72d8e7a4580f97505.tar.gz emacs-8e330b2257db682ec067cdd72d8e7a4580f97505.zip | |
Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-374
(tty_supports_face_attributes_p): Ensure attributes differ from default
This implements the property of `display-supports-face-attributes-p'
which says that the specified attributes must be distinguishable from
those of the default face.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/xfaces.c | 163 |
2 files changed, 97 insertions, 71 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 7b3acf8f578..d9000d6dd05 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2004-06-05 Miles Bader <miles@gnu.org> | ||
| 2 | |||
| 3 | * xfaces.c (tty_supports_face_attributes_p): Make sure the specified | ||
| 4 | attributes have different values than the default face. | ||
| 5 | |||
| 1 | 2004-06-04 Eli Zaretskii <eliz@gnu.org> | 6 | 2004-06-04 Eli Zaretskii <eliz@gnu.org> |
| 2 | 7 | ||
| 3 | * xfaces.c (x_supports_face_attributes_p): Make this function | 8 | * xfaces.c (x_supports_face_attributes_p): Make this function |
diff --git a/src/xfaces.c b/src/xfaces.c index 7937cc5e430..fc665ce3bd5 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -5750,26 +5750,15 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector, | |||
| 5750 | default face for display, can be represented in a way that's | 5750 | default face for display, can be represented in a way that's |
| 5751 | 5751 | ||
| 5752 | \(1) different in appearance than the default face, and | 5752 | \(1) different in appearance than the default face, and |
| 5753 | \(2) `close in spirit' to what the attributes specify, if not exact. | 5753 | \(2) `close in spirit' to what the attributes specify, if not exact. */ |
| 5754 | |||
| 5755 | This function modifies ATTRS by merging from the default face. */ | ||
| 5756 | 5754 | ||
| 5757 | static int | 5755 | static int |
| 5758 | x_supports_face_attributes_p (f, attrs) | 5756 | x_supports_face_attributes_p (f, attrs, def_face) |
| 5759 | struct frame *f; | 5757 | struct frame *f; |
| 5760 | Lisp_Object *attrs; | 5758 | Lisp_Object *attrs; |
| 5759 | struct face *def_face; | ||
| 5761 | { | 5760 | { |
| 5762 | Lisp_Object *def_attrs; | 5761 | Lisp_Object *def_attrs = def_face->lface; |
| 5763 | struct face *def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | ||
| 5764 | |||
| 5765 | if (def_face == NULL) | ||
| 5766 | { | ||
| 5767 | if (! realize_basic_faces (f)) | ||
| 5768 | signal_error ("Cannot realize default face", 0); | ||
| 5769 | def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | ||
| 5770 | } | ||
| 5771 | |||
| 5772 | def_attrs = def_face->lface; | ||
| 5773 | 5762 | ||
| 5774 | /* Check that other specified attributes are different that the default | 5763 | /* Check that other specified attributes are different that the default |
| 5775 | face. */ | 5764 | face. */ |
| @@ -5848,57 +5837,35 @@ x_supports_face_attributes_p (f, attrs) | |||
| 5848 | substitution of a `dim' face for italic. */ | 5837 | substitution of a `dim' face for italic. */ |
| 5849 | 5838 | ||
| 5850 | static int | 5839 | static int |
| 5851 | tty_supports_face_attributes_p (f, attrs) | 5840 | tty_supports_face_attributes_p (f, attrs, def_face) |
| 5852 | struct frame *f; | 5841 | struct frame *f; |
| 5853 | Lisp_Object *attrs; | 5842 | Lisp_Object *attrs; |
| 5843 | struct face *def_face; | ||
| 5854 | { | 5844 | { |
| 5855 | int weight, i; | 5845 | int weight, i; |
| 5856 | Lisp_Object val, fg, bg; | 5846 | Lisp_Object val, fg, bg; |
| 5857 | XColor fg_tty_color, fg_std_color; | 5847 | XColor fg_tty_color, fg_std_color; |
| 5858 | XColor bg_tty_color, bg_std_color; | 5848 | XColor bg_tty_color, bg_std_color; |
| 5859 | unsigned test_caps = 0; | 5849 | unsigned test_caps = 0; |
| 5850 | Lisp_Object *def_attrs = def_face->lface; | ||
| 5860 | 5851 | ||
| 5861 | /* First check some easy-to-check stuff; ttys support none of the | ||
| 5862 | following attributes, so we can just return nil if any are requested. */ | ||
| 5863 | |||
| 5864 | /* stipple */ | ||
| 5865 | val = attrs[LFACE_STIPPLE_INDEX]; | ||
| 5866 | if (!UNSPECIFIEDP (val) && !NILP (val)) | ||
| 5867 | return 0; | ||
| 5868 | |||
| 5869 | /* font height */ | ||
| 5870 | val = attrs[LFACE_HEIGHT_INDEX]; | ||
| 5871 | if (!UNSPECIFIEDP (val) && !NILP (val)) | ||
| 5872 | return 0; | ||
| 5873 | 5852 | ||
| 5874 | /* font width */ | 5853 | /* First check some easy-to-check stuff; ttys support none of the |
| 5875 | val = attrs[LFACE_SWIDTH_INDEX]; | 5854 | following attributes, so we can just return false if any are requested |
| 5876 | if (!UNSPECIFIEDP (val) && !NILP (val) | 5855 | (even if `nominal' values are specified, we should still return false, |
| 5877 | && face_numeric_swidth (val) != XLFD_SWIDTH_MEDIUM) | 5856 | as that will be the same value that the default face uses). We |
| 5878 | return 0; | 5857 | consider :slant unsupportable on ttys, even though the face code |
| 5879 | 5858 | actually `fakes' them using a dim attribute if possible. This is | |
| 5880 | /* overline */ | 5859 | because the faked result is too different from what the face |
| 5881 | val = attrs[LFACE_OVERLINE_INDEX]; | 5860 | specifies. */ |
| 5882 | if (!UNSPECIFIEDP (val) && !NILP (val)) | 5861 | if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX]) |
| 5883 | return 0; | 5862 | || !UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX]) |
| 5884 | 5863 | || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX]) | |
| 5885 | /* strike-through */ | 5864 | || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]) |
| 5886 | val = attrs[LFACE_STRIKE_THROUGH_INDEX]; | 5865 | || !UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX]) |
| 5887 | if (!UNSPECIFIEDP (val) && !NILP (val)) | 5866 | || !UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX]) |
| 5888 | return 0; | 5867 | || !UNSPECIFIEDP (attrs[LFACE_BOX_INDEX]) |
| 5889 | 5868 | || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])) | |
| 5890 | /* boxes */ | ||
| 5891 | val = attrs[LFACE_BOX_INDEX]; | ||
| 5892 | if (!UNSPECIFIEDP (val) && !NILP (val)) | ||
| 5893 | return 0; | ||
| 5894 | |||
| 5895 | /* slant (italics/oblique); We consider any non-default value | ||
| 5896 | unsupportable on ttys, even though the face code actually `fakes' | ||
| 5897 | them using a dim attribute if possible. This is because the faked | ||
| 5898 | result is too different from what the face specifies. */ | ||
| 5899 | val = attrs[LFACE_SLANT_INDEX]; | ||
| 5900 | if (!UNSPECIFIEDP (val) && !NILP (val) | ||
| 5901 | && face_numeric_slant (val) != XLFD_SLANT_ROMAN) | ||
| 5902 | return 0; | 5869 | return 0; |
| 5903 | 5870 | ||
| 5904 | 5871 | ||
| @@ -5908,26 +5875,45 @@ tty_supports_face_attributes_p (f, attrs) | |||
| 5908 | weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]); | 5875 | weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]); |
| 5909 | if (weight >= 0) | 5876 | if (weight >= 0) |
| 5910 | { | 5877 | { |
| 5878 | int def_weight = face_numeric_weight (def_attrs[LFACE_WEIGHT_INDEX]); | ||
| 5879 | |||
| 5911 | if (weight > XLFD_WEIGHT_MEDIUM) | 5880 | if (weight > XLFD_WEIGHT_MEDIUM) |
| 5912 | test_caps = TTY_CAP_BOLD; | 5881 | { |
| 5882 | if (def_weight > XLFD_WEIGHT_MEDIUM) | ||
| 5883 | return 0; /* same as default */ | ||
| 5884 | test_caps = TTY_CAP_BOLD; | ||
| 5885 | } | ||
| 5913 | else if (weight < XLFD_WEIGHT_MEDIUM) | 5886 | else if (weight < XLFD_WEIGHT_MEDIUM) |
| 5914 | test_caps = TTY_CAP_DIM; | 5887 | { |
| 5888 | if (def_weight < XLFD_WEIGHT_MEDIUM) | ||
| 5889 | return 0; /* same as default */ | ||
| 5890 | test_caps = TTY_CAP_DIM; | ||
| 5891 | } | ||
| 5892 | else if (def_weight == XLFD_WEIGHT_MEDIUM) | ||
| 5893 | return 0; /* same as default */ | ||
| 5915 | } | 5894 | } |
| 5916 | 5895 | ||
| 5917 | /* underlining */ | 5896 | /* underlining */ |
| 5918 | val = attrs[LFACE_UNDERLINE_INDEX]; | 5897 | val = attrs[LFACE_UNDERLINE_INDEX]; |
| 5919 | if (!UNSPECIFIEDP (val) && !NILP (val)) | 5898 | if (!UNSPECIFIEDP (val)) |
| 5920 | { | 5899 | { |
| 5921 | if (STRINGP (val)) | 5900 | if (STRINGP (val)) |
| 5922 | return 0; /* ttys don't support colored underlines */ | 5901 | return 0; /* ttys can't use colored underlines */ |
| 5902 | else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX])) | ||
| 5903 | return 0; /* same as default */ | ||
| 5923 | else | 5904 | else |
| 5924 | test_caps |= TTY_CAP_UNDERLINE; | 5905 | test_caps |= TTY_CAP_UNDERLINE; |
| 5925 | } | 5906 | } |
| 5926 | 5907 | ||
| 5927 | /* inverse video */ | 5908 | /* inverse video */ |
| 5928 | val = attrs[LFACE_INVERSE_INDEX]; | 5909 | val = attrs[LFACE_INVERSE_INDEX]; |
| 5929 | if (!UNSPECIFIEDP (val) && !NILP (val)) | 5910 | if (!UNSPECIFIEDP (val)) |
| 5930 | test_caps |= TTY_CAP_INVERSE; | 5911 | { |
| 5912 | if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX])) | ||
| 5913 | return 0; /* same as default */ | ||
| 5914 | else | ||
| 5915 | test_caps |= TTY_CAP_INVERSE; | ||
| 5916 | } | ||
| 5931 | 5917 | ||
| 5932 | 5918 | ||
| 5933 | /* Color testing. */ | 5919 | /* Color testing. */ |
| @@ -5942,22 +5928,48 @@ tty_supports_face_attributes_p (f, attrs) | |||
| 5942 | fg = attrs[LFACE_FOREGROUND_INDEX]; | 5928 | fg = attrs[LFACE_FOREGROUND_INDEX]; |
| 5943 | if (STRINGP (fg)) | 5929 | if (STRINGP (fg)) |
| 5944 | { | 5930 | { |
| 5945 | if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color)) | 5931 | Lisp_Object def_fg = def_attrs[LFACE_FOREGROUND_INDEX]; |
| 5946 | return 0; | 5932 | |
| 5933 | if (face_attr_equal_p (fg, def_fg)) | ||
| 5934 | return 0; /* same as default */ | ||
| 5935 | else if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color)) | ||
| 5936 | return 0; /* not a valid color */ | ||
| 5947 | else if (color_distance (&fg_tty_color, &fg_std_color) | 5937 | else if (color_distance (&fg_tty_color, &fg_std_color) |
| 5948 | > TTY_SAME_COLOR_THRESHOLD) | 5938 | > TTY_SAME_COLOR_THRESHOLD) |
| 5949 | return 0; | 5939 | return 0; /* displayed color is too different */ |
| 5940 | else | ||
| 5941 | /* Make sure the color is really different than the default. */ | ||
| 5942 | { | ||
| 5943 | XColor def_fg_color; | ||
| 5944 | if (tty_lookup_color (f, def_fg, &def_fg_color, 0) | ||
| 5945 | && (color_distance (&fg_tty_color, &def_fg_color) | ||
| 5946 | <= TTY_SAME_COLOR_THRESHOLD)) | ||
| 5947 | return 0; | ||
| 5948 | } | ||
| 5950 | } | 5949 | } |
| 5951 | 5950 | ||
| 5952 | /* Check if background color is close enough. */ | 5951 | /* Check if background color is close enough. */ |
| 5953 | bg = attrs[LFACE_BACKGROUND_INDEX]; | 5952 | bg = attrs[LFACE_BACKGROUND_INDEX]; |
| 5954 | if (STRINGP (bg)) | 5953 | if (STRINGP (bg)) |
| 5955 | { | 5954 | { |
| 5956 | if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color)) | 5955 | Lisp_Object def_bg = def_attrs[LFACE_FOREGROUND_INDEX]; |
| 5957 | return 0; | 5956 | |
| 5957 | if (face_attr_equal_p (bg, def_bg)) | ||
| 5958 | return 0; /* same as default */ | ||
| 5959 | else if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color)) | ||
| 5960 | return 0; /* not a valid color */ | ||
| 5958 | else if (color_distance (&bg_tty_color, &bg_std_color) | 5961 | else if (color_distance (&bg_tty_color, &bg_std_color) |
| 5959 | > TTY_SAME_COLOR_THRESHOLD) | 5962 | > TTY_SAME_COLOR_THRESHOLD) |
| 5960 | return 0; | 5963 | return 0; /* displayed color is too different */ |
| 5964 | else | ||
| 5965 | /* Make sure the color is really different than the default. */ | ||
| 5966 | { | ||
| 5967 | XColor def_bg_color; | ||
| 5968 | if (tty_lookup_color (f, def_bg, &def_bg_color, 0) | ||
| 5969 | && (color_distance (&bg_tty_color, &def_bg_color) | ||
| 5970 | <= TTY_SAME_COLOR_THRESHOLD)) | ||
| 5971 | return 0; | ||
| 5972 | } | ||
| 5961 | } | 5973 | } |
| 5962 | 5974 | ||
| 5963 | /* If both foreground and background are requested, see if the | 5975 | /* If both foreground and background are requested, see if the |
| @@ -6012,6 +6024,7 @@ face for italic. */) | |||
| 6012 | int supports, i; | 6024 | int supports, i; |
| 6013 | Lisp_Object frame; | 6025 | Lisp_Object frame; |
| 6014 | struct frame *f; | 6026 | struct frame *f; |
| 6027 | struct face *def_face; | ||
| 6015 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 6028 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 6016 | 6029 | ||
| 6017 | if (NILP (display)) | 6030 | if (NILP (display)) |
| @@ -6041,13 +6054,21 @@ face for italic. */) | |||
| 6041 | attrs[i] = Qunspecified; | 6054 | attrs[i] = Qunspecified; |
| 6042 | merge_face_vector_with_property (f, attrs, attributes); | 6055 | merge_face_vector_with_property (f, attrs, attributes); |
| 6043 | 6056 | ||
| 6057 | def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | ||
| 6058 | if (def_face == NULL) | ||
| 6059 | { | ||
| 6060 | if (! realize_basic_faces (f)) | ||
| 6061 | signal_error ("Cannot realize default face", 0); | ||
| 6062 | def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | ||
| 6063 | } | ||
| 6064 | |||
| 6044 | /* Dispatch to the appropriate handler. */ | 6065 | /* Dispatch to the appropriate handler. */ |
| 6045 | if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) | 6066 | if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) |
| 6046 | supports = tty_supports_face_attributes_p (f, attrs); | 6067 | supports = tty_supports_face_attributes_p (f, attrs, def_face); |
| 6047 | #ifdef HAVE_WINDOW_SYSTEM | 6068 | #ifdef HAVE_WINDOW_SYSTEM |
| 6048 | else | 6069 | else |
| 6049 | supports = x_supports_face_attributes_p (f, attrs); | 6070 | supports = x_supports_face_attributes_p (f, attrs, def_face); |
| 6050 | #endif /* HAVE_WINDOW_SYSTEM */ | 6071 | #endif |
| 6051 | 6072 | ||
| 6052 | return supports ? Qt : Qnil; | 6073 | return supports ? Qt : Qnil; |
| 6053 | } | 6074 | } |