]> git.eshelyaron.com Git - emacs.git/commitdiff
Add :distant-foreground to faces.
authorJan Djärv <jan.h.d@swipnet.se>
Fri, 1 Nov 2013 15:47:10 +0000 (16:47 +0100)
committerJan Djärv <jan.h.d@swipnet.se>
Fri, 1 Nov 2013 15:47:10 +0000 (16:47 +0100)
* doc/lispref/display.texi (Face Attributes): Document :distant-foreground.

* etc/NEWS: Mention :distant-foreground.

* lisp/faces.el (face-x-resources): Add :distant-foreground.
(region): Use :distant-foreground for gtk and ns.

* src/dispextern.h (lface_attribute_index): Add
LFACE_DISTANT_FOREGROUND_INDEX.

* src/xfaces.c: Declare color_distance.
(QCdistant_foreground): New variable.
(NEAR_SAME_COLOR_THRESHOLD): New define.
(load_color2): New function.
(load_color): Call load_color2.
(load_face_colors): Call load_color2 and if distant-color is specified
calculate distant and use distant-color if colors are near.
(LFACE_DISTANT_FOREGROUND): New define.
(merge_face_ref, Finternal_set_lisp_face_attribute)
(Finternal_get_lisp_face_attribute)
(x_supports_face_attributes_p): Handle distant-foreground similar to
foreground.
(syms_of_xfaces): DEFSYM QCdistant_foreground.

doc/lispref/ChangeLog
doc/lispref/display.texi
etc/ChangeLog
etc/NEWS
lisp/ChangeLog
lisp/faces.el
src/ChangeLog
src/dispextern.h
src/xfaces.c

index fa081f1e7aaa0efc8cb96ee0ced2622f32562c41..cc214aa6dfa7c9785da02bdcc070ab0af88f5c1e 100644 (file)
@@ -1,3 +1,7 @@
+2013-11-01  Jan Djärv  <jan.h.d@swipnet.se>
+
+       * display.texi (Face Attributes): Document :distant-foreground.
+
 2013-10-30  Xue Fuqiao  <xfq.free@gmail.com>
 
        * display.texi (Abstract Display): Improve indexing.
index 07ab2c6745fa5c29bd217ea0af9f47d20e081360..ebb61a76b5911efa2d2ca3108343fab174839c04 100644 (file)
@@ -2036,6 +2036,15 @@ name, or a hexadecimal color specification.  @xref{Color Names}.  On
 black-and-white displays, certain shades of gray are implemented by
 stipple patterns.
 
+@item :distant-foreground
+Alternative foreground color, a string.  This is like @code{:foreground}
+but the color is only used as a foreground when the background color is
+near to the foreground that would have been used.  This is useful for
+example when marking text (i.e. the region face).  If the text has a foreground 
+that is visible with the region face, that foreground is used.
+If the foreground is near the region face background,
+@code{:distant-foreground} is used instead so the text is readable.
+
 @item :background
 Background color, a string.  The value can be a system-defined color
 name, or a hexadecimal color specification.  @xref{Color Names}.
index 6527a7ab365c836765ac0ba2d7390eb28bb8f386..d35fa8634414d1f557c6623199f4704457ba40f8 100644 (file)
@@ -1,3 +1,7 @@
+2013-11-01  Jan Djärv  <jan.h.d@swipnet.se>
+
+       * NEWS: Mention :distant-foreground.
+
 2013-10-16  Dmitry Gutov  <dgutov@yandex.ru>
 
        * NEWS: Mention the homepage-related changes in package.el.
index 1443173d2551b9f5d3dcebbd1a2f91ec6e98f7dd..4fed04da561b2d5ae223f43aa787e30760250a95 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -788,6 +788,10 @@ rather than inheriting from it (as do face specs set via Customize).
 *** New face characteristic (supports :underline (:style wave))
 specifies whether or not the terminal can display a wavy line.
 
+*** New face spec attribute :distant-foreground
+specifies foreground to use if background is near the foreground that would
+otherwise have been used.
+
 ** Image API
 
 +++
index 1493945af383298254abec58a234299c59ae87a4..b71b808fec8d2f8ed8e21e282d199da56427888b 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-01  Jan Djärv  <jan.h.d@swipnet.se>
+
+       * faces.el (face-x-resources): Add :distant-foreground.
+       (region): Use :distant-foreground for gtk and ns.
+
 2013-11-01  Tassilo Horn  <tsdh@gnu.org>
 
        Allow multiple bibliographies when BibLaTeX is used rathen than
index 9aef744b03732d9c3d00aa180b5d1beaca0335a3..8ff93874de0ae6999f9b15ce6b0d0a36a909752e 100644 (file)
@@ -274,6 +274,8 @@ If FRAME is omitted or nil, use the selected frame."
     (:weight (".attributeWeight" . "Face.AttributeWeight"))
     (:slant (".attributeSlant" . "Face.AttributeSlant"))
     (:foreground (".attributeForeground" . "Face.AttributeForeground"))
+    (:distant-foreground
+     (".attributeDistantForeground" . "Face.AttributeDistantForeground"))
     (:background (".attributeBackground" . "Face.AttributeBackground"))
     (:overline (".attributeOverline" . "Face.AttributeOverline"))
     (:strike-through (".attributeStrikeThrough" . "Face.AttributeStrikeThrough"))
@@ -2255,10 +2257,10 @@ terminal type to a different value."
   '((((class color) (min-colors 88) (background dark))
      :background "blue3")
     (((class color) (min-colors 88) (background light) (type gtk))
-     :foreground "gtk_selection_fg_color"
+     :distant-foreground "gtk_selection_fg_color"
      :background "gtk_selection_bg_color")
     (((class color) (min-colors 88) (background light) (type ns))
-     :foreground "ns_selection_fg_color"
+     :distant-foreground "ns_selection_fg_color"
      :background "ns_selection_bg_color")
     (((class color) (min-colors 88) (background light))
      :background "lightgoldenrod2")
index d7cf7d47b0b980f07c86054af2abf5a2d61871c9..8186e220d7d3ffde9dbd2e1f6c8aa248a7901783 100644 (file)
@@ -1,3 +1,22 @@
+2013-11-01  Jan Djärv  <jan.h.d@swipnet.se>
+
+       * xfaces.c: Declare color_distance.
+       (QCdistant_foreground): New variable.
+       (NEAR_SAME_COLOR_THRESHOLD): New define.
+       (load_color2): New function.
+       (load_color): Call load_color2.
+       (load_face_colors): Call load_color2 and if distant-color is specified
+       calculate distant and use distant-color if colors are near.
+       (LFACE_DISTANT_FOREGROUND): New define.
+       (merge_face_ref, Finternal_set_lisp_face_attribute)
+       (Finternal_get_lisp_face_attribute)
+       (x_supports_face_attributes_p): Handle distant-foreground similar to
+       foreground.
+       (syms_of_xfaces): DEFSYM QCdistant_foreground.
+
+       * dispextern.h (lface_attribute_index): Add
+       LFACE_DISTANT_FOREGROUND_INDEX.
+
 2013-11-01  Claudio Bley  <claudio.bley@googlemail.com>
 
        * image.c (pbm_next_char): New function.  See
index dd64ae1921fb7b1b6c21df58e6410e6820c1267b..22357a01c84ffb7d6183c048e0eb2314d4d943b8 100644 (file)
@@ -1543,6 +1543,7 @@ enum lface_attribute_index
   LFACE_FONT_INDEX,
   LFACE_INHERIT_INDEX,
   LFACE_FONTSET_INDEX,
+  LFACE_DISTANT_FOREGROUND_INDEX,
   LFACE_VECTOR_SIZE
 };
 
index f50fffc6419e6d325478ca154a22c7689af98991..72b62216abdcfd7073bb25ffd12e756ce987a1e3 100644 (file)
@@ -292,7 +292,7 @@ Lisp_Object QCwidth;
 static Lisp_Object QCfont, QCbold, QCitalic;
 static Lisp_Object QCreverse_video;
 static Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
-static Lisp_Object QCfontset;
+static Lisp_Object QCfontset, QCdistant_foreground;
 
 /* Symbols used for attribute values.  */
 
@@ -440,6 +440,7 @@ static struct face_cache *make_face_cache (struct frame *);
 static void free_face_cache (struct face_cache *);
 static int merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *,
                           int, struct named_merge_point *);
+static int color_distance (XColor *x, XColor *y);
 
 #ifdef HAVE_WINDOW_SYSTEM
 static void set_font_frame_param (Lisp_Object, Lisp_Object);
@@ -910,6 +911,8 @@ load_pixmap (struct frame *f, Lisp_Object name)
                                X Colors
  ***********************************************************************/
 
+#define NEAR_SAME_COLOR_THRESHOLD 30000
+
 /* Parse RGB_LIST, and fill in the RGB fields of COLOR.
    RGB_LIST should contain (at least) 3 lisp integers.
    Return 0 if there's a problem with RGB_LIST, otherwise return 1.  */
@@ -1176,24 +1179,10 @@ COLOR must be a valid color name.  */)
 }
 
 
-/* Load color with name NAME for use by face FACE on frame F.
-   TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
-   LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
-   LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX.  Value is the
-   pixel color.  If color cannot be loaded, display a message, and
-   return the foreground, background or underline color of F, but
-   record that fact in flags of the face so that we don't try to free
-   these colors.  */
-
-#ifndef MSDOS
-static
-#endif
-unsigned long
-load_color (struct frame *f, struct face *face, Lisp_Object name,
-           enum lface_attribute_index target_index)
+static unsigned long
+load_color2 (struct frame *f, struct face *face, Lisp_Object name,
+             enum lface_attribute_index target_index, XColor *color)
 {
-  XColor color;
-
   eassert (STRINGP (name));
   eassert (target_index == LFACE_FOREGROUND_INDEX
           || target_index == LFACE_BACKGROUND_INDEX
@@ -1204,7 +1193,7 @@ load_color (struct frame *f, struct face *face, Lisp_Object name,
 
   /* if the color map is full, defined_color will return a best match
      to the values in an existing cell. */
-  if (!defined_color (f, SSDATA (name), &color, 1))
+  if (!defined_color (f, SSDATA (name), color, 1))
     {
       add_to_log ("Unable to load color \"%s\"", name, Qnil);
 
@@ -1212,32 +1201,32 @@ load_color (struct frame *f, struct face *face, Lisp_Object name,
        {
        case LFACE_FOREGROUND_INDEX:
          face->foreground_defaulted_p = 1;
-         color.pixel = FRAME_FOREGROUND_PIXEL (f);
+         color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_BACKGROUND_INDEX:
          face->background_defaulted_p = 1;
-         color.pixel = FRAME_BACKGROUND_PIXEL (f);
+         color->pixel = FRAME_BACKGROUND_PIXEL (f);
          break;
 
        case LFACE_UNDERLINE_INDEX:
          face->underline_defaulted_p = 1;
-         color.pixel = FRAME_FOREGROUND_PIXEL (f);
+         color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_OVERLINE_INDEX:
          face->overline_color_defaulted_p = 1;
-         color.pixel = FRAME_FOREGROUND_PIXEL (f);
+         color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_STRIKE_THROUGH_INDEX:
          face->strike_through_color_defaulted_p = 1;
-         color.pixel = FRAME_FOREGROUND_PIXEL (f);
+         color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        case LFACE_BOX_INDEX:
          face->box_color_defaulted_p = 1;
-         color.pixel = FRAME_FOREGROUND_PIXEL (f);
+         color->pixel = FRAME_FOREGROUND_PIXEL (f);
          break;
 
        default:
@@ -1249,7 +1238,27 @@ load_color (struct frame *f, struct face *face, Lisp_Object name,
     ++ncolors_allocated;
 #endif
 
-  return color.pixel;
+  return color->pixel;
+}
+
+/* Load color with name NAME for use by face FACE on frame F.
+   TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
+   LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
+   LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX.  Value is the
+   pixel color.  If color cannot be loaded, display a message, and
+   return the foreground, background or underline color of F, but
+   record that fact in flags of the face so that we don't try to free
+   these colors.  */
+
+#ifndef MSDOS
+static
+#endif
+unsigned long
+load_color (struct frame *f, struct face *face, Lisp_Object name,
+           enum lface_attribute_index target_index)
+{
+  XColor color;
+  return load_color2 (f, face, name, target_index, &color);
 }
 
 
@@ -1264,7 +1273,8 @@ static void
 load_face_colors (struct frame *f, struct face *face,
                  Lisp_Object attrs[LFACE_VECTOR_SIZE])
 {
-  Lisp_Object fg, bg;
+  Lisp_Object fg, bg, dfg;
+  XColor xfg, xbg;
 
   bg = attrs[LFACE_BACKGROUND_INDEX];
   fg = attrs[LFACE_FOREGROUND_INDEX];
@@ -1289,8 +1299,18 @@ load_face_colors (struct frame *f, struct face *face,
       face->stipple = load_pixmap (f, Vface_default_stipple);
     }
 
-  face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
-  face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
+  face->background = load_color2 (f, face, bg, LFACE_BACKGROUND_INDEX, &xbg);
+  face->foreground = load_color2 (f, face, fg, LFACE_FOREGROUND_INDEX, &xfg);
+
+  dfg = attrs[LFACE_DISTANT_FOREGROUND_INDEX];
+  if (!NILP (dfg) && !UNSPECIFIEDP (dfg)
+      && color_distance (&xbg, &xfg) < NEAR_SAME_COLOR_THRESHOLD)
+    {
+      if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
+        face->background = load_color (f, face, dfg, LFACE_BACKGROUND_INDEX);
+      else
+        face->foreground = load_color (f, face, dfg, LFACE_FOREGROUND_INDEX);
+    }
 }
 
 #ifdef HAVE_X_WINDOWS
@@ -1721,6 +1741,8 @@ the WIDTH times as wide as FACE on FRAME.  */)
 #define LFACE_FONT(LFACE)          AREF ((LFACE), LFACE_FONT_INDEX)
 #define LFACE_INHERIT(LFACE)       AREF ((LFACE), LFACE_INHERIT_INDEX)
 #define LFACE_FONTSET(LFACE)       AREF ((LFACE), LFACE_FONTSET_INDEX)
+#define LFACE_DISTANT_FOREGROUND(LFACE) \
+  AREF ((LFACE), LFACE_DISTANT_FOREGROUND_INDEX)
 
 /* Non-zero if LFACE is a Lisp face.  A Lisp face is a vector of size
    LFACE_VECTOR_SIZE which has the symbol `face' in slot 0.  */
@@ -2449,6 +2471,13 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
                  else
                    err = 1;
                }
+             else if (EQ (keyword, QCdistant_foreground))
+               {
+                 if (STRINGP (value))
+                   to[LFACE_DISTANT_FOREGROUND_INDEX] = value;
+                 else
+                   err = 1;
+               }
              else if (EQ (keyword, QCbackground))
                {
                  if (STRINGP (value))
@@ -3005,6 +3034,23 @@ FRAME 0 means change the face on all frames, and change the default
       old_value = LFACE_FOREGROUND (lface);
       ASET (lface, LFACE_FOREGROUND_INDEX, value);
     }
+  else if (EQ (attr, QCdistant_foreground))
+    {
+      /* Compatibility with 20.x.  */
+      if (NILP (value))
+       value = Qunspecified;
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+       {
+         /* Don't check for valid color names here because it depends
+            on the frame (display) whether the color will be valid
+            when the face is realized.  */
+         CHECK_STRING (value);
+         if (SCHARS (value) == 0)
+           signal_error ("Empty distant-foreground color value", value);
+       }
+      old_value = LFACE_DISTANT_FOREGROUND (lface);
+      ASET (lface, LFACE_DISTANT_FOREGROUND_INDEX, value);
+    }
   else if (EQ (attr, QCbackground))
     {
       /* Compatibility with 20.x.  */
@@ -3649,6 +3695,8 @@ frames).  If FRAME is omitted or nil, use the selected frame.  */)
     value = LFACE_INVERSE (lface);
   else if (EQ (keyword, QCforeground))
     value = LFACE_FOREGROUND (lface);
+  else if (EQ (keyword, QCdistant_foreground))
+    value = LFACE_DISTANT_FOREGROUND (lface);
   else if (EQ (keyword, QCbackground))
     value = LFACE_BACKGROUND (lface);
   else if (EQ (keyword, QCstipple))
@@ -4688,6 +4736,9 @@ x_supports_face_attributes_p (struct frame *f,
       || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
          && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
                                def_attrs[LFACE_FOREGROUND_INDEX]))
+      || (!UNSPECIFIEDP (attrs[LFACE_DISTANT_FOREGROUND_INDEX])
+         && face_attr_equal_p (attrs[LFACE_DISTANT_FOREGROUND_INDEX],
+                               def_attrs[LFACE_DISTANT_FOREGROUND_INDEX]))
       || (!UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
          && face_attr_equal_p (attrs[LFACE_BACKGROUND_INDEX],
                                def_attrs[LFACE_BACKGROUND_INDEX]))
@@ -6361,6 +6412,7 @@ syms_of_xfaces (void)
   DEFSYM (QCwidth, ":width");
   DEFSYM (QCfont, ":font");
   DEFSYM (QCfontset, ":fontset");
+  DEFSYM (QCdistant_foreground, ":distant-foreground");
   DEFSYM (QCbold, ":bold");
   DEFSYM (QCitalic, ":italic");
   DEFSYM (QCoverline, ":overline");