changeset 55912:0b7bab25fcec

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.
author Miles Bader <miles@gnu.org>
date Fri, 04 Jun 2004 23:30:03 +0000
parents 584c842ba17a
children c663e2e97168 fe5ecb72e304
files src/ChangeLog src/xfaces.c
diffstat 2 files changed, 98 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Jun 04 23:27:33 2004 +0000
+++ b/src/ChangeLog	Fri Jun 04 23:30:03 2004 +0000
@@ -1,3 +1,8 @@
+2004-06-05  Miles Bader  <miles@gnu.org>
+
+	* xfaces.c (tty_supports_face_attributes_p): Make sure the specified
+	attributes have different values than the default face.
+
 2004-06-04  Eli Zaretskii  <eliz@gnu.org>
 
 	* xfaces.c (x_supports_face_attributes_p): Make this function
--- a/src/xfaces.c	Fri Jun 04 23:27:33 2004 +0000
+++ b/src/xfaces.c	Fri Jun 04 23:30:03 2004 +0000
@@ -5750,26 +5750,15 @@
    default face for display, can be represented in a way that's
 
     \(1) different in appearance than the default face, and
-    \(2) `close in spirit' to what the attributes specify, if not exact.
-
-   This function modifies ATTRS by merging from the default face.  */
+    \(2) `close in spirit' to what the attributes specify, if not exact.  */
 
 static int
-x_supports_face_attributes_p (f, attrs)
+x_supports_face_attributes_p (f, attrs, def_face)
      struct frame *f;
      Lisp_Object *attrs;
-{
-  Lisp_Object *def_attrs;
-  struct face *def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-
-  if (def_face == NULL)
-    {
-      if (! realize_basic_faces (f))
-	signal_error ("Cannot realize default face", 0);
-      def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-    }
-
-  def_attrs = def_face->lface;
+     struct face *def_face;
+{
+  Lisp_Object *def_attrs = def_face->lface;
 
   /* Check that other specified attributes are different that the default
      face.  */
@@ -5848,57 +5837,35 @@
    substitution of a `dim' face for italic.  */
 
 static int
-tty_supports_face_attributes_p (f, attrs)
+tty_supports_face_attributes_p (f, attrs, def_face)
      struct frame *f;
      Lisp_Object *attrs;
+     struct face *def_face;
 {
   int weight, i;
   Lisp_Object val, fg, bg;
   XColor fg_tty_color, fg_std_color;
   XColor bg_tty_color, bg_std_color;
   unsigned test_caps = 0;
+  Lisp_Object *def_attrs = def_face->lface;
+
 
   /* First check some easy-to-check stuff; ttys support none of the
-     following attributes, so we can just return nil if any are requested.  */
-
-  /* stipple */
-  val = attrs[LFACE_STIPPLE_INDEX];
-  if (!UNSPECIFIEDP (val) && !NILP (val))
-    return 0;
-
-  /* font height */
-  val = attrs[LFACE_HEIGHT_INDEX];
-  if (!UNSPECIFIEDP (val) && !NILP (val))
-    return 0;
-
-  /* font width */
-  val = attrs[LFACE_SWIDTH_INDEX];
-  if (!UNSPECIFIEDP (val) && !NILP (val)
-      && face_numeric_swidth (val) != XLFD_SWIDTH_MEDIUM)
-    return 0;
-
-  /* overline */
-  val = attrs[LFACE_OVERLINE_INDEX];
-  if (!UNSPECIFIEDP (val) && !NILP (val))
-    return 0;
-
-  /* strike-through */
-  val = attrs[LFACE_STRIKE_THROUGH_INDEX];
-  if (!UNSPECIFIEDP (val) && !NILP (val))
-    return 0;
-
-  /* boxes */
-  val = attrs[LFACE_BOX_INDEX];
-  if (!UNSPECIFIEDP (val) && !NILP (val))
-    return 0;
-
-  /* slant (italics/oblique); We consider any non-default value
-     unsupportable on ttys, even though the face code actually `fakes'
-     them using a dim attribute if possible.  This is because the faked
-     result is too different from what the face specifies.  */
-  val = attrs[LFACE_SLANT_INDEX];
-  if (!UNSPECIFIEDP (val) && !NILP (val)
-      && face_numeric_slant (val) != XLFD_SLANT_ROMAN)
+     following attributes, so we can just return false if any are requested
+     (even if `nominal' values are specified, we should still return false,
+     as that will be the same value that the default face uses).  We
+     consider :slant unsupportable on ttys, even though the face code
+     actually `fakes' them using a dim attribute if possible.  This is
+     because the faked result is too different from what the face
+     specifies.  */
+  if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
+      || !UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
+      || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
+      || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
+      || !UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
+      || !UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
+      || !UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
+      || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX]))
     return 0;
 
 
@@ -5908,26 +5875,45 @@
   weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
   if (weight >= 0)
     {
+      int def_weight = face_numeric_weight (def_attrs[LFACE_WEIGHT_INDEX]);
+
       if (weight > XLFD_WEIGHT_MEDIUM)
-	test_caps = TTY_CAP_BOLD;
+	{
+	  if (def_weight > XLFD_WEIGHT_MEDIUM)
+	    return 0;		/* same as default */
+	  test_caps = TTY_CAP_BOLD;
+	}
       else if (weight < XLFD_WEIGHT_MEDIUM)
-	test_caps = TTY_CAP_DIM;
+	{
+	  if (def_weight < XLFD_WEIGHT_MEDIUM)
+	    return 0;		/* same as default */
+	  test_caps = TTY_CAP_DIM;
+	}
+      else if (def_weight == XLFD_WEIGHT_MEDIUM)
+	return 0;		/* same as default */
     }
 
   /* underlining */
   val = attrs[LFACE_UNDERLINE_INDEX];
-  if (!UNSPECIFIEDP (val) && !NILP (val))
+  if (!UNSPECIFIEDP (val))
     {
       if (STRINGP (val))
-	return 0;		/* ttys don't support colored underlines */
+	return 0;		/* ttys can't use colored underlines */
+      else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
+	return 0;		/* same as default */
       else
 	test_caps |= TTY_CAP_UNDERLINE;
     }
 
   /* inverse video */
   val = attrs[LFACE_INVERSE_INDEX];
-  if (!UNSPECIFIEDP (val) && !NILP (val))
-    test_caps |= TTY_CAP_INVERSE;
+  if (!UNSPECIFIEDP (val))
+    {
+      if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
+	return 0;		/* same as default */
+      else
+	test_caps |= TTY_CAP_INVERSE;
+    }
 
 
   /* Color testing.  */
@@ -5942,22 +5928,48 @@
   fg = attrs[LFACE_FOREGROUND_INDEX];
   if (STRINGP (fg))
     {
-      if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color))
-	return 0;
+      Lisp_Object def_fg = def_attrs[LFACE_FOREGROUND_INDEX];
+
+      if (face_attr_equal_p (fg, def_fg))
+	return 0;		/* same as default */
+      else if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color))
+	return 0;		/* not a valid color */
       else if (color_distance (&fg_tty_color, &fg_std_color)
 	       > TTY_SAME_COLOR_THRESHOLD)
-	return 0;
+	return 0;		/* displayed color is too different */
+      else
+	/* Make sure the color is really different than the default.  */
+	{
+	  XColor def_fg_color;
+	  if (tty_lookup_color (f, def_fg, &def_fg_color, 0)
+	      && (color_distance (&fg_tty_color, &def_fg_color)
+		  <= TTY_SAME_COLOR_THRESHOLD))
+	    return 0;
+	}
     }
 
   /* Check if background color is close enough.  */
   bg = attrs[LFACE_BACKGROUND_INDEX];
   if (STRINGP (bg))
     {
-      if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color))
-	return 0;
+      Lisp_Object def_bg = def_attrs[LFACE_FOREGROUND_INDEX];
+
+      if (face_attr_equal_p (bg, def_bg))
+	return 0;		/* same as default */
+      else if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color))
+	return 0;		/* not a valid color */
       else if (color_distance (&bg_tty_color, &bg_std_color)
 	       > TTY_SAME_COLOR_THRESHOLD)
-	return 0;
+	return 0;		/* displayed color is too different */
+      else
+	/* Make sure the color is really different than the default.  */
+	{
+	  XColor def_bg_color;
+	  if (tty_lookup_color (f, def_bg, &def_bg_color, 0)
+	      && (color_distance (&bg_tty_color, &def_bg_color)
+		  <= TTY_SAME_COLOR_THRESHOLD))
+	    return 0;
+	}
     }
 
   /* If both foreground and background are requested, see if the
@@ -6012,6 +6024,7 @@
   int supports, i;
   Lisp_Object frame;
   struct frame *f;
+  struct face *def_face;
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
 
   if (NILP (display))
@@ -6041,13 +6054,21 @@
     attrs[i] = Qunspecified;
   merge_face_vector_with_property (f, attrs, attributes);
 
+  def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+  if (def_face == NULL)
+    {
+      if (! realize_basic_faces (f))
+	signal_error ("Cannot realize default face", 0);
+      def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+    }
+
   /* Dispatch to the appropriate handler.  */
   if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
-    supports = tty_supports_face_attributes_p (f, attrs);
+    supports = tty_supports_face_attributes_p (f, attrs, def_face);
 #ifdef HAVE_WINDOW_SYSTEM
   else
-    supports = x_supports_face_attributes_p (f, attrs);
-#endif	/* HAVE_WINDOW_SYSTEM */
+    supports = x_supports_face_attributes_p (f, attrs, def_face);
+#endif
 
   return supports ? Qt : Qnil;
 }