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.
This commit is contained in:
Jan Djärv 2013-11-01 16:47:10 +01:00
parent 9bc236c826
commit 3c334c1412
9 changed files with 163 additions and 63 deletions

View 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.

View 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}.

View 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.

View file

@ -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
+++

View 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

View 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")

View 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

View 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
};

View 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,6 +1179,68 @@ COLOR must be a valid color name. */)
}
static unsigned long
load_color2 (struct frame *f, struct face *face, Lisp_Object name,
enum lface_attribute_index target_index, XColor *color)
{
eassert (STRINGP (name));
eassert (target_index == LFACE_FOREGROUND_INDEX
|| target_index == LFACE_BACKGROUND_INDEX
|| target_index == LFACE_UNDERLINE_INDEX
|| target_index == LFACE_OVERLINE_INDEX
|| target_index == LFACE_STRIKE_THROUGH_INDEX
|| target_index == LFACE_BOX_INDEX);
/* 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))
{
add_to_log ("Unable to load color \"%s\"", name, Qnil);
switch (target_index)
{
case LFACE_FOREGROUND_INDEX:
face->foreground_defaulted_p = 1;
color->pixel = FRAME_FOREGROUND_PIXEL (f);
break;
case LFACE_BACKGROUND_INDEX:
face->background_defaulted_p = 1;
color->pixel = FRAME_BACKGROUND_PIXEL (f);
break;
case LFACE_UNDERLINE_INDEX:
face->underline_defaulted_p = 1;
color->pixel = FRAME_FOREGROUND_PIXEL (f);
break;
case LFACE_OVERLINE_INDEX:
face->overline_color_defaulted_p = 1;
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);
break;
case LFACE_BOX_INDEX:
face->box_color_defaulted_p = 1;
color->pixel = FRAME_FOREGROUND_PIXEL (f);
break;
default:
emacs_abort ();
}
}
#ifdef GLYPH_DEBUG
else
++ncolors_allocated;
#endif
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,
@ -1193,63 +1258,7 @@ load_color (struct frame *f, struct face *face, Lisp_Object name,
enum lface_attribute_index target_index)
{
XColor color;
eassert (STRINGP (name));
eassert (target_index == LFACE_FOREGROUND_INDEX
|| target_index == LFACE_BACKGROUND_INDEX
|| target_index == LFACE_UNDERLINE_INDEX
|| target_index == LFACE_OVERLINE_INDEX
|| target_index == LFACE_STRIKE_THROUGH_INDEX
|| target_index == LFACE_BOX_INDEX);
/* 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))
{
add_to_log ("Unable to load color \"%s\"", name, Qnil);
switch (target_index)
{
case LFACE_FOREGROUND_INDEX:
face->foreground_defaulted_p = 1;
color.pixel = FRAME_FOREGROUND_PIXEL (f);
break;
case LFACE_BACKGROUND_INDEX:
face->background_defaulted_p = 1;
color.pixel = FRAME_BACKGROUND_PIXEL (f);
break;
case LFACE_UNDERLINE_INDEX:
face->underline_defaulted_p = 1;
color.pixel = FRAME_FOREGROUND_PIXEL (f);
break;
case LFACE_OVERLINE_INDEX:
face->overline_color_defaulted_p = 1;
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);
break;
case LFACE_BOX_INDEX:
face->box_color_defaulted_p = 1;
color.pixel = FRAME_FOREGROUND_PIXEL (f);
break;
default:
emacs_abort ();
}
}
#ifdef GLYPH_DEBUG
else
++ncolors_allocated;
#endif
return color.pixel;
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");