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. */
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);
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. */
}
-/* 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
/* 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);
{
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:
++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);
}
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];
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
#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. */
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))
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. */
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))
|| (!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]))
DEFSYM (QCwidth, ":width");
DEFSYM (QCfont, ":font");
DEFSYM (QCfontset, ":fontset");
+ DEFSYM (QCdistant_foreground, ":distant-foreground");
DEFSYM (QCbold, ":bold");
DEFSYM (QCitalic, ":italic");
DEFSYM (QCoverline, ":overline");