- If any of these elements are nil, that allows the frame's parameters to
- show through.
- (lisp/faces.el maintains these association lists.)
-
- The frames' private alists hold the frame-local definitions for the
- faces. The lisp variable global-face-data contains the global
- defaults for faces. (See lisp/faces.el for this too.)
-
- In the C code, we also have a `struct face' with the elements
- `foreground', `background', `font', and `underline',
- which specify its visual appearance, and elements
- `gc' and `cached_index';
- `gc' may be an X GC which has been built for the given display
- parameters. Faces with GC's are called `display faces'. Whether
- or not a face has a GC depends on what data structure the face is
- in; we explain these more below. (See src/dispextern.h.)
-
- Each frame also has members called `faces' and `n_faces' (with the
- accessors FRAME_FACES and FRAME_N_FACES), which define an array of
- struct face pointers, indexed by face ID (element 2 of the
- vector). These are called "frame faces".
- Element 0 is the default face --- the one used for normal text.
- Element 1 is the modeline face.
- These faces have their GC's set; the rest do not.
- If faces[i] is filled in (i.e. non-zero) on one frame, then it must
- be filled in on all frames. Code assumes that face ID's can be
- used on any frame. (See src/xterm.h.)
-
- The global variables `face_vector' and `nfaces' define another
- array of struct face pointers, with their GC's set. This array
- acts as a cache of GC's to be used by all frames. The function
- `intern_face', passed a struct face *, searches face_vector for a
- struct face with the same parameters, adds a new one with a GC if
- it doesn't find one, and returns it. If you have a `struct face',
- and you want a GC for it, call intern_face on that struct, and it
- will return a `struct face *' with its GC set. The faces in
- face_vector are called `cached faces.' (See src/xfaces.c.)
-
- The `GLYPH' data type is an unsigned integer type; the bottom byte
- is a character code, and the byte above that is a face id. The
- `struct frame_glyphs' structure, used to describe frames' current
- or desired contents, is essentially a matrix of GLYPHs; the face
- ID's in a struct frame_glyphs are indices into FRAME_FACES. (See
- src/dispextern.h.)
+ If any of these elements are nil, that parameter is considered
+ unspecified; parameters from faces specified by lower-priority
+ overlays or text properties, or the parameters of the frame itself,
+ can show through. (lisp/faces.el maintains these lists.)
+
+ (assq FACE-NAME global-face-data) returns a vector describing the
+ global parameters for that face.
+
+ Let PARAM-FACE be FRAME->output_data.x->param_faces[Faref (FACE-VECTOR, 2)].
+ PARAM_FACE is a struct face whose members are the Xlib analogues of
+ the parameters in FACE-VECTOR. If an element of FACE-VECTOR is
+ nil, then the corresponding member of PARAM_FACE is FACE_DEFAULT.
+ These faces are called "parameter faces", because they're the ones
+ lisp manipulates to control what gets displayed. Elements 0 and 1
+ of FRAME->output_data.x->param_faces are special - they describe the
+ default and mode line faces. None of the faces in param_faces have
+ GC's. (See src/dispextern.h for the definiton of struct face.
+ lisp/faces.el maintains the isomorphism between face_alist and
+ param_faces.)
+
+ The functions compute_char_face and compute_glyph_face find and
+ combine the parameter faces associated with overlays and text
+ properties. The resulting faces are called "computed faces"; none
+ of their members are FACE_DEFAULT; they are completely specified.
+ They then call intern_compute_face to search
+ FRAME->output_data.x->computed_faces for a matching face, add one if
+ none is found, and return the index into
+ FRAME->output_data.x->computed_faces. FRAME's glyph matrices use these
+ indices to record the faces of the matrix characters, and the X
+ display hooks consult compute_faces to decide how to display these
+ characters. Elements 0 and 1 of computed_faces always describe the
+ default and mode-line faces.
+
+ Each computed face belongs to a particular frame.
+
+ Computed faces have graphics contexts some of the time.
+ intern_face builds a GC for a specified computed face
+ if it doesn't have one already.
+ clear_face_cache clears out the GCs of all computed faces.
+ This is done from time to time so that we don't hold on to
+ lots of GCs that are no longer needed.
+
+ If a computed face has 0 as its font,
+ it is unused, and can be reused by new_computed_face.
+
+ Constraints:
+
+ Symbols naming faces must have associations on all frames; for any
+ FRAME, for all FACE-NAME, if (assq FACE-NAME (frame-face-alist
+ FRAME)) is non-nil, it must be non-nil for all frames.
+
+ Analogously, indices into param_faces must be valid on all frames;
+ if param_faces[i] is a non-zero face pointer on one frame, then it
+ must be filled in on all frames. Code assumes that face ID's can
+ be used on any frame.