#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <stdio.h> /* This needs to be before termchar.h */
#include "lisp.h"
#include "charset.h"
#include "keyboard.h"
#include "frame.h"
+#include "termhooks.h"
#ifdef HAVE_WINDOW_SYSTEM
#include "fontset.h"
#include "blockinput.h"
#include "window.h"
#include "intervals.h"
+#include "termchar.h"
#ifdef HAVE_X_WINDOWS
Lisp_Object Qface;
extern Lisp_Object Qmouse_face;
+/* Property for basic faces which other faces cannot inherit. */
+
+Lisp_Object Qface_no_inherit;
+
/* Error symbol for wrong_type_argument in load_pixmap. */
Lisp_Object Qbitmap_spec_p;
struct font_name;
struct table_entry;
+struct named_merge_point;
static void map_tty_color P_ ((struct frame *, struct face *,
enum lface_attribute_index, int *));
static int face_numeric_swidth P_ ((Lisp_Object));
static int face_fontset P_ ((Lisp_Object *));
static char *choose_face_font P_ ((struct frame *, Lisp_Object *, int, int, int*));
-static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*, Lisp_Object));
-static void merge_face_inheritance P_ ((struct frame *f, Lisp_Object,
- Lisp_Object *, Lisp_Object));
-static void merge_face_vector_with_property P_ ((struct frame *, Lisp_Object *,
- Lisp_Object));
+static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*,
+ struct named_merge_point *));
+static int merge_face_ref P_ ((struct frame *, Lisp_Object, Lisp_Object *,
+ int, struct named_merge_point *));
static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object,
Lisp_Object, int, int));
static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int));
Scolor_supported_p, 1, 3, 0,
doc: /* Return non-nil if COLOR can be displayed on FRAME.
BACKGROUND-P non-nil means COLOR is used as a background.
+Otherwise, this function tells whether it can be used as a foreground.
If FRAME is nil or omitted, use the selected frame.
COLOR must be a valid color name. */)
(color, frame, background_p)
#endif /* GLYPH_DEBUG == 0 */
+\f
+/* Face-merge cycle checking. */
+
+/* A `named merge point' is simply a point during face-merging where we
+ look up a face by name. We keep a stack of which named lookups we're
+ currently processing so that we can easily detect cycles, using a
+ linked- list of struct named_merge_point structures, typically
+ allocated on the stack frame of the named lookup functions which are
+ active (so no consing is required). */
+struct named_merge_point
+{
+ Lisp_Object face_name;
+ struct named_merge_point *prev;
+};
+
+
+/* If a face merging cycle is detected for FACE_NAME, return 0,
+ otherwise add NEW_NAMED_MERGE_POINT, which is initialized using
+ FACE_NAME, as the head of the linked list pointed to by
+ NAMED_MERGE_POINTS, and return 1. */
+
+static INLINE int
+push_named_merge_point (struct named_merge_point *new_named_merge_point,
+ Lisp_Object face_name,
+ struct named_merge_point **named_merge_points)
+{
+ struct named_merge_point *prev;
+
+ for (prev = *named_merge_points; prev; prev = prev->prev)
+ if (EQ (face_name, prev->face_name))
+ return 0;
+
+ new_named_merge_point->face_name = face_name;
+ new_named_merge_point->prev = *named_merge_points;
+
+ *named_merge_points = new_named_merge_point;
+
+ return 1;
+}
+
+\f
+
+
/* Resolve face name FACE_NAME. If FACE_NAME is a string, intern it
to make it a symvol. If FACE_NAME is an alias for another face,
return that face's name. */
else if (FLOATP (to))
/* relative X relative => relative */
result = make_float (XFLOAT_DATA (from) * XFLOAT_DATA (to));
+ else if (UNSPECIFIEDP (to))
+ result = from;
}
else if (FUNCTIONP (from))
/* FROM is a function, which use to adjust TO. */
completely specified and contain only absolute attributes. Every
specified attribute of FROM overrides the corresponding attribute of
TO; relative attributes in FROM are merged with the absolute value in
- TO and replace it. CYCLE_CHECK is used internally to detect loops in
- face inheritance; it should be Qnil when called from other places. */
+ TO and replace it. NAMED_MERGE_POINTS is used internally to detect
+ loops in face inheritance; it should be 0 when called from other
+ places. */
static INLINE void
-merge_face_vectors (f, from, to, cycle_check)
+merge_face_vectors (f, from, to, named_merge_points)
struct frame *f;
Lisp_Object *from, *to;
- Lisp_Object cycle_check;
+ struct named_merge_point *named_merge_points;
{
int i;
other code uses `unspecified' as a generic value for face attributes. */
if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
&& !NILP (from[LFACE_INHERIT_INDEX]))
- merge_face_inheritance (f, from[LFACE_INHERIT_INDEX], to, cycle_check);
+ merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points);
/* If TO specifies a :font attribute, and FROM specifies some
font-related attribute, we need to clear TO's :font attribute
if (!UNSPECIFIEDP (from[i]))
{
if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
- to[i] = merge_face_heights (from[i], to[i], to[i], cycle_check);
+ to[i] = merge_face_heights (from[i], to[i], to[i],
+ named_merge_points);
else
to[i] = from[i];
}
to[LFACE_INHERIT_INDEX] = Qnil;
}
-/* Merge face attributes from the face on frame F whose name is
- INHERITS, into the vector of face attributes TO; INHERITS may also be
- a list of face names, in which case they are applied in order.
- CYCLE_CHECK is used to detect loops in face inheritance.
- Returns true if any of the inherited attributes are `font-related'. */
+/* Merge the named face FACE_NAME on frame F, into the vector of face
+ attributes TO. NAMED_MERGE_POINTS is used to detect loops in face
+ inheritance. Returns true if FACE_NAME is a valid face name and
+ merging succeeded. */
-static void
-merge_face_inheritance (f, inherit, to, cycle_check)
+static int
+merge_named_face (f, face_name, to, named_merge_points)
struct frame *f;
- Lisp_Object inherit;
+ Lisp_Object face_name;
Lisp_Object *to;
- Lisp_Object cycle_check;
+ struct named_merge_point *named_merge_points;
{
- if (SYMBOLP (inherit) && !EQ (inherit, Qunspecified))
- /* Inherit from the named face INHERIT. */
- {
- Lisp_Object lface;
-
- /* Make sure we're not in an inheritance loop. */
- cycle_check = CYCLE_CHECK (cycle_check, inherit, 15);
- if (NILP (cycle_check))
- /* Cycle detected, ignore any further inheritance. */
- return;
+ struct named_merge_point named_merge_point;
- lface = lface_from_face_name (f, inherit, 0);
- if (!NILP (lface))
- merge_face_vectors (f, XVECTOR (lface)->contents, to, cycle_check);
- }
- else if (CONSP (inherit))
- /* Handle a list of inherited faces by calling ourselves recursively
- on each element. Note that we only do so for symbol elements, so
- it's not possible to infinitely recurse. */
+ if (push_named_merge_point (&named_merge_point,
+ face_name, &named_merge_points))
{
- while (CONSP (inherit))
- {
- if (SYMBOLP (XCAR (inherit)))
- merge_face_inheritance (f, XCAR (inherit), to, cycle_check);
+ Lisp_Object from[LFACE_VECTOR_SIZE];
+ int ok = get_lface_attributes (f, face_name, from, 0);
- /* Check for a circular inheritance list. */
- cycle_check = CYCLE_CHECK (cycle_check, inherit, 15);
- if (NILP (cycle_check))
- /* Cycle detected. */
- break;
+ if (ok)
+ merge_face_vectors (f, from, to, named_merge_points);
- inherit = XCDR (inherit);
- }
+ return ok;
}
+ else
+ return 0;
}
-/* Given a Lisp face attribute vector TO and a Lisp object PROP that
- is a face property, determine the resulting face attributes on
- frame F, and store them in TO. PROP may be a single face
- specification or a list of such specifications. Each face
- specification can be
+/* Merge face attributes from the lisp `face reference' FACE_REF on
+ frame F into the face attribute vector TO. If ERR_MSGS is non-zero,
+ problems with FACE_REF cause an error message to be shown. Return
+ non-zero if no errors occurred (regardless of the value of ERR_MSGS).
+ NAMED_MERGE_POINTS is used to detect loops in face inheritance or
+ list structure; it may be 0 for most callers.
+
+ FACE_REF may be a single face specification or a list of such
+ specifications. Each face specification can be:
1. A symbol or string naming a Lisp face.
Face specifications earlier in lists take precedence over later
specifications. */
-static void
-merge_face_vector_with_property (f, to, prop)
+static int
+merge_face_ref (f, face_ref, to, err_msgs, named_merge_points)
struct frame *f;
+ Lisp_Object face_ref;
Lisp_Object *to;
- Lisp_Object prop;
+ int err_msgs;
+ struct named_merge_point *named_merge_points;
{
- if (CONSP (prop))
+ int ok = 1; /* Succeed without an error? */
+
+ if (CONSP (face_ref))
{
- Lisp_Object first = XCAR (prop);
+ Lisp_Object first = XCAR (face_ref);
if (EQ (first, Qforeground_color)
|| EQ (first, Qbackground_color))
{
/* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
. COLOR). COLOR must be a string. */
- Lisp_Object color_name = XCDR (prop);
+ Lisp_Object color_name = XCDR (face_ref);
Lisp_Object color = first;
if (STRINGP (color_name))
to[LFACE_BACKGROUND_INDEX] = color_name;
}
else
- add_to_log ("Invalid face color", color_name, Qnil);
+ {
+ if (err_msgs)
+ add_to_log ("Invalid face color", color_name, Qnil);
+ ok = 0;
+ }
}
else if (SYMBOLP (first)
&& *SDATA (SYMBOL_NAME (first)) == ':')
{
/* Assume this is the property list form. */
- while (CONSP (prop) && CONSP (XCDR (prop)))
+ while (CONSP (face_ref) && CONSP (XCDR (face_ref)))
{
- Lisp_Object keyword = XCAR (prop);
- Lisp_Object value = XCAR (XCDR (prop));
-
- if (EQ (keyword, QCfamily))
+ Lisp_Object keyword = XCAR (face_ref);
+ Lisp_Object value = XCAR (XCDR (face_ref));
+ int err = 0;
+
+ /* Specifying `unspecified' is a no-op. */
+ if (EQ (value, Qunspecified))
+ ;
+ else if (EQ (keyword, QCfamily))
{
if (STRINGP (value))
to[LFACE_FAMILY_INDEX] = value;
else
- add_to_log ("Invalid face font family", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCheight))
{
merge_face_heights (value, to[LFACE_HEIGHT_INDEX],
Qnil, Qnil);
- if (NILP (new_height))
- add_to_log ("Invalid face font height", value, Qnil);
- else
+ if (! NILP (new_height))
to[LFACE_HEIGHT_INDEX] = new_height;
+ else
+ err = 1;
}
else if (EQ (keyword, QCweight))
{
&& face_numeric_weight (value) >= 0)
to[LFACE_WEIGHT_INDEX] = value;
else
- add_to_log ("Invalid face weight", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCslant))
{
&& face_numeric_slant (value) >= 0)
to[LFACE_SLANT_INDEX] = value;
else
- add_to_log ("Invalid face slant", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCunderline))
{
|| STRINGP (value))
to[LFACE_UNDERLINE_INDEX] = value;
else
- add_to_log ("Invalid face underline", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCoverline))
{
|| STRINGP (value))
to[LFACE_OVERLINE_INDEX] = value;
else
- add_to_log ("Invalid face overline", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCstrike_through))
{
|| STRINGP (value))
to[LFACE_STRIKE_THROUGH_INDEX] = value;
else
- add_to_log ("Invalid face strike-through", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCbox))
{
|| NILP (value))
to[LFACE_BOX_INDEX] = value;
else
- add_to_log ("Invalid face box", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCinverse_video)
|| EQ (keyword, QCreverse_video))
if (EQ (value, Qt) || NILP (value))
to[LFACE_INVERSE_INDEX] = value;
else
- add_to_log ("Invalid face inverse-video", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCforeground))
{
if (STRINGP (value))
to[LFACE_FOREGROUND_INDEX] = value;
else
- add_to_log ("Invalid face foreground", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCbackground))
{
if (STRINGP (value))
to[LFACE_BACKGROUND_INDEX] = value;
else
- add_to_log ("Invalid face background", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCstipple))
{
if (!NILP (pixmap_p))
to[LFACE_STIPPLE_INDEX] = value;
else
- add_to_log ("Invalid face stipple", value, Qnil);
+ err = 1;
#endif
}
else if (EQ (keyword, QCwidth))
&& face_numeric_swidth (value) >= 0)
to[LFACE_SWIDTH_INDEX] = value;
else
- add_to_log ("Invalid face width", value, Qnil);
+ err = 1;
}
else if (EQ (keyword, QCinherit))
{
- if (SYMBOLP (value))
- to[LFACE_INHERIT_INDEX] = value;
- else
- {
- Lisp_Object tail;
- for (tail = value; CONSP (tail); tail = XCDR (tail))
- if (!SYMBOLP (XCAR (tail)))
- break;
- if (NILP (tail))
- to[LFACE_INHERIT_INDEX] = value;
- else
- add_to_log ("Invalid face inherit", value, Qnil);
- }
+ /* This is not really very useful; it's just like a
+ normal face reference. */
+ if (! merge_face_ref (f, value, to,
+ err_msgs, named_merge_points))
+ err = 1;
}
else
- add_to_log ("Invalid attribute %s in face property",
- keyword, Qnil);
+ err = 1;
- prop = XCDR (XCDR (prop));
+ if (err)
+ {
+ add_to_log ("Invalid face attribute %S %S", keyword, value);
+ ok = 0;
+ }
+
+ face_ref = XCDR (XCDR (face_ref));
}
}
else
{
- /* This is a list of face specs. Specifications at the
- beginning of the list take precedence over later
- specifications, so we have to merge starting with the
- last specification. */
- Lisp_Object next = XCDR (prop);
- if (!NILP (next))
- merge_face_vector_with_property (f, to, next);
- merge_face_vector_with_property (f, to, first);
+ /* This is a list of face refs. Those at the beginning of the
+ list take precedence over what follows, so we have to merge
+ from the end backwards. */
+ Lisp_Object next = XCDR (face_ref);
+
+ if (! NILP (next))
+ ok = merge_face_ref (f, next, to, err_msgs, named_merge_points);
+
+ if (! merge_face_ref (f, first, to, err_msgs, named_merge_points))
+ ok = 0;
}
}
else
{
- /* PROP ought to be a face name. */
- Lisp_Object lface = lface_from_face_name (f, prop, 0);
- if (NILP (lface))
- add_to_log ("Invalid face text property value: %s", prop, Qnil);
- else
- merge_face_vectors (f, XVECTOR (lface)->contents, to, Qnil);
+ /* FACE_REF ought to be a face name. */
+ ok = merge_named_face (f, face_ref, to, named_merge_points);
+ if (!ok && err_msgs)
+ add_to_log ("Invalid face reference: %s", face_ref, Qnil);
}
+
+ return ok;
}
depend on the face, make sure they are all removed. This is done
by incrementing face_change_count. The next call to
init_iterator will then free realized faces. */
- ++face_change_count;
- ++windows_or_buffers_changed;
+ if (NILP (Fget (face, Qface_no_inherit)))
+ {
+ ++face_change_count;
+ ++windows_or_buffers_changed;
+ }
xassert (LFACEP (lface));
check_lface (lface);
DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
Sinternal_copy_lisp_face, 4, 4, 0,
doc: /* Copy face FROM to TO.
-If FRAME is t, copy the global face definition of FROM to the
-global face definition of TO. Otherwise, copy the frame-local
-definition of FROM on FRAME to the frame-local definition of TO
-on NEW-FRAME, or FRAME if NEW-FRAME is nil.
+If FRAME is t, copy the global face definition of FROM.
+Otherwise, copy the frame-local definition of FROM on FRAME.
+If NEW-FRAME is a frame, copy that data into the frame-local
+definition of TO on NEW-FRAME. If NEW-FRAME is nil.
+FRAME controls where the data is copied to.
-Value is TO. */)
+The value is TO. */)
(from, to, frame, new_frame)
Lisp_Object from, to, frame, new_frame;
{
CHECK_SYMBOL (from);
CHECK_SYMBOL (to);
- if (NILP (new_frame))
- new_frame = frame;
if (EQ (frame, Qt))
{
else
{
/* Copy frame-local definition of FROM. */
+ if (NILP (new_frame))
+ new_frame = frame;
CHECK_LIVE_FRAME (frame);
CHECK_LIVE_FRAME (new_frame);
lface = lface_from_face_name (XFRAME (frame), from, 1);
depend on the face, make sure they are all removed. This is done
by incrementing face_change_count. The next call to
init_iterator will then free realized faces. */
- ++face_change_count;
- ++windows_or_buffers_changed;
+ if (NILP (Fget (to, Qface_no_inherit)))
+ {
+ ++face_change_count;
+ ++windows_or_buffers_changed;
+ }
return to;
}
by incrementing face_change_count. The next call to
init_iterator will then free realized faces. */
if (!EQ (frame, Qt)
+ && NILP (Fget (face, Qface_no_inherit))
&& (EQ (attr, QCfont)
|| NILP (Fequal (old_value, value))))
{
struct frame *f;
Lisp_Object param, new_value;
{
+ Lisp_Object face = Qnil;
Lisp_Object lface;
/* If there are no faces yet, give up. This is the case when called
if (NILP (f->face_alist))
return;
- /* Changing a named face means that all realized faces depending on
- that face are invalid. Since we cannot tell which realized faces
- depend on the face, make sure they are all removed. This is done
- by incrementing face_change_count. The next call to
- init_iterator will then free realized faces. */
- ++face_change_count;
- ++windows_or_buffers_changed;
-
if (EQ (param, Qforeground_color))
{
- lface = lface_from_face_name (f, Qdefault, 1);
+ face = Qdefault;
+ lface = lface_from_face_name (f, face, 1);
LFACE_FOREGROUND (lface) = (STRINGP (new_value)
? new_value : Qunspecified);
realize_basic_faces (f);
XSETFRAME (frame, f);
call1 (Qframe_update_face_colors, frame);
- lface = lface_from_face_name (f, Qdefault, 1);
+ face = Qdefault;
+ lface = lface_from_face_name (f, face, 1);
LFACE_BACKGROUND (lface) = (STRINGP (new_value)
? new_value : Qunspecified);
realize_basic_faces (f);
}
- if (EQ (param, Qborder_color))
+ else if (EQ (param, Qborder_color))
{
- lface = lface_from_face_name (f, Qborder, 1);
+ face = Qborder;
+ lface = lface_from_face_name (f, face, 1);
LFACE_BACKGROUND (lface) = (STRINGP (new_value)
? new_value : Qunspecified);
}
else if (EQ (param, Qcursor_color))
{
- lface = lface_from_face_name (f, Qcursor, 1);
+ face = Qcursor;
+ lface = lface_from_face_name (f, face, 1);
LFACE_BACKGROUND (lface) = (STRINGP (new_value)
? new_value : Qunspecified);
}
else if (EQ (param, Qmouse_color))
{
- lface = lface_from_face_name (f, Qmouse, 1);
+ face = Qmouse;
+ lface = lface_from_face_name (f, face, 1);
LFACE_BACKGROUND (lface) = (STRINGP (new_value)
? new_value : Qunspecified);
}
+
+ /* Changing a named face means that all realized faces depending on
+ that face are invalid. Since we cannot tell which realized faces
+ depend on the face, make sure they are all removed. This is done
+ by incrementing face_change_count. The next call to
+ init_iterator will then free realized faces. */
+ if (!NILP (face)
+ && NILP (Fget (face, Qface_no_inherit)))
+ {
+ ++face_change_count;
+ ++windows_or_buffers_changed;
+ }
}
static INLINE int
face_attr_equal_p (v1, v2)
+ Lisp_Object v1, v2;
{
/* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
and the other is specified. */
get_lface_attributes (f, symbol, symbol_attrs, 1);
bcopy (default_face->lface, attrs, sizeof attrs);
- merge_face_vectors (f, symbol_attrs, attrs, Qnil);
+ merge_face_vectors (f, symbol_attrs, attrs, 0);
+
return lookup_face (f, attrs, c, NULL);
}
get_lface_attributes (f, symbol, symbol_attrs, 1);
bcopy (default_face->lface, attrs, sizeof attrs);
- merge_face_vectors (f, symbol_attrs, attrs, Qnil);
+ merge_face_vectors (f, symbol_attrs, attrs, 0);
return lookup_face (f, attrs, c, default_face);
}
Lisp_Object lface;
lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
Qunspecified);
- merge_face_vector_with_property (XFRAME (selected_frame),
- XVECTOR (lface)->contents,
- plist);
+ merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents,
+ 1, 0);
return lface;
}
bcopy (def_attrs, merged_attrs, sizeof merged_attrs);
- merge_face_vectors (f, attrs, merged_attrs, Qnil);
+ merge_face_vectors (f, attrs, merged_attrs, 0);
face = FACE_FROM_ID (f, lookup_face (f, merged_attrs, 0, 0));
if (! face)
- signal_error ("cannot make face", 0);
+ error ("cannot make face");
/* If the font is the same, then not supported. */
if (face->font == def_face->font)
Lisp_Object *attrs;
struct face *def_face;
{
- int weight, i;
+ int weight;
Lisp_Object val, fg, bg;
XColor fg_tty_color, fg_std_color;
XColor bg_tty_color, bg_std_color;
/* See if the capabilities we selected above are supported, with the
given colors. */
if (test_caps != 0 &&
- ! tty_capable_p (f, test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
+ ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
return 0;
for (i = 0; i < LFACE_VECTOR_SIZE; i++)
attrs[i] = Qunspecified;
- merge_face_vector_with_property (f, attrs, attributes);
+ merge_face_ref (f, attributes, attrs, 1, 0);
def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
if (def_face == NULL)
{
if (! realize_basic_faces (f))
- signal_error ("Cannot realize default face", 0);
+ error ("Cannot realize default face");
def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
}
{
FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
#ifdef USE_X_TOOLKIT
- x_update_menu_appearance (f);
+ if (FRAME_WINDOW_P (f))
+ x_update_menu_appearance (f);
#endif
}
LFACE_FOREGROUND (lface) = XCDR (color);
else if (FRAME_WINDOW_P (f))
return 0;
- else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
+ else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
LFACE_FOREGROUND (lface) = build_string (unspecified_fg);
else
abort ();
LFACE_BACKGROUND (lface) = XCDR (color);
else if (FRAME_WINDOW_P (f))
return 0;
- else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
+ else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
LFACE_BACKGROUND (lface) = build_string (unspecified_bg);
else
abort ();
/* Merge SYMBOL's face with the default face. */
get_lface_attributes (f, symbol, symbol_attrs, 1);
- merge_face_vectors (f, symbol_attrs, attrs, Qnil);
+ merge_face_vectors (f, symbol_attrs, attrs, 0);
/* Realize the face. */
new_face = realize_face (c, attrs, 0, NULL, id);
face = realize_x_face (cache, attrs, c, base_face);
else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
face = realize_tty_face (cache, attrs, c);
+ else if (FRAME_INITIAL_P (cache->f))
+ {
+ /* Create a dummy face. */
+ face = make_realized_face (attrs);
+ }
else
abort ();
Lisp_Object attrs[LFACE_VECTOR_SIZE];
struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
bcopy (default_face->lface, attrs, sizeof attrs);
- merge_face_vector_with_property (f, attrs, prop);
+ merge_face_ref (f, prop, attrs, 1, 0);
face_id = lookup_face (f, attrs, ch, NULL);
}
/* Merge in attributes specified via text properties. */
if (!NILP (prop))
- merge_face_vector_with_property (f, attrs, prop);
+ merge_face_ref (f, prop, attrs, 1, 0);
/* Now merge the overlay data. */
noverlays = sort_overlays (overlay_vec, noverlays, w);
prop = Foverlay_get (overlay_vec[i], propname);
if (!NILP (prop))
- merge_face_vector_with_property (f, attrs, prop);
+ merge_face_ref (f, prop, attrs, 1, 0);
oend = OVERLAY_END (overlay_vec[i]);
oendpos = OVERLAY_POSITION (oend);
/* If in the region, merge in the region face. */
if (pos >= region_beg && pos < region_end)
{
- Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
- merge_face_vectors (f, XVECTOR (region_face)->contents, attrs, Qnil);
+ merge_named_face (f, Qregion, attrs, 0);
if (region_end < endpos)
endpos = region_end;
/* Merge in attributes specified via text properties. */
if (!NILP (prop))
- merge_face_vector_with_property (f, attrs, prop);
+ merge_face_ref (f, prop, attrs, 1, 0);
/* If in the region, merge in the region face. */
if (bufpos
&& bufpos >= region_beg
&& bufpos < region_end)
- {
- Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
- merge_face_vectors (f, XVECTOR (region_face)->contents, attrs, Qnil);
- }
+ merge_named_face (f, Qregion, attrs, 0);
/* Look up a realized face with the given face attributes,
or realize a new one for ASCII characters. */
{
Qface = intern ("face");
staticpro (&Qface);
+ Qface_no_inherit = intern ("face-no-inherit");
+ staticpro (&Qface_no_inherit);
Qbitmap_spec_p = intern ("bitmap-spec-p");
staticpro (&Qbitmap_spec_p);
Qframe_update_face_colors = intern ("frame-update-face-colors");