#define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), QCignore_defface)
+/* True if face attribute ATTR is `reset'. */
+
+#define RESET_P(ATTR) EQ ((ATTR), Qreset)
+
/* Size of hash table of realized faces in face caches (should be a
prime number). */
{
eassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX])
+ || RESET_P (attrs[LFACE_FAMILY_INDEX])
|| STRINGP (attrs[LFACE_FAMILY_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_FOUNDRY_INDEX])
+ || RESET_P (attrs[LFACE_FOUNDRY_INDEX])
|| STRINGP (attrs[LFACE_FOUNDRY_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX])
+ || RESET_P (attrs[LFACE_SWIDTH_INDEX])
|| SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX])
+ || RESET_P (attrs[LFACE_HEIGHT_INDEX])
|| NUMBERP (attrs[LFACE_HEIGHT_INDEX])
|| FUNCTIONP (attrs[LFACE_HEIGHT_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_WEIGHT_INDEX])
+ || RESET_P (attrs[LFACE_WEIGHT_INDEX])
|| SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_SLANT_INDEX])
+ || RESET_P (attrs[LFACE_SLANT_INDEX])
|| SYMBOLP (attrs[LFACE_SLANT_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX])
+ || RESET_P (attrs[LFACE_UNDERLINE_INDEX])
|| SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
|| STRINGP (attrs[LFACE_UNDERLINE_INDEX])
|| CONSP (attrs[LFACE_UNDERLINE_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_EXTEND_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_EXTEND_INDEX])
+ || RESET_P (attrs[LFACE_EXTEND_INDEX])
|| SYMBOLP (attrs[LFACE_EXTEND_INDEX])
|| STRINGP (attrs[LFACE_EXTEND_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
+ || RESET_P (attrs[LFACE_OVERLINE_INDEX])
|| SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
|| STRINGP (attrs[LFACE_OVERLINE_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_STRIKE_THROUGH_INDEX])
+ || RESET_P (attrs[LFACE_STRIKE_THROUGH_INDEX])
|| SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
|| STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_BOX_INDEX])
+ || RESET_P (attrs[LFACE_BOX_INDEX])
|| SYMBOLP (attrs[LFACE_BOX_INDEX])
|| STRINGP (attrs[LFACE_BOX_INDEX])
|| FIXNUMP (attrs[LFACE_BOX_INDEX])
|| CONSP (attrs[LFACE_BOX_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_INVERSE_INDEX])
+ || RESET_P (attrs[LFACE_INVERSE_INDEX])
|| SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_FOREGROUND_INDEX])
+ || RESET_P (attrs[LFACE_FOREGROUND_INDEX])
|| STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_DISTANT_FOREGROUND_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_DISTANT_FOREGROUND_INDEX])
+ || RESET_P (attrs[LFACE_DISTANT_FOREGROUND_INDEX])
|| STRINGP (attrs[LFACE_DISTANT_FOREGROUND_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_BACKGROUND_INDEX])
+ || RESET_P (attrs[LFACE_BACKGROUND_INDEX])
|| STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_INHERIT_INDEX])
#ifdef HAVE_WINDOW_SYSTEM
eassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_STIPPLE_INDEX])
+ || RESET_P (attrs[LFACE_STIPPLE_INDEX])
|| SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
|| !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
eassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX])
+ || RESET_P (attrs[LFACE_FONT_INDEX])
|| FONTP (attrs[LFACE_FONT_INDEX]));
eassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX])
|| STRINGP (attrs[LFACE_FONTSET_INDEX])
+ || RESET_P (attrs[LFACE_FONTSET_INDEX])
|| NILP (attrs[LFACE_FONTSET_INDEX]));
#endif
}
#ifdef HAVE_WINDOW_SYSTEM
/* Set font-related attributes of Lisp face LFACE from FONT-OBJECT.
- If FORCE_P, set only unspecified attributes of LFACE. The
+ If FORCE_P is zero, set only unspecified attributes of LFACE. The
exception is `font' attribute. It is set to FONT_OBJECT regardless
of FORCE_P. */
Lisp_Object from[LFACE_VECTOR_SIZE], val;
bool ok = get_lface_attributes (w, f, face_name, from, false,
named_merge_points);
+ if (ok && !EQ (face_name, Qdefault))
+ {
+ struct face *deflt = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+ int i;
+ for (i = 1; i < LFACE_VECTOR_SIZE; i++)
+ if (EQ (from[i], Qreset))
+ from[i] = deflt->lface[i];
+ }
if (ok && (attr_filter == 0 /* No filter. */
|| (!NILP (from[attr_filter]) /* Filter, but specified. */
if (EQ (attr, QCfamily))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
CHECK_STRING (value);
if (SCHARS (value) == 0)
}
else if (EQ (attr, QCfoundry))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
CHECK_STRING (value);
if (SCHARS (value) == 0)
}
else if (EQ (attr, QCheight))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
if (EQ (face, Qdefault))
{
}
else if (EQ (attr, QCweight))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
CHECK_SYMBOL (value);
if (FONT_WEIGHT_NAME_NUMERIC (value) < 0)
}
else if (EQ (attr, QCslant))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
CHECK_SYMBOL (value);
if (FONT_SLANT_NAME_NUMERIC (value) < 0)
{
bool valid_p = false;
- if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
+ if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value) || RESET_P (value))
valid_p = true;
else if (NILP (value) || EQ (value, Qt))
valid_p = true;
}
else if (EQ (attr, QCoverline))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
if ((SYMBOLP (value)
&& !EQ (value, Qt)
&& !NILP (value))
}
else if (EQ (attr, QCstrike_through))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
if ((SYMBOLP (value)
&& !EQ (value, Qt)
&& !NILP (value))
if (EQ (value, Qt))
value = make_fixnum (1);
- if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
+ if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value) || RESET_P (value))
valid_p = true;
else if (NILP (value))
valid_p = true;
else if (EQ (attr, QCinverse_video)
|| EQ (attr, QCreverse_video))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
CHECK_SYMBOL (value);
if (!EQ (value, Qt) && !NILP (value))
}
else if (EQ (attr, QCextend))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
CHECK_SYMBOL (value);
if (!EQ (value, Qt) && !NILP (value))
/* Compatibility with 20.x. */
if (NILP (value))
value = Qunspecified;
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
/* Don't check for valid color names here because it depends
on the frame (display) whether the color will be valid
/* Compatibility with 20.x. */
if (NILP (value))
value = Qunspecified;
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
/* Don't check for valid color names here because it depends
on the frame (display) whether the color will be valid
/* Compatibility with 20.x. */
if (NILP (value))
value = Qunspecified;
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
/* Don't check for valid color names here because it depends
on the frame (display) whether the color will be valid
else if (EQ (attr, QCstipple))
{
#if defined (HAVE_WINDOW_SYSTEM)
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value)
&& !NILP (value)
&& NILP (Fbitmap_spec_p (value)))
signal_error ("Invalid stipple attribute", value);
}
else if (EQ (attr, QCwidth))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
CHECK_SYMBOL (value);
if (FONT_WIDTH_NAME_NUMERIC (value) < 0)
#ifdef HAVE_WINDOW_SYSTEM
if (EQ (frame, Qt) || FRAME_WINDOW_P (f))
{
- if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ if (!UNSPECIFIEDP (value)
+ && !IGNORE_DEFFACE_P (value)
+ && !RESET_P (value))
{
struct frame *f1;
Lisp_Object tmp;
old_value = LFACE_FONTSET (lface);
- tmp = Fquery_fontset (value, Qnil);
- if (NILP (tmp))
- signal_error ("Invalid fontset name", value);
+ if (!RESET_P (value))
+ {
+ tmp = Fquery_fontset (value, Qnil);
+ if (NILP (tmp))
+ signal_error ("Invalid fontset name", value);
+ }
ASET (lface, LFACE_FONTSET_INDEX, value = tmp);
}
#endif /* HAVE_WINDOW_SYSTEM */
else if (EQ (attr, QCbold))
{
old_value = LFACE_WEIGHT (lface);
- ASET (lface, LFACE_WEIGHT_INDEX, NILP (value) ? Qnormal : Qbold);
+ if (RESET_P (value))
+ ASET (lface, LFACE_WEIGHT_INDEX, value);
+ else
+ ASET (lface, LFACE_WEIGHT_INDEX, NILP (value) ? Qnormal : Qbold);
prop_index = FONT_WEIGHT_INDEX;
}
else if (EQ (attr, QCitalic))
{
attr = QCslant;
old_value = LFACE_SLANT (lface);
- ASET (lface, LFACE_SLANT_INDEX, NILP (value) ? Qnormal : Qitalic);
+ if (RESET_P (value))
+ ASET (lface, LFACE_SLANT_INDEX, value);
+ else
+ ASET (lface, LFACE_SLANT_INDEX, NILP (value) ? Qnormal : Qitalic);
prop_index = FONT_SLANT_INDEX;
}
else
/* Ensure that the face vector is fully specified by merging
the previously-cached vector. */
memcpy (attrs, oldface->lface, sizeof attrs);
+
+ /* Make explicit any attributes whose value is 'reset'. */
+ int i;
+ for (i = 1; i < LFACE_VECTOR_SIZE; i++)
+ if (EQ (lvec[i], Qreset))
+ lvec[i] = attrs[i];
+
merge_face_vectors (NULL, f, lvec, attrs, 0);
vcopy (local_lface, 0, attrs, LFACE_VECTOR_SIZE);
newface = realize_face (c, lvec, DEFAULT_FACE_ID);
return -1;
memcpy (attrs, default_face->lface, sizeof attrs);
+
+ /* Make explicit any attributes whose value is 'reset'. */
+ int i;
+ for (i = 1; i < LFACE_VECTOR_SIZE; i++)
+ if (EQ (symbol_attrs[i], Qreset))
+ symbol_attrs[i] = attrs[i];
+
merge_face_vectors (w, f, symbol_attrs, attrs, 0);
return lookup_face (f, attrs);
default_face = FACE_FROM_ID (f, face_id);
memcpy (attrs, default_face->lface, sizeof attrs);
+
+ /* Make explicit any attributes whose value is 'reset'. */
+ int i;
+ for (i = 1; i < LFACE_VECTOR_SIZE; i++)
+ if (EQ (symbol_attrs[i], Qreset))
+ symbol_attrs[i] = attrs[i];
+
merge_face_vectors (w, f, symbol_attrs, attrs, 0);
return lookup_face (f, attrs);
}
{
Lisp_Object *def_attrs = def_face->lface;
+ /* Make explicit any attributes whose value is 'reset'. */
+ int i;
+ for (i = 1; i < LFACE_VECTOR_SIZE; i++)
+ if (EQ (attrs[i], Qreset))
+ attrs[i] = def_attrs[i];
+
/* Check that other specified attributes are different from the
default face. */
if ((!UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
lface = Finternal_make_lisp_face (symbol, frame);
}
- /* Merge SYMBOL's face with the default face. */
+
get_lface_attributes_no_remap (f, symbol, symbol_attrs, true);
+
+ /* Handle the 'reset' pseudo-value of any attribute by replacing it
+ with the corresponding value of the default face. */
+ int i;
+ for (i = 1; i < LFACE_VECTOR_SIZE; i++)
+ if (EQ (symbol_attrs[i], Qreset))
+ symbol_attrs[i] = attrs[i];
+ /* Merge SYMBOL's face with the default face. */
merge_face_vectors (NULL, f, symbol_attrs, attrs, 0);
/* Realize the face. */
if (!face)
return base_face_id;
- merge_face_vectors (w, f, face->lface, attrs, 0);
+ if (face_id != DEFAULT_FACE_ID)
+ {
+ struct face *deflt = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+ Lisp_Object lface_attrs[LFACE_VECTOR_SIZE];
+ int i;
+
+ memcpy (lface_attrs, face->lface, LFACE_VECTOR_SIZE);
+ /* Make explicit any attributes whose value is 'reset'. */
+ for (i = 1; i < LFACE_VECTOR_SIZE; i++)
+ if (EQ (lface_attrs[i], Qreset))
+ lface_attrs[i] = deflt->lface[i];
+ merge_face_vectors (w, f, lface_attrs, attrs, 0);
+ }
+ else
+ merge_face_vectors (w, f, face->lface, attrs, 0);
}
/* Look up a realized face with the given face attributes,
DEFSYM (Qblack, "black");
DEFSYM (Qoblique, "oblique");
DEFSYM (Qitalic, "italic");
+ DEFSYM (Qreset, "reset");
/* The symbols `foreground-color' and `background-color' which can be
used as part of a `face' property. This is for compatibility with