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, *oldface = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID);
      Lisp_Object attrs[LFACE_VECTOR_SIZE];

      /* This can be NULL (e.g., in batch mode).  */
      if (oldface)
	{
	  /* 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);
	      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);
	    }
	}
    }

  return Qnil;
}