From 3c334c1412e708585fddba61b7f91e0902a830f4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Fri, 1 Nov 2013 16:47:10 +0100 Subject: [PATCH] Add :distant-foreground to faces. * 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 | 4 ++ doc/lispref/display.texi | 9 ++++ etc/ChangeLog | 4 ++ etc/NEWS | 4 ++ lisp/ChangeLog | 5 ++ lisp/faces.el | 6 ++- src/ChangeLog | 19 +++++++ src/dispextern.h | 1 + src/xfaces.c | 110 ++++++++++++++++++++++++++++----------- 9 files changed, 131 insertions(+), 31 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index fa081f1e7a..cc214aa6df 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,7 @@ +2013-11-01 Jan Djärv + + * display.texi (Face Attributes): Document :distant-foreground. + 2013-10-30 Xue Fuqiao * display.texi (Abstract Display): Improve indexing. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 07ab2c6745..ebb61a76b5 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -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}. diff --git a/etc/ChangeLog b/etc/ChangeLog index 6527a7ab36..d35fa86344 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,7 @@ +2013-11-01 Jan Djärv + + * NEWS: Mention :distant-foreground. + 2013-10-16 Dmitry Gutov * NEWS: Mention the homepage-related changes in package.el. diff --git a/etc/NEWS b/etc/NEWS index 1443173d25..4fed04da56 100644 --- 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 +++ diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 1493945af3..b71b808fec 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2013-11-01 Jan Djärv + + * faces.el (face-x-resources): Add :distant-foreground. + (region): Use :distant-foreground for gtk and ns. + 2013-11-01 Tassilo Horn Allow multiple bibliographies when BibLaTeX is used rathen than diff --git a/lisp/faces.el b/lisp/faces.el index 9aef744b03..8ff93874de 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -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") diff --git a/src/ChangeLog b/src/ChangeLog index d7cf7d47b0..8186e220d7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,22 @@ +2013-11-01 Jan Djärv + + * 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 * image.c (pbm_next_char): New function. See diff --git a/src/dispextern.h b/src/dispextern.h index dd64ae1921..22357a01c8 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1543,6 +1543,7 @@ enum lface_attribute_index LFACE_FONT_INDEX, LFACE_INHERIT_INDEX, LFACE_FONTSET_INDEX, + LFACE_DISTANT_FOREGROUND_INDEX, LFACE_VECTOR_SIZE }; diff --git a/src/xfaces.c b/src/xfaces.c index f50fffc641..72b62216ab 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -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"); -- 2.20.1