Function: internal-merge-in-global-face
internal-merge-in-global-face is a function defined in xfaces.c.
Signature
(internal-merge-in-global-face FACE FRAME)
Documentation
Add attributes from frame-default definition of FACE to FACE on FRAME.
Default face attributes override any local face attributes.
Source Code
// Defined in /usr/src/emacs/src/xfaces.c
{
int i;
Lisp_Object global_lface, local_lface, *gvec, *lvec;
struct frame *f = XFRAME (frame);
CHECK_LIVE_FRAME (frame);
global_lface = lface_from_face_name (NULL, face, true);
local_lface = lface_from_face_name (f, face, false);
if (NILP (local_lface))
local_lface = Finternal_make_lisp_face (face, frame);
/* Make every specified global attribute override the local one.
BEWARE!! This is only used from `face-set-after-frame-default' where
the local frame is defined from default specs in `face-defface-spec'
and those should be overridden by global settings. Hence the strange
"global before local" priority. */
lvec = XVECTOR (local_lface)->contents;
gvec = XVECTOR (global_lface)->contents;
for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
if (IGNORE_DEFFACE_P (gvec[i]))
ASET (local_lface, i, Qunspecified);
else if (! UNSPECIFIEDP (gvec[i]))
ASET (local_lface, i, AREF (global_lface, i));
/* If the default face was changed, update the face cache and the
`font' frame parameter. */
if (EQ (face, Qdefault))
{
struct face_cache *c = FRAME_FACE_CACHE (f);
struct face *newface;
struct face *oldface =
c ? FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID) : NULL;
Lisp_Object attrs[LFACE_VECTOR_SIZE];
/* This can be NULL (e.g., in batch mode). */
if (oldface)
{
/* In some cases, realize_face below can call Lisp, which could
trigger redisplay. But we are in the process of realizing
the default face, and therefore are not ready to do display. */
specpdl_ref count = SPECPDL_INDEX ();
specbind (Qinhibit_redisplay, Qt);
/* Ensure that the face vector is fully specified by merging
the previously-cached vector. */
memcpy (attrs, oldface->lface, sizeof attrs);
merge_face_vectors (NULL, f, lvec, attrs, 0);
vcopy (local_lface, 0, attrs, LFACE_VECTOR_SIZE);
newface = realize_face (c, lvec, DEFAULT_FACE_ID);
if ((! UNSPECIFIEDP (gvec[LFACE_FAMILY_INDEX])
|| ! UNSPECIFIEDP (gvec[LFACE_FOUNDRY_INDEX])
|| ! UNSPECIFIEDP (gvec[LFACE_HEIGHT_INDEX])
|| ! UNSPECIFIEDP (gvec[LFACE_WEIGHT_INDEX])
|| ! UNSPECIFIEDP (gvec[LFACE_SLANT_INDEX])
|| ! UNSPECIFIEDP (gvec[LFACE_SWIDTH_INDEX])
|| ! UNSPECIFIEDP (gvec[LFACE_FONT_INDEX]))
&& newface->font)
{
Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
AUTO_FRAME_ARG (arg, Qfont, name);
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
/* This is a window-system frame. Prevent changes of
the `font' parameter here from messing with the
`font-parameter' frame property, as the frame
parameter is not being changed by the user. */
gui_set_frame_parameters_1 (f, arg, true);
else
#endif
Fmodify_frame_parameters (frame, arg);
}
if (STRINGP (gvec[LFACE_FOREGROUND_INDEX]))
{
AUTO_FRAME_ARG (arg, Qforeground_color,
gvec[LFACE_FOREGROUND_INDEX]);
Fmodify_frame_parameters (frame, arg);
}
if (STRINGP (gvec[LFACE_BACKGROUND_INDEX]))
{
AUTO_FRAME_ARG (arg, Qbackground_color,
gvec[LFACE_BACKGROUND_INDEX]);
Fmodify_frame_parameters (frame, arg);
}
unbind_to (count, Qnil);
}
}
return Qnil;
}