aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiles Bader2004-06-04 06:00:59 +0000
committerMiles Bader2004-06-04 06:00:59 +0000
commit9717e36cff1ceda0bbebb2209c9fbbbd420af6d0 (patch)
tree4bcc228ea273eed5cf6e2f4134cb41d63635fca8 /src
parent5129f10c94db38789a92f396f568f993d726e7bd (diff)
downloademacs-9717e36cff1ceda0bbebb2209c9fbbbd420af6d0.tar.gz
emacs-9717e36cff1ceda0bbebb2209c9fbbbd420af6d0.zip
Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-370
Move `display-supports-face-attributes-p' entirely into C code Previously only the tty-related portion of display-supports-face-attributes-p was done in C. This just moves the graphical-display related bits into C too, which allows us to implement them properly (the previous attempt to do a halfway-proper job in lisp didn't work because of funny conditions during emacs startup).
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/xfaces.c574
2 files changed, 366 insertions, 219 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index fd108641f22..5c87b950403 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12004-06-04 Miles Bader <miles@gnu.org>
2
3 * xfaces.c (tty_supports_face_attributes_p): New function, mostly
4 from Ftty_supports_face_attributes_p.
5 (x_supports_face_attributes_p): New function.
6 (Ftty_supports_face_attributes_p): Function deleted.
7 (Fdisplay_supports_face_attributes_p): New function.
8 (syms_of_xfaces): Initialize Sdisplay_supports_face_attributes_p.
9 (face_attr_equal_p): New function
10 (lface_equal_p): Use it.
11
12004-06-03 Juanma Barranquero <lektu@terra.es> 122004-06-03 Juanma Barranquero <lektu@terra.es>
2 13
3 * w32fns.c (Fx_display_grayscale_p, Fw32_send_sys_command) 14 * w32fns.c (Fx_display_grayscale_p, Fw32_send_sys_command)
diff --git a/src/xfaces.c b/src/xfaces.c
index 2bd3f31d6ea..bd19d32c990 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4867,49 +4867,51 @@ If FRAME is omitted or nil, use the selected frame. */)
4867} 4867}
4868 4868
4869 4869
4870/* Compare face vectors V1 and V2 for equality. Value is non-zero if 4870/* Compare face-attribute values v1 and v2 for equality. Value is non-zero if
4871 all attributes are `equal'. Tries to be fast because this function 4871 all attributes are `equal'. Tries to be fast because this function
4872 is called quite often. */ 4872 is called quite often. */
4873 4873
4874static INLINE int 4874static INLINE int
4875lface_equal_p (v1, v2) 4875face_attr_equal_p (v1, v2)
4876 Lisp_Object *v1, *v2;
4877{ 4876{
4878 int i, equal_p = 1; 4877 /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
4878 and the other is specified. */
4879 if (XTYPE (v1) != XTYPE (v2))
4880 return 0;
4879 4881
4880 for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i) 4882 if (EQ (v1, v2))
4881 { 4883 return 1;
4882 Lisp_Object a = v1[i];
4883 Lisp_Object b = v2[i];
4884 4884
4885 /* Type can differ, e.g. when one attribute is unspecified, i.e. nil, 4885 switch (XTYPE (v1))
4886 and the other is specified. */ 4886 {
4887 equal_p = XTYPE (a) == XTYPE (b); 4887 case Lisp_String:
4888 if (!equal_p) 4888 if (SBYTES (v1) != SBYTES (v2))
4889 break; 4889 return 0;
4890 4890
4891 if (!EQ (a, b)) 4891 return bcmp (SDATA (v1), SDATA (v2), SBYTES (v1)) == 0;
4892 {
4893 switch (XTYPE (a))
4894 {
4895 case Lisp_String:
4896 equal_p = ((SBYTES (a)
4897 == SBYTES (b))
4898 && bcmp (SDATA (a), SDATA (b),
4899 SBYTES (a)) == 0);
4900 break;
4901 4892
4902 case Lisp_Int: 4893 case Lisp_Int:
4903 case Lisp_Symbol: 4894 case Lisp_Symbol:
4904 equal_p = 0; 4895 return 0;
4905 break;
4906 4896
4907 default: 4897 default:
4908 equal_p = !NILP (Fequal (a, b)); 4898 return !NILP (Fequal (v1, v2));
4909 break;
4910 }
4911 }
4912 } 4899 }
4900}
4901
4902
4903/* Compare face vectors V1 and V2 for equality. Value is non-zero if
4904 all attributes are `equal'. Tries to be fast because this function
4905 is called quite often. */
4906
4907static INLINE int
4908lface_equal_p (v1, v2)
4909 Lisp_Object *v1, *v2;
4910{
4911 int i, equal_p = 1;
4912
4913 for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
4914 equal_p = face_attr_equal_p (v1[i], v2[i]);
4913 4915
4914 return equal_p; 4916 return equal_p;
4915} 4917}
@@ -5209,192 +5211,6 @@ If FRAME is unspecified or nil, the current frame is used. */)
5209 5211
5210 5212
5211/*********************************************************************** 5213/***********************************************************************
5212 Face capability testing for ttys
5213 ***********************************************************************/
5214
5215
5216/* If the distance (as returned by color_distance) between two colors is
5217 less than this, then they are considered the same, for determining
5218 whether a color is supported or not. The range of values is 0-65535. */
5219
5220#define TTY_SAME_COLOR_THRESHOLD 10000
5221
5222
5223DEFUN ("tty-supports-face-attributes-p",
5224 Ftty_supports_face_attributes_p, Stty_supports_face_attributes_p,
5225 1, 2, 0,
5226 doc: /* Return non-nil if all the face attributes in ATTRIBUTES are supported.
5227The optional argument FRAME is the frame on which to test; if it is nil
5228or unspecified, then the current frame is used. If FRAME is not a tty
5229frame, then nil is returned.
5230
5231The definition of `supported' is somewhat heuristic, but basically means
5232that a face containing all the attributes in ATTRIBUTES, when merged
5233with the default face for display, can be represented in a way that's
5234
5235 \(1) different in appearance than the default face, and
5236 \(2) `close in spirit' to what the attributes specify, if not exact.
5237
5238Point (2) implies that a `:weight black' attribute will be satisfied
5239by any terminal that can display bold, and a `:foreground "yellow"' as
5240long as the terminal can display a yellowish color, but `:slant italic'
5241will _not_ be satisfied by the tty display code's automatic
5242substitution of a `dim' face for italic. */)
5243 (attributes, frame)
5244 Lisp_Object attributes, frame;
5245{
5246 int weight, i;
5247 struct frame *f;
5248 Lisp_Object val, fg, bg;
5249 XColor fg_tty_color, fg_std_color;
5250 XColor bg_tty_color, bg_std_color;
5251 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5252 unsigned test_caps = 0;
5253
5254 if (NILP (frame))
5255 frame = selected_frame;
5256 CHECK_LIVE_FRAME (frame);
5257 f = XFRAME (frame);
5258
5259 for (i = 0; i < LFACE_VECTOR_SIZE; i++)
5260 attrs[i] = Qunspecified;
5261 merge_face_vector_with_property (f, attrs, attributes);
5262
5263 /* This function only works on ttys. */
5264 if (!FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f))
5265 return Qnil;
5266
5267 /* First check some easy-to-check stuff; ttys support none of the
5268 following attributes, so we can just return nil if any are requested. */
5269
5270 /* stipple */
5271 val = attrs[LFACE_STIPPLE_INDEX];
5272 if (!UNSPECIFIEDP (val) && !NILP (val))
5273 return Qnil;
5274
5275 /* font height */
5276 val = attrs[LFACE_HEIGHT_INDEX];
5277 if (!UNSPECIFIEDP (val) && !NILP (val))
5278 return Qnil;
5279
5280 /* font width */
5281 val = attrs[LFACE_SWIDTH_INDEX];
5282 if (!UNSPECIFIEDP (val) && !NILP (val)
5283 && face_numeric_swidth (val) != XLFD_SWIDTH_MEDIUM)
5284 return Qnil;
5285
5286 /* overline */
5287 val = attrs[LFACE_OVERLINE_INDEX];
5288 if (!UNSPECIFIEDP (val) && !NILP (val))
5289 return Qnil;
5290
5291 /* strike-through */
5292 val = attrs[LFACE_STRIKE_THROUGH_INDEX];
5293 if (!UNSPECIFIEDP (val) && !NILP (val))
5294 return Qnil;
5295
5296 /* boxes */
5297 val = attrs[LFACE_BOX_INDEX];
5298 if (!UNSPECIFIEDP (val) && !NILP (val))
5299 return Qnil;
5300
5301 /* slant (italics/oblique); We consider any non-default value
5302 unsupportable on ttys, even though the face code actually `fakes'
5303 them using a dim attribute if possible. This is because the faked
5304 result is too different from what the face specifies. */
5305 val = attrs[LFACE_SLANT_INDEX];
5306 if (!UNSPECIFIEDP (val) && !NILP (val)
5307 && face_numeric_slant (val) != XLFD_SLANT_ROMAN)
5308 return Qnil;
5309
5310
5311 /* Test for terminal `capabilities' (non-color character attributes). */
5312
5313 /* font weight (bold/dim) */
5314 weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
5315 if (weight >= 0)
5316 {
5317 if (weight > XLFD_WEIGHT_MEDIUM)
5318 test_caps = TTY_CAP_BOLD;
5319 else if (weight < XLFD_WEIGHT_MEDIUM)
5320 test_caps = TTY_CAP_DIM;
5321 }
5322
5323 /* underlining */
5324 val = attrs[LFACE_UNDERLINE_INDEX];
5325 if (!UNSPECIFIEDP (val) && !NILP (val))
5326 {
5327 if (STRINGP (val))
5328 return Qnil; /* ttys don't support colored underlines */
5329 else
5330 test_caps |= TTY_CAP_UNDERLINE;
5331 }
5332
5333 /* inverse video */
5334 val = attrs[LFACE_INVERSE_INDEX];
5335 if (!UNSPECIFIEDP (val) && !NILP (val))
5336 test_caps |= TTY_CAP_INVERSE;
5337
5338
5339 /* Color testing. */
5340
5341 /* Default the color indices in FG_TTY_COLOR and BG_TTY_COLOR, since
5342 we use them when calling `tty_capable_p' below, even if the face
5343 specifies no colors. */
5344 fg_tty_color.pixel = FACE_TTY_DEFAULT_FG_COLOR;
5345 bg_tty_color.pixel = FACE_TTY_DEFAULT_BG_COLOR;
5346
5347 /* Check if foreground color is close enough. */
5348 fg = attrs[LFACE_FOREGROUND_INDEX];
5349 if (STRINGP (fg))
5350 {
5351 if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color))
5352 return Qnil;
5353 else if (color_distance (&fg_tty_color, &fg_std_color)
5354 > TTY_SAME_COLOR_THRESHOLD)
5355 return Qnil;
5356 }
5357
5358 /* Check if background color is close enough. */
5359 bg = attrs[LFACE_BACKGROUND_INDEX];
5360 if (STRINGP (bg))
5361 {
5362 if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color))
5363 return Qnil;
5364 else if (color_distance (&bg_tty_color, &bg_std_color)
5365 > TTY_SAME_COLOR_THRESHOLD)
5366 return Qnil;
5367 }
5368
5369 /* If both foreground and background are requested, see if the
5370 distance between them is OK. We just check to see if the distance
5371 between the tty's foreground and background is close enough to the
5372 distance between the standard foreground and background. */
5373 if (STRINGP (fg) && STRINGP (bg))
5374 {
5375 int delta_delta
5376 = (color_distance (&fg_std_color, &bg_std_color)
5377 - color_distance (&fg_tty_color, &bg_tty_color));
5378 if (delta_delta > TTY_SAME_COLOR_THRESHOLD
5379 || delta_delta < -TTY_SAME_COLOR_THRESHOLD)
5380 return Qnil;
5381 }
5382
5383
5384 /* See if the capabilities we selected above are supported, with the
5385 given colors. */
5386 if (test_caps != 0 &&
5387 ! tty_capable_p (f, test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
5388 return Qnil;
5389
5390
5391 /* Hmmm, everything checks out, this terminal must support this face. */
5392 return Qt;
5393}
5394
5395
5396
5397/***********************************************************************
5398 Face Cache 5214 Face Cache
5399 ***********************************************************************/ 5215 ***********************************************************************/
5400 5216
@@ -5914,6 +5730,326 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
5914 5730
5915 5731
5916/*********************************************************************** 5732/***********************************************************************
5733 Face capability testing
5734 ***********************************************************************/
5735
5736
5737/* If the distance (as returned by color_distance) between two colors is
5738 less than this, then they are considered the same, for determining
5739 whether a color is supported or not. The range of values is 0-65535. */
5740
5741#define TTY_SAME_COLOR_THRESHOLD 10000
5742
5743
5744/* Return non-zero if all the face attributes in ATTRS are supported
5745 on the window-system frame F.
5746
5747 The definition of `supported' is somewhat heuristic, but basically means
5748 that a face containing all the attributes in ATTRS, when merged with the
5749 default face for display, can be represented in a way that's
5750
5751 \(1) different in appearance than the default face, and
5752 \(2) `close in spirit' to what the attributes specify, if not exact.
5753
5754 This function modifies ATTRS by merging from the default face. */
5755
5756static int
5757x_supports_face_attributes_p (f, attrs)
5758 struct frame *f;
5759 Lisp_Object *attrs;
5760{
5761 Lisp_Object *def_attrs;
5762 struct face *def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5763
5764 if (def_face == NULL)
5765 {
5766 if (! realize_basic_faces (f))
5767 signal_error ("Cannot realize default face", 0);
5768 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5769 }
5770
5771 def_attrs = def_face->lface;
5772
5773 /* Check that other specified attributes are different that the default
5774 face. */
5775 if ((!UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
5776 && face_attr_equal_p (attrs[LFACE_UNDERLINE_INDEX],
5777 def_attrs[LFACE_UNDERLINE_INDEX]))
5778 || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
5779 && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX],
5780 def_attrs[LFACE_INVERSE_INDEX]))
5781 || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
5782 && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
5783 def_attrs[LFACE_FOREGROUND_INDEX]))
5784 || (!UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
5785 && face_attr_equal_p (attrs[LFACE_BACKGROUND_INDEX],
5786 def_attrs[LFACE_BACKGROUND_INDEX]))
5787 || (!UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
5788 && face_attr_equal_p (attrs[LFACE_STIPPLE_INDEX],
5789 def_attrs[LFACE_STIPPLE_INDEX]))
5790 || (!UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
5791 && face_attr_equal_p (attrs[LFACE_OVERLINE_INDEX],
5792 def_attrs[LFACE_OVERLINE_INDEX]))
5793 || (!UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
5794 && face_attr_equal_p (attrs[LFACE_STRIKE_THROUGH_INDEX],
5795 def_attrs[LFACE_STRIKE_THROUGH_INDEX]))
5796 || (!UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
5797 && face_attr_equal_p (attrs[LFACE_BOX_INDEX],
5798 def_attrs[LFACE_BOX_INDEX])))
5799 return 0;
5800
5801 /* Check font-related attributes, as those are the most commonly
5802 "unsupported" on a window-system (because of missing fonts). */
5803 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
5804 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
5805 || !UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
5806 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
5807 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
5808 || !UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX]))
5809 {
5810 struct face *face;
5811 Lisp_Object merged_attrs[LFACE_VECTOR_SIZE];
5812
5813 bcopy (def_attrs, merged_attrs, sizeof merged_attrs);
5814
5815 merge_face_vectors (f, attrs, merged_attrs, Qnil);
5816
5817 face = FACE_FROM_ID (f, lookup_face (f, merged_attrs, 0, 0));
5818
5819 if (! face)
5820 signal_error ("cannot make face", 0);
5821
5822 /* If the font is the same, then not supported. */
5823 if (face->font == def_face->font)
5824 return 0;
5825 }
5826
5827 /* Everything checks out, this face is supported. */
5828 return 1;
5829}
5830
5831
5832/* Return non-zero if all the face attributes in ATTRS are supported
5833 on the tty frame F.
5834
5835 The definition of `supported' is somewhat heuristic, but basically means
5836 that a face containing all the attributes in ATTRS, when merged
5837 with the default face for display, can be represented in a way that's
5838
5839 \(1) different in appearance than the default face, and
5840 \(2) `close in spirit' to what the attributes specify, if not exact.
5841
5842 Point (2) implies that a `:weight black' attribute will be satisfied
5843 by any terminal that can display bold, and a `:foreground "yellow"' as
5844 long as the terminal can display a yellowish color, but `:slant italic'
5845 will _not_ be satisfied by the tty display code's automatic
5846 substitution of a `dim' face for italic. */
5847
5848static int
5849tty_supports_face_attributes_p (f, attrs)
5850 struct frame *f;
5851 Lisp_Object *attrs;
5852{
5853 int weight, i;
5854 Lisp_Object val, fg, bg;
5855 XColor fg_tty_color, fg_std_color;
5856 XColor bg_tty_color, bg_std_color;
5857 unsigned test_caps = 0;
5858
5859 /* First check some easy-to-check stuff; ttys support none of the
5860 following attributes, so we can just return nil if any are requested. */
5861
5862 /* stipple */
5863 val = attrs[LFACE_STIPPLE_INDEX];
5864 if (!UNSPECIFIEDP (val) && !NILP (val))
5865 return 0;
5866
5867 /* font height */
5868 val = attrs[LFACE_HEIGHT_INDEX];
5869 if (!UNSPECIFIEDP (val) && !NILP (val))
5870 return 0;
5871
5872 /* font width */
5873 val = attrs[LFACE_SWIDTH_INDEX];
5874 if (!UNSPECIFIEDP (val) && !NILP (val)
5875 && face_numeric_swidth (val) != XLFD_SWIDTH_MEDIUM)
5876 return 0;
5877
5878 /* overline */
5879 val = attrs[LFACE_OVERLINE_INDEX];
5880 if (!UNSPECIFIEDP (val) && !NILP (val))
5881 return 0;
5882
5883 /* strike-through */
5884 val = attrs[LFACE_STRIKE_THROUGH_INDEX];
5885 if (!UNSPECIFIEDP (val) && !NILP (val))
5886 return 0;
5887
5888 /* boxes */
5889 val = attrs[LFACE_BOX_INDEX];
5890 if (!UNSPECIFIEDP (val) && !NILP (val))
5891 return 0;
5892
5893 /* slant (italics/oblique); We consider any non-default value
5894 unsupportable on ttys, even though the face code actually `fakes'
5895 them using a dim attribute if possible. This is because the faked
5896 result is too different from what the face specifies. */
5897 val = attrs[LFACE_SLANT_INDEX];
5898 if (!UNSPECIFIEDP (val) && !NILP (val)
5899 && face_numeric_slant (val) != XLFD_SLANT_ROMAN)
5900 return 0;
5901
5902
5903 /* Test for terminal `capabilities' (non-color character attributes). */
5904
5905 /* font weight (bold/dim) */
5906 weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
5907 if (weight >= 0)
5908 {
5909 if (weight > XLFD_WEIGHT_MEDIUM)
5910 test_caps = TTY_CAP_BOLD;
5911 else if (weight < XLFD_WEIGHT_MEDIUM)
5912 test_caps = TTY_CAP_DIM;
5913 }
5914
5915 /* underlining */
5916 val = attrs[LFACE_UNDERLINE_INDEX];
5917 if (!UNSPECIFIEDP (val) && !NILP (val))
5918 {
5919 if (STRINGP (val))
5920 return 0; /* ttys don't support colored underlines */
5921 else
5922 test_caps |= TTY_CAP_UNDERLINE;
5923 }
5924
5925 /* inverse video */
5926 val = attrs[LFACE_INVERSE_INDEX];
5927 if (!UNSPECIFIEDP (val) && !NILP (val))
5928 test_caps |= TTY_CAP_INVERSE;
5929
5930
5931 /* Color testing. */
5932
5933 /* Default the color indices in FG_TTY_COLOR and BG_TTY_COLOR, since
5934 we use them when calling `tty_capable_p' below, even if the face
5935 specifies no colors. */
5936 fg_tty_color.pixel = FACE_TTY_DEFAULT_FG_COLOR;
5937 bg_tty_color.pixel = FACE_TTY_DEFAULT_BG_COLOR;
5938
5939 /* Check if foreground color is close enough. */
5940 fg = attrs[LFACE_FOREGROUND_INDEX];
5941 if (STRINGP (fg))
5942 {
5943 if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color))
5944 return 0;
5945 else if (color_distance (&fg_tty_color, &fg_std_color)
5946 > TTY_SAME_COLOR_THRESHOLD)
5947 return 0;
5948 }
5949
5950 /* Check if background color is close enough. */
5951 bg = attrs[LFACE_BACKGROUND_INDEX];
5952 if (STRINGP (bg))
5953 {
5954 if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color))
5955 return 0;
5956 else if (color_distance (&bg_tty_color, &bg_std_color)
5957 > TTY_SAME_COLOR_THRESHOLD)
5958 return 0;
5959 }
5960
5961 /* If both foreground and background are requested, see if the
5962 distance between them is OK. We just check to see if the distance
5963 between the tty's foreground and background is close enough to the
5964 distance between the standard foreground and background. */
5965 if (STRINGP (fg) && STRINGP (bg))
5966 {
5967 int delta_delta
5968 = (color_distance (&fg_std_color, &bg_std_color)
5969 - color_distance (&fg_tty_color, &bg_tty_color));
5970 if (delta_delta > TTY_SAME_COLOR_THRESHOLD
5971 || delta_delta < -TTY_SAME_COLOR_THRESHOLD)
5972 return 0;
5973 }
5974
5975
5976 /* See if the capabilities we selected above are supported, with the
5977 given colors. */
5978 if (test_caps != 0 &&
5979 ! tty_capable_p (f, test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
5980 return 0;
5981
5982
5983 /* Hmmm, everything checks out, this terminal must support this face. */
5984 return 1;
5985}
5986
5987
5988DEFUN ("display-supports-face-attributes-p",
5989 Fdisplay_supports_face_attributes_p, Sdisplay_supports_face_attributes_p,
5990 1, 2, 0,
5991 doc: /* Return non-nil if all the face attributes in ATTRIBUTES are supported.
5992The optional argument DISPLAY can be a display name, a frame, or
5993nil (meaning the selected frame's display)
5994
5995The definition of `supported' is somewhat heuristic, but basically means
5996that a face containing all the attributes in ATTRIBUTES, when merged
5997with the default face for display, can be represented in a way that's
5998
5999 \(1) different in appearance than the default face, and
6000 \(2) `close in spirit' to what the attributes specify, if not exact.
6001
6002Point (2) implies that a `:weight black' attribute will be satisfied by
6003any display that can display bold, and a `:foreground \"yellow\"' as long
6004as it can display a yellowish color, but `:slant italic' will _not_ be
6005satisfied by the tty display code's automatic substitution of a `dim'
6006face for italic. */)
6007 (attributes, display)
6008 Lisp_Object attributes, display;
6009{
6010 int supports, i;
6011 Lisp_Object frame;
6012 struct frame *f;
6013 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6014
6015 if (NILP (display))
6016 frame = selected_frame;
6017 else if (FRAMEP (display))
6018 frame = display;
6019 else
6020 {
6021 /* Find any frame on DISPLAY. */
6022 Lisp_Object fl_tail;
6023
6024 frame = Qnil;
6025 for (fl_tail = Vframe_list; CONSP (fl_tail); fl_tail = XCDR (fl_tail))
6026 {
6027 frame = XCAR (fl_tail);
6028 if (!NILP (Fequal (Fcdr (Fassq (Qdisplay,
6029 XFRAME (frame)->param_alist)),
6030 display)))
6031 break;
6032 }
6033 }
6034
6035 CHECK_LIVE_FRAME (frame);
6036 f = XFRAME (frame);
6037
6038 for (i = 0; i < LFACE_VECTOR_SIZE; i++)
6039 attrs[i] = Qunspecified;
6040 merge_face_vector_with_property (f, attrs, attributes);
6041
6042 /* Dispatch to the appropriate handler. */
6043 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
6044 supports = tty_supports_face_attributes_p (f, attrs);
6045 else
6046 supports = x_supports_face_attributes_p (f, attrs);
6047
6048 return supports ? Qt : Qnil;
6049}
6050
6051
6052/***********************************************************************
5917 Font selection 6053 Font selection
5918 ***********************************************************************/ 6054 ***********************************************************************/
5919 6055
@@ -7713,7 +7849,7 @@ syms_of_xfaces ()
7713 defsubr (&Sinternal_merge_in_global_face); 7849 defsubr (&Sinternal_merge_in_global_face);
7714 defsubr (&Sface_font); 7850 defsubr (&Sface_font);
7715 defsubr (&Sframe_face_alist); 7851 defsubr (&Sframe_face_alist);
7716 defsubr (&Stty_supports_face_attributes_p); 7852 defsubr (&Sdisplay_supports_face_attributes_p);
7717 defsubr (&Scolor_distance); 7853 defsubr (&Scolor_distance);
7718 defsubr (&Sinternal_set_font_selection_order); 7854 defsubr (&Sinternal_set_font_selection_order);
7719 defsubr (&Sinternal_set_alternative_font_family_alist); 7855 defsubr (&Sinternal_set_alternative_font_family_alist);