Function: internal-make-lisp-face

internal-make-lisp-face is a function defined in xfaces.c.

Signature

(internal-make-lisp-face FACE &optional FRAME)

Documentation

Make FACE, a symbol, a Lisp face with all attributes nil.

If FACE was not known as a face before, create a new one. If optional argument FRAME is specified, make a frame-local face for that frame. Otherwise operate on the global face definition. Value is a vector of face attributes.

Source Code

// Defined in /usr/src/emacs/src/xfaces.c
{
  Lisp_Object global_lface, lface;
  struct frame *f;
  int i;

  CHECK_SYMBOL (face);
  global_lface = lface_from_face_name (NULL, face, false);

  if (!NILP (frame))
    {
      CHECK_LIVE_FRAME (frame);
      f = XFRAME (frame);
      lface = lface_from_face_name (f, face, false);
    }
  else
    f = NULL, lface = Qnil;

  /* Add a global definition if there is none.  */
  if (NILP (global_lface))
    {
      /* Assign the new Lisp face a unique ID.  The mapping from Lisp
	 face id to Lisp face is given by the vector lface_id_to_name.
	 The mapping from Lisp face to Lisp face id is given by the
	 property `face' of the Lisp face name.  */
      if (next_lface_id == lface_id_to_name_size)
	lface_id_to_name =
	  xpalloc (lface_id_to_name, &lface_id_to_name_size, 1, MAX_FACE_ID,
		   sizeof *lface_id_to_name);

      Lisp_Object face_id = make_fixnum (next_lface_id);
      lface_id_to_name[next_lface_id] = face;
      Fput (face, Qface, face_id);
      ++next_lface_id;

      global_lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified);
      ASET (global_lface, 0, Qface);
      Fputhash (face, Fcons (face_id, global_lface), Vface_new_frame_defaults);
    }
  else if (f == NULL)
    for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
      ASET (global_lface, i, Qunspecified);

  /* Add a frame-local definition.  */
  if (f)
    {
      if (NILP (lface))
	{
	  lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified);
	  ASET (lface, 0, Qface);
          Fputhash (face, lface, f->face_hash_table);
	}
      else
	for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
	  ASET (lface, i, Qunspecified);
    }
  else
    lface = global_lface;

  /* 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 setting face_change.  The next call to init_iterator will then
     free realized faces.  */
  if (NILP (Fget (face, Qface_no_inherit)))
    {
      if (f)
	{
	  f->face_change = true;
	  fset_redisplay (f);
	}
      else
	{
	  face_change = true;
	  windows_or_buffers_changed = 54;
	}
    }

  eassert (LFACEP (lface));
  check_lface (lface);
  return lface;
}