1/* xfaces.c -- "Face" primitives.
2   Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001
3   Free Software Foundation.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING.  If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA.  */
21
22/* New face implementation by Gerd Moellmann <gerd@gnu.org>.  */
23
24/* Faces.
25
26   When using Emacs with X, the display style of characters can be
27   changed by defining `faces'.  Each face can specify the following
28   display attributes:
29
30   1. Font family name.
31
32   2. Relative proportionate width, aka character set width or set
33   width (swidth), e.g. `semi-compressed'.
34
35   3. Font height in 1/10pt.
36
37   4. Font weight, e.g. `bold'.
38
39   5. Font slant, e.g. `italic'.
40
41   6. Foreground color.
42
43   7. Background color.
44
45   8. Whether or not characters should be underlined, and in what color.
46
47   9. Whether or not characters should be displayed in inverse video.
48
49   10. A background stipple, a bitmap.
50
51   11. Whether or not characters should be overlined, and in what color.
52
53   12. Whether or not characters should be strike-through, and in what
54   color.
55
56   13. Whether or not a box should be drawn around characters, the box
57   type, and, for simple boxes, in what color.
58
59   14. Font or fontset pattern, or nil.  This is a special attribute.
60   When this attribute is specified, the face uses a font opened by
61   that pattern as is.  In addition, all the other font-related
62   attributes (1st thru 5th) are generated from the opened font name.
63   On the other hand, if one of the other font-related attributes are
64   specified, this attribute is set to nil.  In that case, the face
65   doesn't inherit this attribute from the `default' face, and uses a
66   font determined by the other attributes (those may be inherited
67   from the `default' face).
68
69   15. A face name or list of face names from which to inherit attributes.
70
71   16. A specified average font width, which is invisible from Lisp,
72   and is used to ensure that a font specified on the command line,
73   for example, can be matched exactly.
74
75   Faces are frame-local by nature because Emacs allows to define the
76   same named face (face names are symbols) differently for different
77   frames.  Each frame has an alist of face definitions for all named
78   faces.  The value of a named face in such an alist is a Lisp vector
79   with the symbol `face' in slot 0, and a slot for each of the face
80   attributes mentioned above.
81
82   There is also a global face alist `Vface_new_frame_defaults'.  Face
83   definitions from this list are used to initialize faces of newly
84   created frames.
85
86   A face doesn't have to specify all attributes.  Those not specified
87   have a value of `unspecified'.  Faces specifying all attributes but
88   the 14th are called `fully-specified'.
89
90
91   Face merging.
92
93   The display style of a given character in the text is determined by
94   combining several faces.  This process is called `face merging'.
95   Any aspect of the display style that isn't specified by overlays or
96   text properties is taken from the `default' face.  Since it is made
97   sure that the default face is always fully-specified, face merging
98   always results in a fully-specified face.
99
100
101   Face realization.
102
103   After all face attributes for a character have been determined by
104   merging faces of that character, that face is `realized'.  The
105   realization process maps face attributes to what is physically
106   available on the system where Emacs runs.  The result is a
107   `realized face' in form of a struct face which is stored in the
108   face cache of the frame on which it was realized.
109
110   Face realization is done in the context of the character to display
111   because different fonts may be used for different characters.  In
112   other words, for characters that have different font
113   specifications, different realized faces are needed to display
114   them.
115
116   Font specification is done by fontsets.  See the comment in
117   fontset.c for the details.  In the current implementation, all ASCII
118   characters share the same font in a fontset.
119
120   Faces are at first realized for ASCII characters, and, at that
121   time, assigned a specific realized fontset.  Hereafter, we call
122   such a face as `ASCII face'.  When a face for a multibyte character
123   is realized, it inherits (thus shares) a fontset of an ASCII face
124   that has the same attributes other than font-related ones.
125
126   Thus, all realized face have a realized fontset.
127
128
129   Unibyte text.
130
131   Unibyte text (i.e. raw 8-bit characters) is displayed with the same
132   font as ASCII characters.  That is because it is expected that
133   unibyte text users specify a font that is suitable both for ASCII
134   and raw 8-bit characters.
135
136
137   Font selection.
138
139   Font selection tries to find the best available matching font for a
140   given (character, face) combination.
141
142   If the face specifies a fontset name, that fontset determines a
143   pattern for fonts of the given character.  If the face specifies a
144   font name or the other font-related attributes, a fontset is
145   realized from the default fontset.  In that case, that
146   specification determines a pattern for ASCII characters and the
147   default fontset determines a pattern for multibyte characters.
148
149   Available fonts on the system on which Emacs runs are then matched
150   against the font pattern.  The result of font selection is the best
151   match for the given face attributes in this font list.
152
153   Font selection can be influenced by the user.
154
155   1. The user can specify the relative importance he gives the face
156   attributes width, height, weight, and slant by setting
157   face-font-selection-order (faces.el) to a list of face attribute
158   names.  The default is '(:width :height :weight :slant), and means
159   that font selection first tries to find a good match for the font
160   width specified by a face, then---within fonts with that
161   width---tries to find a best match for the specified font height,
162   etc.
163
164   2. Setting face-font-family-alternatives allows the user to
165   specify alternative font families to try if a family specified by a
166   face doesn't exist.
167
168   3. Setting face-font-registry-alternatives allows the user to
169   specify all alternative font registries to try for a face
170   specifying a registry.
171
172   4. Setting face-ignored-fonts allows the user to ignore specific
173   fonts.
174
175
176   Character composition.
177
178   Usually, the realization process is already finished when Emacs
179   actually reflects the desired glyph matrix on the screen.  However,
180   on displaying a composition (sequence of characters to be composed
181   on the screen), a suitable font for the components of the
182   composition is selected and realized while drawing them on the
183   screen, i.e.  the realization process is delayed but in principle
184   the same.
185
186
187   Initialization of basic faces.
188
189   The faces `default', `modeline' are considered `basic faces'.
190   When redisplay happens the first time for a newly created frame,
191   basic faces are realized for CHARSET_ASCII.  Frame parameters are
192   used to fill in unspecified attributes of the default face.  */
193
194#include <config.h>
195#include <sys/types.h>
196#include <sys/stat.h>
197#include "lisp.h"
198#include "charset.h"
199#include "keyboard.h"
200#include "frame.h"
201
202#ifdef HAVE_WINDOW_SYSTEM
203#include "fontset.h"
204#endif /* HAVE_WINDOW_SYSTEM */
205
206#ifdef HAVE_X_WINDOWS
207#include "xterm.h"
208#ifdef USE_MOTIF
209#include <Xm/Xm.h>
210#include <Xm/XmStrDefs.h>
211#endif /* USE_MOTIF */
212#endif /* HAVE_X_WINDOWS */
213
214#ifdef MSDOS
215#include "dosfns.h"
216#endif
217
218#ifdef WINDOWSNT
219#include "w32term.h"
220#include "fontset.h"
221/* Redefine X specifics to W32 equivalents to avoid cluttering the
222   code with #ifdef blocks. */
223#undef FRAME_X_DISPLAY_INFO
224#define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
225#define x_display_info w32_display_info
226#define FRAME_X_FONT_TABLE FRAME_W32_FONT_TABLE
227#define check_x check_w32
228#define x_list_fonts w32_list_fonts
229#define GCGraphicsExposures 0
230/* For historic reasons, FONT_WIDTH refers to average width on W32,
231   not maximum as on X. Redefine here. */
232#undef FONT_WIDTH
233#define FONT_WIDTH FONT_MAX_WIDTH
234#endif /* WINDOWSNT */
235
236#ifdef macintosh
237#include "macterm.h"
238#define x_display_info mac_display_info
239#define check_x check_mac
240
241extern XGCValues *XCreateGC (void *, WindowPtr, unsigned long, XGCValues *);
242
243static INLINE GC
244x_create_gc (f, mask, xgcv)
245     struct frame *f;
246     unsigned long mask;
247     XGCValues *xgcv;
248{
249  GC gc;
250  gc = XCreateGC (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), mask, xgcv);
251  return gc;
252}
253
254static INLINE void
255x_free_gc (f, gc)
256     struct frame *f;
257     GC gc;
258{
259  XFreeGC (FRAME_MAC_DISPLAY (f), gc);
260}
261#endif
262
263#include "buffer.h"
264#include "dispextern.h"
265#include "blockinput.h"
266#include "window.h"
267#include "intervals.h"
268
269#ifdef HAVE_X_WINDOWS
270
271/* Compensate for a bug in Xos.h on some systems, on which it requires
272   time.h.  On some such systems, Xos.h tries to redefine struct
273   timeval and struct timezone if USG is #defined while it is
274   #included.  */
275
276#ifdef XOS_NEEDS_TIME_H
277#include <time.h>
278#undef USG
279#include <X11/Xos.h>
280#define USG
281#define __TIMEVAL__
282#else /* not XOS_NEEDS_TIME_H */
283#include <X11/Xos.h>
284#endif /* not XOS_NEEDS_TIME_H */
285
286#endif /* HAVE_X_WINDOWS */
287
288#include <stdio.h>
289#include <ctype.h>
290
291#ifndef max
292#define max(A, B)	((A) > (B) ? (A) : (B))
293#define min(A, B)	((A) < (B) ? (A) : (B))
294#define abs(X)		((X) < 0 ? -(X) : (X))
295#endif
296
297/* Number of pt per inch (from the TeXbook).  */
298
299#define PT_PER_INCH 72.27
300
301/* Non-zero if face attribute ATTR is unspecified.  */
302
303#define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
304
305/* Value is the number of elements of VECTOR.  */
306
307#define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
308
309/* Make a copy of string S on the stack using alloca.  Value is a pointer
310   to the copy.  */
311
312#define STRDUPA(S) strcpy ((char *) alloca (strlen ((S)) + 1), (S))
313
314/* Make a copy of the contents of Lisp string S on the stack using
315   alloca.  Value is a pointer to the copy.  */
316
317#define LSTRDUPA(S) STRDUPA (XSTRING ((S))->data)
318
319/* Size of hash table of realized faces in face caches (should be a
320   prime number).  */
321
322#define FACE_CACHE_BUCKETS_SIZE 1001
323
324/* A definition of XColor for non-X frames.  */
325
326#ifndef HAVE_X_WINDOWS
327
328typedef struct
329{
330  unsigned long pixel;
331  unsigned short red, green, blue;
332  char flags;
333  char pad;
334}
335XColor;
336
337#endif /* not HAVE_X_WINDOWS */
338
339/* Keyword symbols used for face attribute names.  */
340
341Lisp_Object QCfamily, QCheight, QCweight, QCslant, QCunderline;
342Lisp_Object QCinverse_video, QCforeground, QCbackground, QCstipple;
343Lisp_Object QCwidth, QCfont, QCbold, QCitalic;
344Lisp_Object QCreverse_video;
345Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
346
347/* Symbols used for attribute values.  */
348
349Lisp_Object Qnormal, Qbold, Qultra_light, Qextra_light, Qlight;
350Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
351Lisp_Object Qoblique, Qitalic, Qreverse_oblique, Qreverse_italic;
352Lisp_Object Qultra_condensed, Qextra_condensed, Qcondensed;
353Lisp_Object Qsemi_condensed, Qsemi_expanded, Qexpanded, Qextra_expanded;
354Lisp_Object Qultra_expanded;
355Lisp_Object Qreleased_button, Qpressed_button;
356Lisp_Object QCstyle, QCcolor, QCline_width;
357Lisp_Object Qunspecified;
358
359char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
360
361/* The name of the function to call when the background of the frame
362   has changed, frame_update_face_colors.  */
363
364Lisp_Object Qframe_update_face_colors;
365
366/* Names of basic faces.  */
367
368Lisp_Object Qdefault, Qtool_bar, Qregion, Qfringe;
369Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu;
370extern Lisp_Object Qmode_line;
371
372/* The symbol `face-alias'.  A symbols having that property is an
373   alias for another face.  Value of the property is the name of
374   the aliased face.  */
375
376Lisp_Object Qface_alias;
377
378/* Names of frame parameters related to faces.  */
379
380extern Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
381extern Lisp_Object Qborder_color, Qcursor_color, Qmouse_color;
382
383/* Default stipple pattern used on monochrome displays.  This stipple
384   pattern is used on monochrome displays instead of shades of gray
385   for a face background color.  See `set-face-stipple' for possible
386   values for this variable.  */
387
388Lisp_Object Vface_default_stipple;
389
390/* Alist of alternative font families.  Each element is of the form
391   (FAMILY FAMILY1 FAMILY2 ...).  If fonts of FAMILY can't be loaded,
392   try FAMILY1, then FAMILY2, ...  */
393
394Lisp_Object Vface_alternative_font_family_alist;
395
396/* Alist of alternative font registries.  Each element is of the form
397   (REGISTRY REGISTRY1 REGISTRY2...).  If fonts of REGISTRY can't be
398   loaded, try REGISTRY1, then REGISTRY2, ...  */
399
400Lisp_Object Vface_alternative_font_registry_alist;
401
402/* Allowed scalable fonts.  A value of nil means don't allow any
403   scalable fonts.  A value of t means allow the use of any scalable
404   font.  Otherwise, value must be a list of regular expressions.  A
405   font may be scaled if its name matches a regular expression in the
406   list.  */
407
408Lisp_Object Vscalable_fonts_allowed, Qscalable_fonts_allowed;
409
410/* List of regular expressions that matches names of fonts to ignore. */
411
412Lisp_Object Vface_ignored_fonts;
413
414/* Maximum number of fonts to consider in font_list.  If not an
415   integer > 0, DEFAULT_FONT_LIST_LIMIT is used instead.  */
416
417Lisp_Object Vfont_list_limit;
418#define DEFAULT_FONT_LIST_LIMIT 100
419
420/* The symbols `foreground-color' and `background-color' which can be
421   used as part of a `face' property.  This is for compatibility with
422   Emacs 20.2.  */
423
424Lisp_Object Qforeground_color, Qbackground_color;
425
426/* The symbols `face' and `mouse-face' used as text properties.  */
427
428Lisp_Object Qface;
429extern Lisp_Object Qmouse_face;
430
431/* Error symbol for wrong_type_argument in load_pixmap.  */
432
433Lisp_Object Qbitmap_spec_p;
434
435/* Alist of global face definitions.  Each element is of the form
436   (FACE . LFACE) where FACE is a symbol naming a face and LFACE
437   is a Lisp vector of face attributes.  These faces are used
438   to initialize faces for new frames.  */
439
440Lisp_Object Vface_new_frame_defaults;
441
442/* The next ID to assign to Lisp faces.  */
443
444static int next_lface_id;
445
446/* A vector mapping Lisp face Id's to face names.  */
447
448static Lisp_Object *lface_id_to_name;
449static int lface_id_to_name_size;
450
451/* TTY color-related functions (defined in tty-colors.el).  */
452
453Lisp_Object Qtty_color_desc, Qtty_color_by_index;
454
455/* The name of the function used to compute colors on TTYs.  */
456
457Lisp_Object Qtty_color_alist;
458
459/* An alist of defined terminal colors and their RGB values.  */
460
461Lisp_Object Vtty_defined_color_alist;
462
463/* Counter for calls to clear_face_cache.  If this counter reaches
464   CLEAR_FONT_TABLE_COUNT, and a frame has more than
465   CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed.  */
466
467static int clear_font_table_count;
468#define CLEAR_FONT_TABLE_COUNT	100
469#define CLEAR_FONT_TABLE_NFONTS	10
470
471/* Non-zero means face attributes have been changed since the last
472   redisplay.  Used in redisplay_internal.  */
473
474int face_change_count;
475
476/* Non-zero means don't display bold text if a face's foreground
477   and background colors are the inverse of the default colors of the
478   display.   This is a kluge to suppress `bold black' foreground text
479   which is hard to read on an LCD monitor.  */
480
481int tty_suppress_bold_inverse_default_colors_p;
482
483/* A list of the form `((x . y))' used to avoid consing in
484   Finternal_set_lisp_face_attribute.  */
485
486static Lisp_Object Vparam_value_alist;
487
488/* The total number of colors currently allocated.  */
489
490#if GLYPH_DEBUG
491static int ncolors_allocated;
492static int npixmaps_allocated;
493static int ngcs;
494#endif
495
496/* Non-zero means the definition of the `menu' face for new frames has
497   been changed.  */
498
499int menu_face_changed_default;
500
501
502/* Function prototypes.  */
503
504struct font_name;
505struct table_entry;
506
507static void map_tty_color P_ ((struct frame *, struct face *,
508			       enum lface_attribute_index, int *));
509static Lisp_Object resolve_face_name P_ ((Lisp_Object));
510static int may_use_scalable_font_p P_ ((char *));
511static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object));
512static int better_font_p P_ ((int *, struct font_name *, struct font_name *,
513			      int, int));
514static int x_face_list_fonts P_ ((struct frame *, char *,
515				  struct font_name *, int, int));
516static int font_scalable_p P_ ((struct font_name *));
517static int get_lface_attributes P_ ((struct frame *, Lisp_Object, Lisp_Object *, int));
518static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *));
519static unsigned char *xstrlwr P_ ((unsigned char *));
520static void signal_error P_ ((char *, Lisp_Object));
521static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int));
522static void load_face_font P_ ((struct frame *, struct face *, int));
523static void load_face_colors P_ ((struct frame *, struct face *, Lisp_Object *));
524static void free_face_colors P_ ((struct frame *, struct face *));
525static int face_color_gray_p P_ ((struct frame *, char *));
526static char *build_font_name P_ ((struct font_name *));
527static void free_font_names P_ ((struct font_name *, int));
528static int sorted_font_list P_ ((struct frame *, char *,
529				 int (*cmpfn) P_ ((const void *, const void *)),
530				 struct font_name **));
531static int font_list_1 P_ ((struct frame *, Lisp_Object, Lisp_Object,
532			    Lisp_Object, struct font_name **));
533static int font_list P_ ((struct frame *, Lisp_Object, Lisp_Object,
534			  Lisp_Object, struct font_name **));
535static int try_font_list P_ ((struct frame *, Lisp_Object *,
536			      Lisp_Object, Lisp_Object, struct font_name **));
537static int try_alternative_families P_ ((struct frame *f, Lisp_Object,
538					 Lisp_Object, struct font_name **));
539static int cmp_font_names P_ ((const void *, const void *));
540static struct face *realize_face P_ ((struct face_cache *, Lisp_Object *, int,
541				      struct face *, int));
542static struct face *realize_x_face P_ ((struct face_cache *,
543					Lisp_Object *, int, struct face *));
544static struct face *realize_tty_face P_ ((struct face_cache *,
545					  Lisp_Object *, int));
546static int realize_basic_faces P_ ((struct frame *));
547static int realize_default_face P_ ((struct frame *));
548static void realize_named_face P_ ((struct frame *, Lisp_Object, int));
549static int lface_fully_specified_p P_ ((Lisp_Object *));
550static int lface_equal_p P_ ((Lisp_Object *, Lisp_Object *));
551static unsigned hash_string_case_insensitive P_ ((Lisp_Object));
552static unsigned lface_hash P_ ((Lisp_Object *));
553static int lface_same_font_attributes_p P_ ((Lisp_Object *, Lisp_Object *));
554static struct face_cache *make_face_cache P_ ((struct frame *));
555static void free_realized_face P_ ((struct frame *, struct face *));
556static void clear_face_gcs P_ ((struct face_cache *));
557static void free_face_cache P_ ((struct face_cache *));
558static int face_numeric_weight P_ ((Lisp_Object));
559static int face_numeric_slant P_ ((Lisp_Object));
560static int face_numeric_swidth P_ ((Lisp_Object));
561static int face_fontset P_ ((Lisp_Object *));
562static char *choose_face_font P_ ((struct frame *, Lisp_Object *, int, int));
563static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*, Lisp_Object));
564static void merge_face_inheritance P_ ((struct frame *f, Lisp_Object,
565					Lisp_Object *, Lisp_Object));
566static void merge_face_vector_with_property P_ ((struct frame *, Lisp_Object *,
567						 Lisp_Object));
568static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object,
569					 Lisp_Object, int, int));
570static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int));
571static struct face *make_realized_face P_ ((Lisp_Object *));
572static void free_realized_faces P_ ((struct face_cache *));
573static char *best_matching_font P_ ((struct frame *, Lisp_Object *,
574				     struct font_name *, int, int));
575static void cache_face P_ ((struct face_cache *, struct face *, unsigned));
576static void uncache_face P_ ((struct face_cache *, struct face *));
577static int xlfd_numeric_slant P_ ((struct font_name *));
578static int xlfd_numeric_weight P_ ((struct font_name *));
579static int xlfd_numeric_swidth P_ ((struct font_name *));
580static Lisp_Object xlfd_symbolic_slant P_ ((struct font_name *));
581static Lisp_Object xlfd_symbolic_weight P_ ((struct font_name *));
582static Lisp_Object xlfd_symbolic_swidth P_ ((struct font_name *));
583static int xlfd_fixed_p P_ ((struct font_name *));
584static int xlfd_numeric_value P_ ((struct table_entry *, int, struct font_name *,
585				   int, int));
586static Lisp_Object xlfd_symbolic_value P_ ((struct table_entry *, int,
587					    struct font_name *, int,
588					    Lisp_Object));
589static struct table_entry *xlfd_lookup_field_contents P_ ((struct table_entry *, int,
590							   struct font_name *, int));
591
592#ifdef HAVE_WINDOW_SYSTEM
593
594static int split_font_name P_ ((struct frame *, struct font_name *, int));
595static int xlfd_point_size P_ ((struct frame *, struct font_name *));
596static void sort_fonts P_ ((struct frame *, struct font_name *, int,
597			       int (*cmpfn) P_ ((const void *, const void *))));
598static GC x_create_gc P_ ((struct frame *, unsigned long, XGCValues *));
599static void x_free_gc P_ ((struct frame *, GC));
600static void clear_font_table P_ ((struct x_display_info *));
601
602#ifdef WINDOWSNT
603extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
604#endif /* WINDOWSNT */
605
606#ifdef USE_X_TOOLKIT
607static void x_update_menu_appearance P_ ((struct frame *));
608#endif /* USE_X_TOOLKIT */
609
610#endif /* HAVE_WINDOW_SYSTEM */
611
612
613/***********************************************************************
614			      Utilities
615 ***********************************************************************/
616
617#ifdef HAVE_X_WINDOWS
618
619#ifdef DEBUG_X_COLORS
620
621/* The following is a poor mans infrastructure for debugging X color
622   allocation problems on displays with PseudoColor-8.  Some X servers
623   like 3.3.5 XF86_SVGA with Matrox cards apparently don't implement
624   color reference counts completely so that they don't signal an
625   error when a color is freed whose reference count is already 0.
626   Other X servers do.  To help me debug this, the following code
627   implements a simple reference counting schema of its own, for a
628   single display/screen.  --gerd.  */
629
630/* Reference counts for pixel colors.  */
631
632int color_count[256];
633
634/* Register color PIXEL as allocated.  */
635
636void
637register_color (pixel)
638     unsigned long pixel;
639{
640  xassert (pixel < 256);
641  ++color_count[pixel];
642}
643
644
645/* Register color PIXEL as deallocated.  */
646
647void
648unregister_color (pixel)
649     unsigned long pixel;
650{
651  xassert (pixel < 256);
652  if (color_count[pixel] > 0)
653    --color_count[pixel];
654  else
655    abort ();
656}
657
658
659/* Register N colors from PIXELS as deallocated.  */
660
661void
662unregister_colors (pixels, n)
663     unsigned long *pixels;
664     int n;
665{
666  int i;
667  for (i = 0; i < n; ++i)
668    unregister_color (pixels[i]);
669}
670
671
672DEFUN ("dump-colors", Fdump_colors, Sdump_colors, 0, 0, 0,
673  "Dump currently allocated colors and their reference counts to stderr.")
674  ()
675{
676  int i, n;
677
678  fputc ('\n', stderr);
679
680  for (i = n = 0; i < sizeof color_count / sizeof color_count[0]; ++i)
681    if (color_count[i])
682      {
683	fprintf (stderr, "%3d: %5d", i, color_count[i]);
684	++n;
685	if (n % 5 == 0)
686	  fputc ('\n', stderr);
687	else
688	  fputc ('\t', stderr);
689      }
690
691  if (n % 5 != 0)
692    fputc ('\n', stderr);
693  return Qnil;
694}
695
696#endif /* DEBUG_X_COLORS */
697
698
699/* Free colors used on frame F.  PIXELS is an array of NPIXELS pixel
700   color values.  Interrupt input must be blocked when this function
701   is called.  */
702
703void
704x_free_colors (f, pixels, npixels)
705     struct frame *f;
706     unsigned long *pixels;
707     int npixels;
708{
709  int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
710
711  /* If display has an immutable color map, freeing colors is not
712     necessary and some servers don't allow it.  So don't do it.  */
713  if (class != StaticColor && class != StaticGray && class != TrueColor)
714    {
715#ifdef DEBUG_X_COLORS
716      unregister_colors (pixels, npixels);
717#endif
718      XFreeColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
719		   pixels, npixels, 0);
720    }
721}
722
723
724/* Free colors used on frame F.  PIXELS is an array of NPIXELS pixel
725   color values.  Interrupt input must be blocked when this function
726   is called.  */
727
728void
729x_free_dpy_colors (dpy, screen, cmap, pixels, npixels)
730     Display *dpy;
731     Screen *screen;
732     Colormap cmap;
733     unsigned long *pixels;
734     int npixels;
735{
736  struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
737  int class = dpyinfo->visual->class;
738
739  /* If display has an immutable color map, freeing colors is not
740     necessary and some servers don't allow it.  So don't do it.  */
741  if (class != StaticColor && class != StaticGray && class != TrueColor)
742    {
743#ifdef DEBUG_X_COLORS
744      unregister_colors (pixels, npixels);
745#endif
746      XFreeColors (dpy, cmap, pixels, npixels, 0);
747    }
748}
749
750
751/* Create and return a GC for use on frame F.  GC values and mask
752   are given by XGCV and MASK.  */
753
754static INLINE GC
755x_create_gc (f, mask, xgcv)
756     struct frame *f;
757     unsigned long mask;
758     XGCValues *xgcv;
759{
760  GC gc;
761  BLOCK_INPUT;
762  gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, xgcv);
763  UNBLOCK_INPUT;
764  IF_DEBUG (++ngcs);
765  return gc;
766}
767
768
769/* Free GC which was used on frame F.  */
770
771static INLINE void
772x_free_gc (f, gc)
773     struct frame *f;
774     GC gc;
775{
776  BLOCK_INPUT;
777  xassert (--ngcs >= 0);
778  XFreeGC (FRAME_X_DISPLAY (f), gc);
779  UNBLOCK_INPUT;
780}
781
782#endif /* HAVE_X_WINDOWS */
783
784#ifdef WINDOWSNT
785/* W32 emulation of GCs */
786
787static INLINE GC
788x_create_gc (f, mask, xgcv)
789     struct frame *f;
790     unsigned long mask;
791     XGCValues *xgcv;
792{
793  GC gc;
794  BLOCK_INPUT;
795  gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, xgcv);
796  UNBLOCK_INPUT;
797  IF_DEBUG (++ngcs);
798  return gc;
799}
800
801
802/* Free GC which was used on frame F.  */
803
804static INLINE void
805x_free_gc (f, gc)
806     struct frame *f;
807     GC gc;
808{
809  BLOCK_INPUT;
810  xassert (--ngcs >= 0);
811  xfree (gc);
812  UNBLOCK_INPUT;
813}
814
815#endif  /* WINDOWSNT */
816
817/* Like stricmp.  Used to compare parts of font names which are in
818   ISO8859-1.  */
819
820int
821xstricmp (s1, s2)
822     unsigned char *s1, *s2;
823{
824  while (*s1 && *s2)
825    {
826      unsigned char c1 = tolower (*s1);
827      unsigned char c2 = tolower (*s2);
828      if (c1 != c2)
829	return c1 < c2 ? -1 : 1;
830      ++s1, ++s2;
831    }
832
833  if (*s1 == 0)
834    return *s2 == 0 ? 0 : -1;
835  return 1;
836}
837
838
839/* Like strlwr, which might not always be available.  */
840
841static unsigned char *
842xstrlwr (s)
843     unsigned char *s;
844{
845  unsigned char *p = s;
846
847  for (p = s; *p; ++p)
848    *p = tolower (*p);
849
850  return s;
851}
852
853
854/* Signal `error' with message S, and additional argument ARG.  */
855
856static void
857signal_error (s, arg)
858     char *s;
859     Lisp_Object arg;
860{
861  Fsignal (Qerror, Fcons (build_string (s), Fcons (arg, Qnil)));
862}
863
864
865/* If FRAME is nil, return a pointer to the selected frame.
866   Otherwise, check that FRAME is a live frame, and return a pointer
867   to it.  NPARAM is the parameter number of FRAME, for
868   CHECK_LIVE_FRAME.  This is here because it's a frequent pattern in
869   Lisp function definitions.  */
870
871static INLINE struct frame *
872frame_or_selected_frame (frame, nparam)
873     Lisp_Object frame;
874     int nparam;
875{
876  if (NILP (frame))
877    frame = selected_frame;
878
879  CHECK_LIVE_FRAME (frame, nparam);
880  return XFRAME (frame);
881}
882
883
884/***********************************************************************
885			   Frames and faces
886 ***********************************************************************/
887
888/* Initialize face cache and basic faces for frame F.  */
889
890void
891init_frame_faces (f)
892     struct frame *f;
893{
894  /* Make a face cache, if F doesn't have one.  */
895  if (FRAME_FACE_CACHE (f) == NULL)
896    FRAME_FACE_CACHE (f) = make_face_cache (f);
897
898#ifdef HAVE_WINDOW_SYSTEM
899  /* Make the image cache.  */
900  if (FRAME_WINDOW_P (f))
901    {
902      if (FRAME_X_IMAGE_CACHE (f) == NULL)
903	FRAME_X_IMAGE_CACHE (f) = make_image_cache ();
904      ++FRAME_X_IMAGE_CACHE (f)->refcount;
905    }
906#endif /* HAVE_WINDOW_SYSTEM */
907
908  /* Realize basic faces.  Must have enough information in frame
909     parameters to realize basic faces at this point.  */
910#ifdef HAVE_X_WINDOWS
911  if (!FRAME_X_P (f) || FRAME_X_WINDOW (f))
912#endif
913#ifdef WINDOWSNT
914  if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
915#endif
916    if (!realize_basic_faces (f))
917      abort ();
918}
919
920
921/* Free face cache of frame F.  Called from Fdelete_frame.  */
922
923void
924free_frame_faces (f)
925     struct frame *f;
926{
927  struct face_cache *face_cache = FRAME_FACE_CACHE (f);
928
929  if (face_cache)
930    {
931      free_face_cache (face_cache);
932      FRAME_FACE_CACHE (f) = NULL;
933    }
934
935#ifdef HAVE_WINDOW_SYSTEM
936  if (FRAME_WINDOW_P (f))
937    {
938      struct image_cache *image_cache = FRAME_X_IMAGE_CACHE (f);
939      if (image_cache)
940	{
941	  --image_cache->refcount;
942	  if (image_cache->refcount == 0)
943	    free_image_cache (f);
944	}
945    }
946#endif /* HAVE_WINDOW_SYSTEM */
947}
948
949
950/* Clear face caches, and recompute basic faces for frame F.  Call
951   this after changing frame parameters on which those faces depend,
952   or when realized faces have been freed due to changing attributes
953   of named faces. */
954
955void
956recompute_basic_faces (f)
957     struct frame *f;
958{
959  if (FRAME_FACE_CACHE (f))
960    {
961      clear_face_cache (0);
962      if (!realize_basic_faces (f))
963	abort ();
964    }
965}
966
967
968/* Clear the face caches of all frames.  CLEAR_FONTS_P non-zero means
969   try to free unused fonts, too.  */
970
971void
972clear_face_cache (clear_fonts_p)
973     int clear_fonts_p;
974{
975#ifdef HAVE_WINDOW_SYSTEM
976  Lisp_Object tail, frame;
977  struct frame *f;
978
979  if (clear_fonts_p
980      || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
981    {
982      struct x_display_info *dpyinfo;
983
984      /* Fonts are common for frames on one display, i.e. on
985	 one X screen.  */
986      for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
987	if (dpyinfo->n_fonts > CLEAR_FONT_TABLE_NFONTS)
988	  clear_font_table (dpyinfo);
989
990      /* From time to time see if we can unload some fonts.  This also
991	 frees all realized faces on all frames.  Fonts needed by
992	 faces will be loaded again when faces are realized again.  */
993      clear_font_table_count = 0;
994
995      FOR_EACH_FRAME (tail, frame)
996	{
997	  struct frame *f = XFRAME (frame);
998	  if (FRAME_WINDOW_P (f)
999	      && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
1000	    free_all_realized_faces (frame);
1001	}
1002    }
1003  else
1004    {
1005      /* Clear GCs of realized faces.  */
1006      FOR_EACH_FRAME (tail, frame)
1007	{
1008	  f = XFRAME (frame);
1009	  if (FRAME_WINDOW_P (f))
1010	    {
1011	      clear_face_gcs (FRAME_FACE_CACHE (f));
1012	      clear_image_cache (f, 0);
1013	    }
1014	}
1015    }
1016#endif /* HAVE_WINDOW_SYSTEM */
1017}
1018
1019
1020DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
1021  "Clear face caches on all frames.\n\
1022Optional THOROUGHLY non-nil means try to free unused fonts, too.")
1023  (thoroughly)
1024     Lisp_Object thoroughly;
1025{
1026  clear_face_cache (!NILP (thoroughly));
1027  ++face_change_count;
1028  ++windows_or_buffers_changed;
1029  return Qnil;
1030}
1031
1032
1033
1034#ifdef HAVE_WINDOW_SYSTEM
1035
1036
1037/* Remove fonts from the font table of DPYINFO except for the default
1038   ASCII fonts of frames on that display.  Called from clear_face_cache
1039   from time to time.  */
1040
1041static void
1042clear_font_table (dpyinfo)
1043     struct x_display_info *dpyinfo;
1044{
1045  int i;
1046
1047  /* Free those fonts that are not used by frames on DPYINFO.  */
1048  for (i = 0; i < dpyinfo->n_fonts; ++i)
1049    {
1050      struct font_info *font_info = dpyinfo->font_table + i;
1051      Lisp_Object tail, frame;
1052
1053      /* Check if slot is already free.  */
1054      if (font_info->name == NULL)
1055	continue;
1056
1057      /* Don't free a default font of some frame on this display.  */
1058      FOR_EACH_FRAME (tail, frame)
1059	{
1060	  struct frame *f = XFRAME (frame);
1061	  if (FRAME_WINDOW_P (f)
1062	      && FRAME_X_DISPLAY_INFO (f) == dpyinfo
1063	      && font_info->font == FRAME_FONT (f))
1064	    break;
1065	}
1066
1067      if (!NILP (tail))
1068	continue;
1069
1070      /* Free names.  */
1071      if (font_info->full_name != font_info->name)
1072	xfree (font_info->full_name);
1073      xfree (font_info->name);
1074
1075      /* Free the font.  */
1076      BLOCK_INPUT;
1077#ifdef HAVE_X_WINDOWS
1078      XFreeFont (dpyinfo->display, font_info->font);
1079#endif
1080#ifdef WINDOWSNT
1081      w32_unload_font (dpyinfo, font_info->font);
1082#endif
1083      UNBLOCK_INPUT;
1084
1085      /* Mark font table slot free.  */
1086      font_info->font = NULL;
1087      font_info->name = font_info->full_name = NULL;
1088    }
1089}
1090
1091#endif /* HAVE_WINDOW_SYSTEM */
1092
1093
1094
1095/***********************************************************************
1096			      X Pixmaps
1097 ***********************************************************************/
1098
1099#ifdef HAVE_WINDOW_SYSTEM
1100
1101DEFUN ("bitmap-spec-p", Fbitmap_spec_p, Sbitmap_spec_p, 1, 1, 0,
1102  "Value is non-nil if OBJECT is a valid bitmap specification.\n\
1103A bitmap specification is either a string, a file name, or a list\n\
1104(WIDTH HEIGHT DATA) where WIDTH is the pixel width of the bitmap,\n\
1105HEIGHT is its height, and DATA is a string containing the bits of\n\
1106the pixmap.  Bits are stored row by row, each row occupies\n\
1107(WIDTH + 7)/8 bytes.")
1108  (object)
1109     Lisp_Object object;
1110{
1111  int pixmap_p = 0;
1112
1113  if (STRINGP (object))
1114    /* If OBJECT is a string, it's a file name.  */
1115    pixmap_p = 1;
1116  else if (CONSP (object))
1117    {
1118      /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and
1119	 HEIGHT must be integers > 0, and DATA must be string large
1120	 enough to hold a bitmap of the specified size.  */
1121      Lisp_Object width, height, data;
1122
1123      height = width = data = Qnil;
1124
1125      if (CONSP (object))
1126	{
1127	  width = XCAR (object);
1128	  object = XCDR (object);
1129	  if (CONSP (object))
1130	    {
1131	      height = XCAR (object);
1132	      object = XCDR (object);
1133	      if (CONSP (object))
1134		data = XCAR (object);
1135	    }
1136	}
1137
1138      if (NATNUMP (width) && NATNUMP (height) && STRINGP (data))
1139	{
1140	  int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1)
1141			       / BITS_PER_CHAR);
1142	  if (STRING_BYTES (XSTRING (data)) >= bytes_per_row * XINT (height))
1143	    pixmap_p = 1;
1144	}
1145    }
1146
1147  return pixmap_p ? Qt : Qnil;
1148}
1149
1150
1151/* Load a bitmap according to NAME (which is either a file name or a
1152   pixmap spec) for use on frame F.  Value is the bitmap_id (see
1153   xfns.c).  If NAME is nil, return with a bitmap id of zero.  If
1154   bitmap cannot be loaded, display a message saying so, and return
1155   zero.  Store the bitmap width in *W_PTR and its height in *H_PTR,
1156   if these pointers are not null.  */
1157
1158static int
1159load_pixmap (f, name, w_ptr, h_ptr)
1160     FRAME_PTR f;
1161     Lisp_Object name;
1162     unsigned int *w_ptr, *h_ptr;
1163{
1164  int bitmap_id;
1165  Lisp_Object tem;
1166
1167  if (NILP (name))
1168    return 0;
1169
1170  tem = Fbitmap_spec_p (name);
1171  if (NILP (tem))
1172    wrong_type_argument (Qbitmap_spec_p, name);
1173
1174  BLOCK_INPUT;
1175  if (CONSP (name))
1176    {
1177      /* Decode a bitmap spec into a bitmap.  */
1178
1179      int h, w;
1180      Lisp_Object bits;
1181
1182      w = XINT (Fcar (name));
1183      h = XINT (Fcar (Fcdr (name)));
1184      bits = Fcar (Fcdr (Fcdr (name)));
1185
1186      bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data,
1187					     w, h);
1188    }
1189  else
1190    {
1191      /* It must be a string -- a file name.  */
1192      bitmap_id = x_create_bitmap_from_file (f, name);
1193    }
1194  UNBLOCK_INPUT;
1195
1196  if (bitmap_id < 0)
1197    {
1198      add_to_log ("Invalid or undefined bitmap %s", name, Qnil);
1199      bitmap_id = 0;
1200
1201      if (w_ptr)
1202	*w_ptr = 0;
1203      if (h_ptr)
1204	*h_ptr = 0;
1205    }
1206  else
1207    {
1208#if GLYPH_DEBUG
1209      ++npixmaps_allocated;
1210#endif
1211      if (w_ptr)
1212	*w_ptr = x_bitmap_width (f, bitmap_id);
1213
1214      if (h_ptr)
1215	*h_ptr = x_bitmap_height (f, bitmap_id);
1216    }
1217
1218  return bitmap_id;
1219}
1220
1221#endif /* HAVE_WINDOW_SYSTEM */
1222
1223
1224
1225/***********************************************************************
1226			 Minimum font bounds
1227 ***********************************************************************/
1228
1229#ifdef HAVE_WINDOW_SYSTEM
1230
1231/* Update the line_height of frame F.  Return non-zero if line height
1232   changes.  */
1233
1234int
1235frame_update_line_height (f)
1236     struct frame *f;
1237{
1238  int line_height, changed_p;
1239
1240  line_height = FONT_HEIGHT (FRAME_FONT (f));
1241  changed_p = line_height != FRAME_LINE_HEIGHT (f);
1242  FRAME_LINE_HEIGHT (f) = line_height;
1243  return changed_p;
1244}
1245
1246#endif /* HAVE_WINDOW_SYSTEM */
1247
1248
1249/***********************************************************************
1250				Fonts
1251 ***********************************************************************/
1252
1253#ifdef HAVE_WINDOW_SYSTEM
1254
1255/* Load font of face FACE which is used on frame F to display
1256   character C.  The name of the font to load is determined by lface
1257   and fontset of FACE.  */
1258
1259static void
1260load_face_font (f, face, c)
1261     struct frame *f;
1262     struct face *face;
1263     int c;
1264{
1265  struct font_info *font_info = NULL;
1266  char *font_name;
1267
1268  face->font_info_id = -1;
1269  face->font = NULL;
1270
1271  font_name = choose_face_font (f, face->lface, face->fontset, c);
1272  if (!font_name)
1273    return;
1274
1275  BLOCK_INPUT;
1276  font_info = FS_LOAD_FACE_FONT (f, c, font_name, face);
1277  UNBLOCK_INPUT;
1278
1279  if (font_info)
1280    {
1281      face->font_info_id = font_info->font_idx;
1282      face->font = font_info->font;
1283      face->font_name = font_info->full_name;
1284      if (face->gc)
1285	{
1286	  x_free_gc (f, face->gc);
1287	  face->gc = 0;
1288	}
1289    }
1290  else
1291    add_to_log ("Unable to load font %s",
1292		build_string (font_name), Qnil);
1293  xfree (font_name);
1294}
1295
1296#endif /* HAVE_WINDOW_SYSTEM */
1297
1298
1299
1300/***********************************************************************
1301				X Colors
1302 ***********************************************************************/
1303
1304/* A version of defined_color for non-X frames.  */
1305
1306int
1307tty_defined_color (f, color_name, color_def, alloc)
1308     struct frame *f;
1309     char *color_name;
1310     XColor *color_def;
1311     int alloc;
1312{
1313  Lisp_Object color_desc;
1314  unsigned long color_idx = FACE_TTY_DEFAULT_COLOR;
1315  unsigned long red = 0, green = 0, blue = 0;
1316  int status = 1;
1317
1318  if (*color_name && !NILP (Ffboundp (Qtty_color_desc)))
1319    {
1320      Lisp_Object frame;
1321
1322      XSETFRAME (frame, f);
1323      status = 0;
1324      color_desc = call2 (Qtty_color_desc, build_string (color_name), frame);
1325      if (CONSP (color_desc) && CONSP (XCDR (color_desc)))
1326	{
1327	  color_idx = XINT (XCAR (XCDR (color_desc)));
1328	  if (CONSP (XCDR (XCDR (color_desc))))
1329	    {
1330	      red = XINT (XCAR (XCDR (XCDR (color_desc))));
1331	      green = XINT (XCAR (XCDR (XCDR (XCDR (color_desc)))));
1332	      blue = XINT (XCAR (XCDR (XCDR (XCDR (XCDR (color_desc))))));
1333	    }
1334	  status = 1;
1335	}
1336      else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist"))))
1337	/* We were called early during startup, and the colors are not
1338	   yet set up in tty-defined-color-alist.  Don't return a failure
1339	   indication, since this produces the annoying "Unable to
1340	   load color" messages in the *Messages* buffer.  */
1341	status = 1;
1342    }
1343  if (color_idx == FACE_TTY_DEFAULT_COLOR && *color_name)
1344    {
1345      if (strcmp (color_name, "unspecified-fg") == 0)
1346	color_idx = FACE_TTY_DEFAULT_FG_COLOR;
1347      else if (strcmp (color_name, "unspecified-bg") == 0)
1348	color_idx = FACE_TTY_DEFAULT_BG_COLOR;
1349    }
1350
1351  if (color_idx != FACE_TTY_DEFAULT_COLOR)
1352    status = 1;
1353
1354  color_def->pixel = color_idx;
1355  color_def->red = red;
1356  color_def->green = green;
1357  color_def->blue = blue;
1358
1359  return status;
1360}
1361
1362
1363/* Decide if color named COLOR_NAME is valid for the display
1364   associated with the frame F; if so, return the rgb values in
1365   COLOR_DEF.  If ALLOC is nonzero, allocate a new colormap cell.
1366
1367   This does the right thing for any type of frame.  */
1368
1369int
1370defined_color (f, color_name, color_def, alloc)
1371     struct frame *f;
1372     char *color_name;
1373     XColor *color_def;
1374     int alloc;
1375{
1376  if (!FRAME_WINDOW_P (f))
1377    return tty_defined_color (f, color_name, color_def, alloc);
1378#ifdef HAVE_X_WINDOWS
1379  else if (FRAME_X_P (f))
1380    return x_defined_color (f, color_name, color_def, alloc);
1381#endif
1382#ifdef WINDOWSNT
1383  else if (FRAME_W32_P (f))
1384    return w32_defined_color (f, color_name, color_def, alloc);
1385#endif
1386#ifdef macintosh
1387  else if (FRAME_MAC_P (f))
1388    return mac_defined_color (f, color_name, color_def, alloc);
1389#endif
1390  else
1391    abort ();
1392}
1393
1394
1395/* Given the index IDX of a tty color on frame F, return its name, a
1396   Lisp string.  */
1397
1398Lisp_Object
1399tty_color_name (f, idx)
1400     struct frame *f;
1401     int idx;
1402{
1403  if (idx >= 0 && !NILP (Ffboundp (Qtty_color_by_index)))
1404    {
1405      Lisp_Object frame;
1406      Lisp_Object coldesc;
1407
1408      XSETFRAME (frame, f);
1409      coldesc = call2 (Qtty_color_by_index, make_number (idx), frame);
1410
1411      if (!NILP (coldesc))
1412	return XCAR (coldesc);
1413    }
1414#ifdef MSDOS
1415  /* We can have an MSDOG frame under -nw for a short window of
1416     opportunity before internal_terminal_init is called.  DTRT.  */
1417  if (FRAME_MSDOS_P (f) && !inhibit_window_system)
1418    return msdos_stdcolor_name (idx);
1419#endif
1420
1421  if (idx == FACE_TTY_DEFAULT_FG_COLOR)
1422    return build_string (unspecified_fg);
1423  if (idx == FACE_TTY_DEFAULT_BG_COLOR)
1424    return build_string (unspecified_bg);
1425
1426#ifdef WINDOWSNT
1427  return vga_stdcolor_name (idx);
1428#endif
1429
1430  return Qunspecified;
1431}
1432
1433
1434/* Return non-zero if COLOR_NAME is a shade of gray (or white or
1435   black) on frame F.  The algorithm is taken from 20.2 faces.el.  */
1436
1437static int
1438face_color_gray_p (f, color_name)
1439     struct frame *f;
1440     char *color_name;
1441{
1442  XColor color;
1443  int gray_p;
1444
1445  if (defined_color (f, color_name, &color, 0))
1446    gray_p = ((abs (color.red - color.green)
1447	       < max (color.red, color.green) / 20)
1448	      && (abs (color.green - color.blue)
1449		  < max (color.green, color.blue) / 20)
1450	      && (abs (color.blue - color.red)
1451		  < max (color.blue, color.red) / 20));
1452  else
1453    gray_p = 0;
1454
1455  return gray_p;
1456}
1457
1458
1459/* Return non-zero if color COLOR_NAME can be displayed on frame F.
1460   BACKGROUND_P non-zero means the color will be used as background
1461   color.  */
1462
1463static int
1464face_color_supported_p (f, color_name, background_p)
1465     struct frame *f;
1466     char *color_name;
1467     int background_p;
1468{
1469  Lisp_Object frame;
1470  XColor not_used;
1471
1472  XSETFRAME (frame, f);
1473  return (FRAME_WINDOW_P (f)
1474	  ? (!NILP (Fxw_display_color_p (frame))
1475	     || xstricmp (color_name, "black") == 0
1476	     || xstricmp (color_name, "white") == 0
1477	     || (background_p
1478		 && face_color_gray_p (f, color_name))
1479	     || (!NILP (Fx_display_grayscale_p (frame))
1480		 && face_color_gray_p (f, color_name)))
1481	  : tty_defined_color (f, color_name, &not_used, 0));
1482}
1483
1484
1485DEFUN ("color-gray-p", Fcolor_gray_p, Scolor_gray_p, 1, 2, 0,
1486  "Return non-nil if COLOR is a shade of gray (or white or black).\n\
1487FRAME specifies the frame and thus the display for interpreting COLOR.\n\
1488If FRAME is nil or omitted, use the selected frame.")
1489   (color, frame)
1490     Lisp_Object color, frame;
1491{
1492  struct frame *f;
1493
1494  CHECK_FRAME (frame, 0);
1495  CHECK_STRING (color, 0);
1496  f = XFRAME (frame);
1497  return face_color_gray_p (f, XSTRING (color)->data) ? Qt : Qnil;
1498}
1499
1500
1501DEFUN ("color-supported-p", Fcolor_supported_p,
1502       Scolor_supported_p, 2, 3, 0,
1503  "Return non-nil if COLOR can be displayed on FRAME.\n\
1504BACKGROUND-P non-nil means COLOR is used as a background.\n\
1505If FRAME is nil or omitted, use the selected frame.\n\
1506COLOR must be a valid color name.")
1507   (color, frame, background_p)
1508     Lisp_Object frame, color, background_p;
1509{
1510  struct frame *f;
1511
1512  CHECK_FRAME (frame, 0);
1513  CHECK_STRING (color, 0);
1514  f = XFRAME (frame);
1515  if (face_color_supported_p (f, XSTRING (color)->data, !NILP (background_p)))
1516    return Qt;
1517  return Qnil;
1518}
1519
1520
1521/* Load color with name NAME for use by face FACE on frame F.
1522   TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
1523   LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
1524   LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX.  Value is the
1525   pixel color.  If color cannot be loaded, display a message, and
1526   return the foreground, background or underline color of F, but
1527   record that fact in flags of the face so that we don't try to free
1528   these colors.  */
1529
1530unsigned long
1531load_color (f, face, name, target_index)
1532     struct frame *f;
1533     struct face *face;
1534     Lisp_Object name;
1535     enum lface_attribute_index target_index;
1536{
1537  XColor color;
1538
1539  xassert (STRINGP (name));
1540  xassert (target_index == LFACE_FOREGROUND_INDEX
1541	   || target_index == LFACE_BACKGROUND_INDEX
1542	   || target_index == LFACE_UNDERLINE_INDEX
1543	   || target_index == LFACE_OVERLINE_INDEX
1544	   || target_index == LFACE_STRIKE_THROUGH_INDEX
1545	   || target_index == LFACE_BOX_INDEX);
1546
1547  /* if the color map is full, defined_color will return a best match
1548     to the values in an existing cell. */
1549  if (!defined_color (f, XSTRING (name)->data, &color, 1))
1550    {
1551      add_to_log ("Unable to load color \"%s\"", name, Qnil);
1552
1553      switch (target_index)
1554	{
1555	case LFACE_FOREGROUND_INDEX:
1556	  face->foreground_defaulted_p = 1;
1557	  color.pixel = FRAME_FOREGROUND_PIXEL (f);
1558	  break;
1559
1560	case LFACE_BACKGROUND_INDEX:
1561	  face->background_defaulted_p = 1;
1562	  color.pixel = FRAME_BACKGROUND_PIXEL (f);
1563	  break;
1564
1565	case LFACE_UNDERLINE_INDEX:
1566	  face->underline_defaulted_p = 1;
1567	  color.pixel = FRAME_FOREGROUND_PIXEL (f);
1568	  break;
1569
1570	case LFACE_OVERLINE_INDEX:
1571	  face->overline_color_defaulted_p = 1;
1572	  color.pixel = FRAME_FOREGROUND_PIXEL (f);
1573	  break;
1574
1575	case LFACE_STRIKE_THROUGH_INDEX:
1576	  face->strike_through_color_defaulted_p = 1;
1577	  color.pixel = FRAME_FOREGROUND_PIXEL (f);
1578	  break;
1579
1580	case LFACE_BOX_INDEX:
1581	  face->box_color_defaulted_p = 1;
1582	  color.pixel = FRAME_FOREGROUND_PIXEL (f);
1583	  break;
1584
1585	default:
1586	  abort ();
1587	}
1588    }
1589#if GLYPH_DEBUG
1590  else
1591    ++ncolors_allocated;
1592#endif
1593
1594  return color.pixel;
1595}
1596
1597
1598#ifdef HAVE_WINDOW_SYSTEM
1599
1600/* Load colors for face FACE which is used on frame F.  Colors are
1601   specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
1602   of ATTRS.  If the background color specified is not supported on F,
1603   try to emulate gray colors with a stipple from Vface_default_stipple.  */
1604
1605static void
1606load_face_colors (f, face, attrs)
1607     struct frame *f;
1608     struct face *face;
1609     Lisp_Object *attrs;
1610{
1611  Lisp_Object fg, bg;
1612
1613  bg = attrs[LFACE_BACKGROUND_INDEX];
1614  fg = attrs[LFACE_FOREGROUND_INDEX];
1615
1616  /* Swap colors if face is inverse-video.  */
1617  if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
1618    {
1619      Lisp_Object tmp;
1620      tmp = fg;
1621      fg = bg;
1622      bg = tmp;
1623    }
1624
1625  /* Check for support for foreground, not for background because
1626     face_color_supported_p is smart enough to know that grays are
1627     "supported" as background because we are supposed to use stipple
1628     for them.  */
1629  if (!face_color_supported_p (f, XSTRING (bg)->data, 0)
1630      && !NILP (Fbitmap_spec_p (Vface_default_stipple)))
1631    {
1632      x_destroy_bitmap (f, face->stipple);
1633      face->stipple = load_pixmap (f, Vface_default_stipple,
1634				   &face->pixmap_w, &face->pixmap_h);
1635    }
1636
1637  face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
1638  face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
1639}
1640
1641
1642/* Free color PIXEL on frame F.  */
1643
1644void
1645unload_color (f, pixel)
1646     struct frame *f;
1647     unsigned long pixel;
1648{
1649#ifdef HAVE_X_WINDOWS
1650  if (pixel != -1)
1651    {
1652      BLOCK_INPUT;
1653      x_free_colors (f, &pixel, 1);
1654      UNBLOCK_INPUT;
1655    }
1656#endif
1657}
1658
1659
1660/* Free colors allocated for FACE.  */
1661
1662static void
1663free_face_colors (f, face)
1664     struct frame *f;
1665     struct face *face;
1666{
1667#ifdef HAVE_X_WINDOWS
1668  if (face->colors_copied_bitwise_p)
1669    return;
1670
1671  BLOCK_INPUT;
1672
1673  if (!face->foreground_defaulted_p)
1674    {
1675      x_free_colors (f, &face->foreground, 1);
1676      IF_DEBUG (--ncolors_allocated);
1677    }
1678
1679  if (!face->background_defaulted_p)
1680    {
1681      x_free_colors (f, &face->background, 1);
1682      IF_DEBUG (--ncolors_allocated);
1683    }
1684
1685  if (face->underline_p
1686      && !face->underline_defaulted_p)
1687    {
1688      x_free_colors (f, &face->underline_color, 1);
1689      IF_DEBUG (--ncolors_allocated);
1690    }
1691
1692  if (face->overline_p
1693      && !face->overline_color_defaulted_p)
1694    {
1695      x_free_colors (f, &face->overline_color, 1);
1696      IF_DEBUG (--ncolors_allocated);
1697    }
1698
1699  if (face->strike_through_p
1700      && !face->strike_through_color_defaulted_p)
1701    {
1702      x_free_colors (f, &face->strike_through_color, 1);
1703      IF_DEBUG (--ncolors_allocated);
1704    }
1705
1706  if (face->box != FACE_NO_BOX
1707      && !face->box_color_defaulted_p)
1708    {
1709      x_free_colors (f, &face->box_color, 1);
1710      IF_DEBUG (--ncolors_allocated);
1711    }
1712
1713  UNBLOCK_INPUT;
1714#endif /* HAVE_X_WINDOWS */
1715}
1716
1717#endif /* HAVE_WINDOW_SYSTEM */
1718
1719
1720
1721/***********************************************************************
1722			   XLFD Font Names
1723 ***********************************************************************/
1724
1725/* An enumerator for each field of an XLFD font name.  */
1726
1727enum xlfd_field
1728{
1729  XLFD_FOUNDRY,
1730  XLFD_FAMILY,
1731  XLFD_WEIGHT,
1732  XLFD_SLANT,
1733  XLFD_SWIDTH,
1734  XLFD_ADSTYLE,
1735  XLFD_PIXEL_SIZE,
1736  XLFD_POINT_SIZE,
1737  XLFD_RESX,
1738  XLFD_RESY,
1739  XLFD_SPACING,
1740  XLFD_AVGWIDTH,
1741  XLFD_REGISTRY,
1742  XLFD_ENCODING,
1743  XLFD_LAST
1744};
1745
1746/* An enumerator for each possible slant value of a font.  Taken from
1747   the XLFD specification.  */
1748
1749enum xlfd_slant
1750{
1751  XLFD_SLANT_UNKNOWN,
1752  XLFD_SLANT_ROMAN,
1753  XLFD_SLANT_ITALIC,
1754  XLFD_SLANT_OBLIQUE,
1755  XLFD_SLANT_REVERSE_ITALIC,
1756  XLFD_SLANT_REVERSE_OBLIQUE,
1757  XLFD_SLANT_OTHER
1758};
1759
1760/* Relative font weight according to XLFD documentation.  */
1761
1762enum xlfd_weight
1763{
1764  XLFD_WEIGHT_UNKNOWN,
1765  XLFD_WEIGHT_ULTRA_LIGHT,	/* 10 */
1766  XLFD_WEIGHT_EXTRA_LIGHT,	/* 20 */
1767  XLFD_WEIGHT_LIGHT,		/* 30 */
1768  XLFD_WEIGHT_SEMI_LIGHT,	/* 40: SemiLight, Book, ...  */
1769  XLFD_WEIGHT_MEDIUM,		/* 50: Medium, Normal, Regular, ...  */
1770  XLFD_WEIGHT_SEMI_BOLD,	/* 60: SemiBold, DemiBold, ...  */
1771  XLFD_WEIGHT_BOLD,		/* 70: Bold, ... */
1772  XLFD_WEIGHT_EXTRA_BOLD,	/* 80: ExtraBold, Heavy, ...  */
1773  XLFD_WEIGHT_ULTRA_BOLD	/* 90: UltraBold, Black, ...  */
1774};
1775
1776/* Relative proportionate width.  */
1777
1778enum xlfd_swidth
1779{
1780  XLFD_SWIDTH_UNKNOWN,
1781  XLFD_SWIDTH_ULTRA_CONDENSED,	/* 10 */
1782  XLFD_SWIDTH_EXTRA_CONDENSED,	/* 20 */
1783  XLFD_SWIDTH_CONDENSED,	/* 30: Condensed, Narrow, Compressed, ... */
1784  XLFD_SWIDTH_SEMI_CONDENSED,	/* 40: semicondensed */
1785  XLFD_SWIDTH_MEDIUM,		/* 50: Medium, Normal, Regular, ... */
1786  XLFD_SWIDTH_SEMI_EXPANDED,	/* 60: SemiExpanded, DemiExpanded, ... */
1787  XLFD_SWIDTH_EXPANDED,		/* 70: Expanded... */
1788  XLFD_SWIDTH_EXTRA_EXPANDED,	/* 80: ExtraExpanded, Wide...  */
1789  XLFD_SWIDTH_ULTRA_EXPANDED	/* 90: UltraExpanded... */
1790};
1791
1792/* Structure used for tables mapping XLFD weight, slant, and width
1793   names to numeric and symbolic values.  */
1794
1795struct table_entry
1796{
1797  char *name;
1798  int numeric;
1799  Lisp_Object *symbol;
1800};
1801
1802/* Table of XLFD slant names and their numeric and symbolic
1803   representations.  This table must be sorted by slant names in
1804   ascending order.  */
1805
1806static struct table_entry slant_table[] =
1807{
1808  {"i",			XLFD_SLANT_ITALIC,		&Qitalic},
1809  {"o",			XLFD_SLANT_OBLIQUE,		&Qoblique},
1810  {"ot",		XLFD_SLANT_OTHER,		&Qitalic},
1811  {"r",			XLFD_SLANT_ROMAN,		&Qnormal},
1812  {"ri",		XLFD_SLANT_REVERSE_ITALIC,	&Qreverse_italic},
1813  {"ro",		XLFD_SLANT_REVERSE_OBLIQUE,	&Qreverse_oblique}
1814};
1815
1816/* Table of XLFD weight names.  This table must be sorted by weight
1817   names in ascending order.  */
1818
1819static struct table_entry weight_table[] =
1820{
1821  {"black",		XLFD_WEIGHT_ULTRA_BOLD,		&Qultra_bold},
1822  {"bold",		XLFD_WEIGHT_BOLD,		&Qbold},
1823  {"book",		XLFD_WEIGHT_SEMI_LIGHT,		&Qsemi_light},
1824  {"demi",		XLFD_WEIGHT_SEMI_BOLD,		&Qsemi_bold},
1825  {"demibold",		XLFD_WEIGHT_SEMI_BOLD,		&Qsemi_bold},
1826  {"extralight",	XLFD_WEIGHT_EXTRA_LIGHT,	&Qextra_light},
1827  {"extrabold",		XLFD_WEIGHT_EXTRA_BOLD,		&Qextra_bold},
1828  {"heavy",		XLFD_WEIGHT_EXTRA_BOLD,		&Qextra_bold},
1829  {"light",		XLFD_WEIGHT_LIGHT,		&Qlight},
1830  {"medium",		XLFD_WEIGHT_MEDIUM,		&Qnormal},
1831  {"normal",		XLFD_WEIGHT_MEDIUM,		&Qnormal},
1832  {"regular",		XLFD_WEIGHT_MEDIUM,		&Qnormal},
1833  {"semibold",		XLFD_WEIGHT_SEMI_BOLD,		&Qsemi_bold},
1834  {"semilight",		XLFD_WEIGHT_SEMI_LIGHT,		&Qsemi_light},
1835  {"ultralight",	XLFD_WEIGHT_ULTRA_LIGHT,	&Qultra_light},
1836  {"ultrabold",		XLFD_WEIGHT_ULTRA_BOLD,		&Qultra_bold}
1837};
1838
1839/* Table of XLFD width names.  This table must be sorted by width
1840   names in ascending order.  */
1841
1842static struct table_entry swidth_table[] =
1843{
1844  {"compressed",	XLFD_SWIDTH_CONDENSED,		&Qcondensed},
1845  {"condensed",		XLFD_SWIDTH_CONDENSED,		&Qcondensed},
1846  {"demiexpanded",	XLFD_SWIDTH_SEMI_EXPANDED,	&Qsemi_expanded},
1847  {"expanded",		XLFD_SWIDTH_EXPANDED,		&Qexpanded},
1848  {"extracondensed",	XLFD_SWIDTH_EXTRA_CONDENSED,	&Qextra_condensed},
1849  {"extraexpanded",	XLFD_SWIDTH_EXTRA_EXPANDED,	&Qextra_expanded},
1850  {"medium",		XLFD_SWIDTH_MEDIUM,		&Qnormal},
1851  {"narrow",		XLFD_SWIDTH_CONDENSED,		&Qcondensed},
1852  {"normal",		XLFD_SWIDTH_MEDIUM,		&Qnormal},
1853  {"regular",		XLFD_SWIDTH_MEDIUM,		&Qnormal},
1854  {"semicondensed",	XLFD_SWIDTH_SEMI_CONDENSED,	&Qsemi_condensed},
1855  {"semiexpanded",	XLFD_SWIDTH_SEMI_EXPANDED,	&Qsemi_expanded},
1856  {"ultracondensed",	XLFD_SWIDTH_ULTRA_CONDENSED,	&Qultra_condensed},
1857  {"ultraexpanded",	XLFD_SWIDTH_ULTRA_EXPANDED,	&Qultra_expanded},
1858  {"wide",		XLFD_SWIDTH_EXTRA_EXPANDED,	&Qextra_expanded}
1859};
1860
1861/* Structure used to hold the result of splitting font names in XLFD
1862   format into their fields.  */
1863
1864struct font_name
1865{
1866  /* The original name which is modified destructively by
1867     split_font_name.  The pointer is kept here to be able to free it
1868     if it was allocated from the heap.  */
1869  char *name;
1870
1871  /* Font name fields.  Each vector element points into `name' above.
1872     Fields are NUL-terminated.  */
1873  char *fields[XLFD_LAST];
1874
1875  /* Numeric values for those fields that interest us.  See
1876     split_font_name for which these are.  */
1877  int numeric[XLFD_LAST];
1878
1879  /* Lower value mean higher priority.  */
1880  int registry_priority;
1881};
1882
1883/* The frame in effect when sorting font names.  Set temporarily in
1884   sort_fonts so that it is available in font comparison functions.  */
1885
1886static struct frame *font_frame;
1887
1888/* Order by which font selection chooses fonts.  The default values
1889   mean `first, find a best match for the font width, then for the
1890   font height, then for weight, then for slant.'  This variable can be
1891   set via set-face-font-sort-order.  */
1892
1893#ifdef macintosh
1894static int font_sort_order[4] = {
1895  XLFD_SWIDTH, XLFD_POINT_SIZE, XLFD_WEIGHT, XLFD_SLANT
1896};
1897#else
1898static int font_sort_order[4];
1899#endif
1900
1901/* Look up FONT.fields[FIELD_INDEX] in TABLE which has DIM entries.
1902   TABLE must be sorted by TABLE[i]->name in ascending order.  Value
1903   is a pointer to the matching table entry or null if no table entry
1904   matches.  */
1905
1906static struct table_entry *
1907xlfd_lookup_field_contents (table, dim, font, field_index)
1908     struct table_entry *table;
1909     int dim;
1910     struct font_name *font;
1911     int field_index;
1912{
1913  /* Function split_font_name converts fields to lower-case, so there
1914     is no need to use xstrlwr or xstricmp here.  */
1915  char *s = font->fields[field_index];
1916  int low, mid, high, cmp;
1917
1918  low = 0;
1919  high = dim - 1;
1920
1921  while (low <= high)
1922    {
1923      mid = (low + high) / 2;
1924      cmp = strcmp (table[mid].name, s);
1925
1926      if (cmp < 0)
1927	low = mid + 1;
1928      else if (cmp > 0)
1929	high = mid - 1;
1930      else
1931	return table + mid;
1932    }
1933
1934  return NULL;
1935}
1936
1937
1938/* Return a numeric representation for font name field
1939   FONT.fields[FIELD_INDEX].  The field is looked up in TABLE which
1940   has DIM entries.  Value is the numeric value found or DFLT if no
1941   table entry matches.  This function is used to translate weight,
1942   slant, and swidth names of XLFD font names to numeric values.  */
1943
1944static INLINE int
1945xlfd_numeric_value (table, dim, font, field_index, dflt)
1946     struct table_entry *table;
1947     int dim;
1948     struct font_name *font;
1949     int field_index;
1950     int dflt;
1951{
1952  struct table_entry *p;
1953  p = xlfd_lookup_field_contents (table, dim, font, field_index);
1954  return p ? p->numeric : dflt;
1955}
1956
1957
1958/* Return a symbolic representation for font name field
1959   FONT.fields[FIELD_INDEX].  The field is looked up in TABLE which
1960   has DIM entries.  Value is the symbolic value found or DFLT if no
1961   table entry matches.  This function is used to translate weight,
1962   slant, and swidth names of XLFD font names to symbols.  */
1963
1964static INLINE Lisp_Object
1965xlfd_symbolic_value (table, dim, font, field_index, dflt)
1966     struct table_entry *table;
1967     int dim;
1968     struct font_name *font;
1969     int field_index;
1970     Lisp_Object dflt;
1971{
1972  struct table_entry *p;
1973  p = xlfd_lookup_field_contents (table, dim, font, field_index);
1974  return p ? *p->symbol : dflt;
1975}
1976
1977
1978/* Return a numeric value for the slant of the font given by FONT.  */
1979
1980static INLINE int
1981xlfd_numeric_slant (font)
1982     struct font_name *font;
1983{
1984  return xlfd_numeric_value (slant_table, DIM (slant_table),
1985			     font, XLFD_SLANT, XLFD_SLANT_ROMAN);
1986}
1987
1988
1989/* Return a symbol representing the weight of the font given by FONT.  */
1990
1991static INLINE Lisp_Object
1992xlfd_symbolic_slant (font)
1993     struct font_name *font;
1994{
1995  return xlfd_symbolic_value (slant_table, DIM (slant_table),
1996			      font, XLFD_SLANT, Qnormal);
1997}
1998
1999
2000/* Return a numeric value for the weight of the font given by FONT.  */
2001
2002static INLINE int
2003xlfd_numeric_weight (font)
2004     struct font_name *font;
2005{
2006  return xlfd_numeric_value (weight_table, DIM (weight_table),
2007			     font, XLFD_WEIGHT, XLFD_WEIGHT_MEDIUM);
2008}
2009
2010
2011/* Return a symbol representing the slant of the font given by FONT.  */
2012
2013static INLINE Lisp_Object
2014xlfd_symbolic_weight (font)
2015     struct font_name *font;
2016{
2017  return xlfd_symbolic_value (weight_table, DIM (weight_table),
2018			      font, XLFD_WEIGHT, Qnormal);
2019}
2020
2021
2022/* Return a numeric value for the swidth of the font whose XLFD font
2023   name fields are found in FONT.  */
2024
2025static INLINE int
2026xlfd_numeric_swidth (font)
2027     struct font_name *font;
2028{
2029  return xlfd_numeric_value (swidth_table, DIM (swidth_table),
2030			     font, XLFD_SWIDTH, XLFD_SWIDTH_MEDIUM);
2031}
2032
2033
2034/* Return a symbolic value for the swidth of FONT.  */
2035
2036static INLINE Lisp_Object
2037xlfd_symbolic_swidth (font)
2038     struct font_name *font;
2039{
2040  return xlfd_symbolic_value (swidth_table, DIM (swidth_table),
2041			      font, XLFD_SWIDTH, Qnormal);
2042}
2043
2044
2045/* Look up the entry of SYMBOL in the vector TABLE which has DIM
2046   entries.  Value is a pointer to the matching table entry or null if
2047   no element of TABLE contains SYMBOL.  */
2048
2049static struct table_entry *
2050face_value (table, dim, symbol)
2051     struct table_entry *table;
2052     int dim;
2053     Lisp_Object symbol;
2054{
2055  int i;
2056
2057  xassert (SYMBOLP (symbol));
2058
2059  for (i = 0; i < dim; ++i)
2060    if (EQ (*table[i].symbol, symbol))
2061      break;
2062
2063  return i < dim ? table + i : NULL;
2064}
2065
2066
2067/* Return a numeric value for SYMBOL in the vector TABLE which has DIM
2068   entries.  Value is -1 if SYMBOL is not found in TABLE.  */
2069
2070static INLINE int
2071face_numeric_value (table, dim, symbol)
2072     struct table_entry *table;
2073     int dim;
2074     Lisp_Object symbol;
2075{
2076  struct table_entry *p = face_value (table, dim, symbol);
2077  return p ? p->numeric : -1;
2078}
2079
2080
2081/* Return a numeric value representing the weight specified by Lisp
2082   symbol WEIGHT.  Value is one of the enumerators of enum
2083   xlfd_weight.  */
2084
2085static INLINE int
2086face_numeric_weight (weight)
2087     Lisp_Object weight;
2088{
2089  return face_numeric_value (weight_table, DIM (weight_table), weight);
2090}
2091
2092
2093/* Return a numeric value representing the slant specified by Lisp
2094   symbol SLANT.  Value is one of the enumerators of enum xlfd_slant.  */
2095
2096static INLINE int
2097face_numeric_slant (slant)
2098     Lisp_Object slant;
2099{
2100  return face_numeric_value (slant_table, DIM (slant_table), slant);
2101}
2102
2103
2104/* Return a numeric value representing the swidth specified by Lisp
2105   symbol WIDTH.  Value is one of the enumerators of enum xlfd_swidth.  */
2106
2107static int
2108face_numeric_swidth (width)
2109     Lisp_Object width;
2110{
2111  return face_numeric_value (swidth_table, DIM (swidth_table), width);
2112}
2113
2114
2115#ifdef HAVE_WINDOW_SYSTEM
2116
2117/* Return non-zero if FONT is the name of a fixed-pitch font.  */
2118
2119static INLINE int
2120xlfd_fixed_p (font)
2121     struct font_name *font;
2122{
2123  /* Function split_font_name converts fields to lower-case, so there
2124     is no need to use tolower here.  */
2125  return *font->fields[XLFD_SPACING] != 'p';
2126}
2127
2128
2129/* Return the point size of FONT on frame F, measured in 1/10 pt.
2130
2131   The actual height of the font when displayed on F depends on the
2132   resolution of both the font and frame.  For example, a 10pt font
2133   designed for a 100dpi display will display larger than 10pt on a
2134   75dpi display.  (It's not unusual to use fonts not designed for the
2135   display one is using.  For example, some intlfonts are available in
2136   72dpi versions, only.)
2137
2138   Value is the real point size of FONT on frame F, or 0 if it cannot
2139   be determined.  */
2140
2141static INLINE int
2142xlfd_point_size (f, font)
2143     struct frame *f;
2144     struct font_name *font;
2145{
2146  double resy = FRAME_X_DISPLAY_INFO (f)->resy;
2147  char *pixel_field = font->fields[XLFD_PIXEL_SIZE];
2148  double pixel;
2149  int real_pt;
2150
2151  if (*pixel_field == '[')
2152    {
2153      /* The pixel size field is `[A B C D]' which specifies
2154	 a transformation matrix.
2155
2156	 A  B  0
2157	 C  D  0
2158	 0  0  1
2159
2160	 by which all glyphs of the font are transformed.  The spec
2161	 says that s scalar value N for the pixel size is equivalent
2162	 to A = N * resx/resy, B = C = 0, D = N.  */
2163      char *start = pixel_field + 1, *end;
2164      double matrix[4];
2165      int i;
2166
2167      for (i = 0; i < 4; ++i)
2168	{
2169	  matrix[i] = strtod (start, &end);
2170	  start = end;
2171	}
2172
2173      pixel = matrix[3];
2174    }
2175  else
2176    pixel = atoi (pixel_field);
2177
2178  if (pixel == 0)
2179    real_pt = 0;
2180  else
2181    real_pt = PT_PER_INCH * 10.0 * pixel / resy + 0.5;
2182
2183  return real_pt;
2184}
2185
2186
2187/* Return point size of PIXEL dots while considering Y-resultion (DPI)
2188   of frame F.  This function is used to guess a point size of font
2189   when only the pixel height of the font is available.  */
2190
2191static INLINE int
2192pixel_point_size (f, pixel)
2193     struct frame *f;
2194     int pixel;
2195{
2196  double resy = FRAME_X_DISPLAY_INFO (f)->resy;
2197  double real_pt;
2198  int int_pt;
2199
2200  /* As one inch is PT_PER_INCH points, PT_PER_INCH/RESY gives the
2201     point size of one dot.  */
2202  real_pt = pixel * PT_PER_INCH / resy;
2203  int_pt = real_pt + 0.5;
2204
2205  return int_pt;
2206}
2207
2208
2209/* Split XLFD font name FONT->name destructively into NUL-terminated,
2210   lower-case fields in FONT->fields.  NUMERIC_P non-zero means
2211   compute numeric values for fields XLFD_POINT_SIZE, XLFD_SWIDTH,
2212   XLFD_RESY, XLFD_SLANT, and XLFD_WEIGHT in FONT->numeric.  Value is
2213   zero if the font name doesn't have the format we expect.  The
2214   expected format is a font name that starts with a `-' and has
2215   XLFD_LAST fields separated by `-'.  */
2216
2217static int
2218split_font_name (f, font, numeric_p)
2219     struct frame *f;
2220     struct font_name *font;
2221     int numeric_p;
2222{
2223  int i = 0;
2224  int success_p;
2225
2226  if (*font->name == '-')
2227    {
2228      char *p = xstrlwr (font->name) + 1;
2229
2230      while (i < XLFD_LAST)
2231	{
2232	  font->fields[i] = p;
2233	  ++i;
2234
2235	  /* Pixel and point size may be of the form `[....]'.  For
2236	     BNF, see XLFD spec, chapter 4.  Negative values are
2237	     indicated by tilde characters which we replace with
2238	     `-' characters, here.  */
2239	  if (*p == '['
2240	      && (i - 1 == XLFD_PIXEL_SIZE
2241		  || i - 1 == XLFD_POINT_SIZE))
2242	    {
2243	      char *start, *end;
2244	      int j;
2245
2246	      for (++p; *p && *p != ']'; ++p)
2247		if (*p == '~')
2248		  *p = '-';
2249
2250	      /* Check that the matrix contains 4 floating point
2251		 numbers.  */
2252	      for (j = 0, start = font->fields[i - 1] + 1;
2253		   j < 4;
2254		   ++j, start = end)
2255		if (strtod (start, &end) == 0 && start == end)
2256		  break;
2257
2258	      if (j < 4)
2259		break;
2260	    }
2261
2262	  while (*p && *p != '-')
2263	    ++p;
2264
2265	  if (*p != '-')
2266	    break;
2267
2268	  *p++ = 0;
2269	}
2270    }
2271
2272  success_p = i == XLFD_LAST;
2273
2274  /* If requested, and font name was in the expected format,
2275     compute numeric values for some fields.  */
2276  if (numeric_p && success_p)
2277    {
2278      font->numeric[XLFD_POINT_SIZE] = xlfd_point_size (f, font);
2279      font->numeric[XLFD_RESY] = atoi (font->fields[XLFD_RESY]);
2280      font->numeric[XLFD_SLANT] = xlfd_numeric_slant (font);
2281      font->numeric[XLFD_WEIGHT] = xlfd_numeric_weight (font);
2282      font->numeric[XLFD_SWIDTH] = xlfd_numeric_swidth (font);
2283      font->numeric[XLFD_AVGWIDTH] = atoi (font->fields[XLFD_AVGWIDTH]);
2284    }
2285
2286  /* Initialize it to zero.  It will be overridden by font_list while
2287     trying alternate registries.  */
2288  font->registry_priority = 0;
2289
2290  return success_p;
2291}
2292
2293
2294/* Build an XLFD font name from font name fields in FONT.  Value is a
2295   pointer to the font name, which is allocated via xmalloc.  */
2296
2297static char *
2298build_font_name (font)
2299     struct font_name *font;
2300{
2301  int i;
2302  int size = 100;
2303  char *font_name = (char *) xmalloc (size);
2304  int total_length = 0;
2305
2306  for (i = 0; i < XLFD_LAST; ++i)
2307    {
2308      /* Add 1 because of the leading `-'.  */
2309      int len = strlen (font->fields[i]) + 1;
2310
2311      /* Reallocate font_name if necessary.  Add 1 for the final
2312         NUL-byte.  */
2313      if (total_length + len + 1 >= size)
2314	{
2315	  int new_size = max (2 * size, size + len + 1);
2316	  int sz = new_size * sizeof *font_name;
2317	  font_name = (char *) xrealloc (font_name, sz);
2318	  size = new_size;
2319	}
2320
2321      font_name[total_length] = '-';
2322      bcopy (font->fields[i], font_name + total_length + 1, len - 1);
2323      total_length += len;
2324    }
2325
2326  font_name[total_length] = 0;
2327  return font_name;
2328}
2329
2330
2331/* Free an array FONTS of N font_name structures.  This frees FONTS
2332   itself and all `name' fields in its elements.  */
2333
2334static INLINE void
2335free_font_names (fonts, n)
2336     struct font_name *fonts;
2337     int n;
2338{
2339  while (n)
2340    xfree (fonts[--n].name);
2341  xfree (fonts);
2342}
2343
2344
2345/* Sort vector FONTS of font_name structures which contains NFONTS
2346   elements using qsort and comparison function CMPFN.  F is the frame
2347   on which the fonts will be used.  The global variable font_frame
2348   is temporarily set to F to make it available in CMPFN.  */
2349
2350static INLINE void
2351sort_fonts (f, fonts, nfonts, cmpfn)
2352     struct frame *f;
2353     struct font_name *fonts;
2354     int nfonts;
2355     int (*cmpfn) P_ ((const void *, const void *));
2356{
2357  font_frame = f;
2358  qsort (fonts, nfonts, sizeof *fonts, cmpfn);
2359  font_frame = NULL;
2360}
2361
2362
2363/* Get fonts matching PATTERN on frame F.  If F is null, use the first
2364   display in x_display_list.  FONTS is a pointer to a vector of
2365   NFONTS font_name structures.  TRY_ALTERNATIVES_P non-zero means try
2366   alternative patterns from Valternate_fontname_alist if no fonts are
2367   found matching PATTERN.
2368
2369   For all fonts found, set FONTS[i].name to the name of the font,
2370   allocated via xmalloc, and split font names into fields.  Ignore
2371   fonts that we can't parse.  Value is the number of fonts found.  */
2372
2373static int
2374x_face_list_fonts (f, pattern, fonts, nfonts, try_alternatives_p)
2375     struct frame *f;
2376     char *pattern;
2377     struct font_name *fonts;
2378     int nfonts, try_alternatives_p;
2379{
2380  int n, nignored;
2381
2382  /* NTEMACS_TODO : currently this uses w32_list_fonts, but it may be
2383     better to do it the other way around. */
2384  Lisp_Object lfonts;
2385  Lisp_Object lpattern, tem;
2386
2387  lpattern = build_string (pattern);
2388
2389  /* Get the list of fonts matching PATTERN.  */
2390#ifdef WINDOWSNT
2391  BLOCK_INPUT;
2392  lfonts = w32_list_fonts (f, lpattern, 0, nfonts);
2393  UNBLOCK_INPUT;
2394#else
2395  lfonts = x_list_fonts (f, lpattern, -1, nfonts);
2396#endif
2397
2398  /* Make a copy of the font names we got from X, and
2399     split them into fields.  */
2400  n = nignored = 0;
2401  for (tem = lfonts; CONSP (tem) && n < nfonts; tem = XCDR (tem))
2402    {
2403      Lisp_Object elt, tail;
2404      char *name = XSTRING (XCAR (tem))->data;
2405
2406      /* Ignore fonts matching a pattern from face-ignored-fonts.  */
2407      for (tail = Vface_ignored_fonts; CONSP (tail); tail = XCDR (tail))
2408	{
2409	  elt = XCAR (tail);
2410	  if (STRINGP (elt)
2411	      && fast_c_string_match_ignore_case (elt, name) >= 0)
2412	    break;
2413	}
2414      if (!NILP (tail))
2415	{
2416	  ++nignored;
2417	  continue;
2418	}
2419
2420      /* Make a copy of the font name.  */
2421      fonts[n].name = xstrdup (name);
2422
2423      if (split_font_name (f, fonts + n, 1))
2424	{
2425	  if (font_scalable_p (fonts + n)
2426	      && !may_use_scalable_font_p (name))
2427	    {
2428	      ++nignored;
2429	      xfree (fonts[n].name);
2430	    }
2431	  else
2432	    ++n;
2433	}
2434      else
2435	xfree (fonts[n].name);
2436    }
2437
2438  /* If no fonts found, try patterns from Valternate_fontname_alist.  */
2439  if (n == 0 && try_alternatives_p)
2440    {
2441      Lisp_Object list = Valternate_fontname_alist;
2442
2443      while (CONSP (list))
2444	{
2445	  Lisp_Object entry = XCAR (list);
2446	  if (CONSP (entry)
2447	      && STRINGP (XCAR (entry))
2448	      && strcmp (XSTRING (XCAR (entry))->data, pattern) == 0)
2449	    break;
2450	  list = XCDR (list);
2451	}
2452
2453      if (CONSP (list))
2454	{
2455	  Lisp_Object patterns = XCAR (list);
2456	  Lisp_Object name;
2457
2458	  while (CONSP (patterns)
2459		 /* If list is screwed up, give up.  */
2460		 && (name = XCAR (patterns),
2461		     STRINGP (name))
2462		 /* Ignore patterns equal to PATTERN because we tried that
2463		    already with no success.  */
2464		 && (strcmp (XSTRING (name)->data, pattern) == 0
2465		     || (n = x_face_list_fonts (f, XSTRING (name)->data,
2466						fonts, nfonts, 0),
2467			 n == 0)))
2468	    patterns = XCDR (patterns);
2469	}
2470    }
2471
2472  return n;
2473}
2474
2475
2476/* Determine fonts matching PATTERN on frame F.  Sort resulting fonts
2477   using comparison function CMPFN.  Value is the number of fonts
2478   found.  If value is non-zero, *FONTS is set to a vector of
2479   font_name structures allocated from the heap containing matching
2480   fonts.  Each element of *FONTS contains a name member that is also
2481   allocated from the heap.  Font names in these structures are split
2482   into fields.  Use free_font_names to free such an array.  */
2483
2484static int
2485sorted_font_list (f, pattern, cmpfn, fonts)
2486     struct frame *f;
2487     char *pattern;
2488     int (*cmpfn) P_ ((const void *, const void *));
2489     struct font_name **fonts;
2490{
2491  int nfonts;
2492
2493  /* Get the list of fonts matching pattern.  100 should suffice.  */
2494  nfonts = DEFAULT_FONT_LIST_LIMIT;
2495  if (INTEGERP (Vfont_list_limit) && XINT (Vfont_list_limit) > 0)
2496    nfonts = XFASTINT (Vfont_list_limit);
2497
2498  *fonts = (struct font_name *) xmalloc (nfonts * sizeof **fonts);
2499  nfonts = x_face_list_fonts (f, pattern, *fonts, nfonts, 1);
2500
2501  /* Sort the resulting array and return it in *FONTS.  If no
2502     fonts were found, make sure to set *FONTS to null.  */
2503  if (nfonts)
2504    sort_fonts (f, *fonts, nfonts, cmpfn);
2505  else
2506    {
2507      xfree (*fonts);
2508      *fonts = NULL;
2509    }
2510
2511  return nfonts;
2512}
2513
2514
2515/* Compare two font_name structures *A and *B.  Value is analogous to
2516   strcmp.  Sort order is given by the global variable
2517   font_sort_order.  Font names are sorted so that, everything else
2518   being equal, fonts with a resolution closer to that of the frame on
2519   which they are used are listed first.  The global variable
2520   font_frame is the frame on which we operate.  */
2521
2522static int
2523cmp_font_names (a, b)
2524     const void *a, *b;
2525{
2526  struct font_name *x = (struct font_name *) a;
2527  struct font_name *y = (struct font_name *) b;
2528  int cmp;
2529
2530  /* All strings have been converted to lower-case by split_font_name,
2531     so we can use strcmp here.  */
2532  cmp = strcmp (x->fields[XLFD_FAMILY], y->fields[XLFD_FAMILY]);
2533  if (cmp == 0)
2534    {
2535      int i;
2536
2537      for (i = 0; i < DIM (font_sort_order) && cmp == 0; ++i)
2538	{
2539	  int j = font_sort_order[i];
2540	  cmp = x->numeric[j] - y->numeric[j];
2541	}
2542
2543      if (cmp == 0)
2544	{
2545	  /* Everything else being equal, we prefer fonts with an
2546	     y-resolution closer to that of the frame.  */
2547	  int resy = FRAME_X_DISPLAY_INFO (font_frame)->resy;
2548	  int x_resy = x->numeric[XLFD_RESY];
2549	  int y_resy = y->numeric[XLFD_RESY];
2550	  cmp = abs (resy - x_resy) - abs (resy - y_resy);
2551	}
2552    }
2553
2554  return cmp;
2555}
2556
2557
2558/* Get a sorted list of fonts of family FAMILY on frame F.  If PATTERN
2559   is non-nil list fonts matching that pattern.  Otherwise, if
2560   REGISTRY is non-nil return only fonts with that registry, otherwise
2561   return fonts of any registry.  Set *FONTS to a vector of font_name
2562   structures allocated from the heap containing the fonts found.
2563   Value is the number of fonts found.  */
2564
2565static int
2566font_list_1 (f, pattern, family, registry, fonts)
2567     struct frame *f;
2568     Lisp_Object pattern, family, registry;
2569     struct font_name **fonts;
2570{
2571  char *pattern_str, *family_str, *registry_str;
2572
2573  if (NILP (pattern))
2574    {
2575      family_str = (NILP (family) ? "*" : (char *) XSTRING (family)->data);
2576      registry_str = (NILP (registry) ? "*" : (char *) XSTRING (registry)->data);
2577
2578      pattern_str = (char *) alloca (strlen (family_str)
2579				     + strlen (registry_str)
2580				     + 10);
2581      strcpy (pattern_str, index (family_str, '-') ? "-" : "-*-");
2582      strcat (pattern_str, family_str);
2583      strcat (pattern_str, "-*-");
2584      strcat (pattern_str, registry_str);
2585      if (!index (registry_str, '-'))
2586	{
2587	  if (registry_str[strlen (registry_str) - 1] == '*')
2588	    strcat (pattern_str, "-*");
2589	  else
2590	    strcat (pattern_str, "*-*");
2591	}
2592    }
2593  else
2594    pattern_str = (char *) XSTRING (pattern)->data;
2595
2596  return sorted_font_list (f, pattern_str, cmp_font_names, fonts);
2597}
2598
2599
2600/* Concatenate font list FONTS1 and FONTS2.  FONTS1 and FONTS2
2601   contains NFONTS1 fonts and NFONTS2 fonts respectively.  Return a
2602   pointer to a newly allocated font list.  FONTS1 and FONTS2 are
2603   freed.  */
2604
2605static struct font_name *
2606concat_font_list (fonts1, nfonts1, fonts2, nfonts2)
2607     struct font_name *fonts1, *fonts2;
2608     int nfonts1, nfonts2;
2609{
2610  int new_nfonts = nfonts1 + nfonts2;
2611  struct font_name *new_fonts;
2612
2613  new_fonts = (struct font_name *) xmalloc (sizeof *new_fonts * new_nfonts);
2614  bcopy (fonts1, new_fonts, sizeof *new_fonts * nfonts1);
2615  bcopy (fonts2, new_fonts + nfonts1, sizeof *new_fonts * nfonts2);
2616  xfree (fonts1);
2617  xfree (fonts2);
2618  return new_fonts;
2619}
2620
2621
2622/* Get a sorted list of fonts of family FAMILY on frame F.
2623
2624   If PATTERN is non-nil list fonts matching that pattern.
2625
2626   If REGISTRY is non-nil, return fonts with that registry and the
2627   alternative registries from Vface_alternative_font_registry_alist.
2628
2629   If REGISTRY is nil return fonts of any registry.
2630
2631   Set *FONTS to a vector of font_name structures allocated from the
2632   heap containing the fonts found.  Value is the number of fonts
2633   found.  */
2634
2635static int
2636font_list (f, pattern, family, registry, fonts)
2637     struct frame *f;
2638     Lisp_Object pattern, family, registry;
2639     struct font_name **fonts;
2640{
2641  int nfonts = font_list_1 (f, pattern, family, registry, fonts);
2642
2643  if (!NILP (registry)
2644      && CONSP (Vface_alternative_font_registry_alist))
2645    {
2646      Lisp_Object alter;
2647
2648      alter = Fassoc (registry, Vface_alternative_font_registry_alist);
2649      if (CONSP (alter))
2650	{
2651	  int reg_prio, i;
2652
2653	  for (alter = XCDR (alter), reg_prio = 1;
2654	       CONSP (alter);
2655	       alter = XCDR (alter), reg_prio++)
2656	    if (STRINGP (XCAR (alter)))
2657	      {
2658		int nfonts2;
2659		struct font_name *fonts2;
2660
2661		nfonts2 = font_list_1 (f, pattern, family, XCAR (alter),
2662				       &fonts2);
2663		for (i = 0; i < nfonts2; i++)
2664		  fonts2[i].registry_priority = reg_prio;
2665		*fonts = (nfonts > 0
2666			  ? concat_font_list (*fonts, nfonts, fonts2, nfonts2)
2667			  : fonts2);
2668		nfonts += nfonts2;
2669	      }
2670	}
2671    }
2672
2673  return nfonts;
2674}
2675
2676
2677/* Remove elements from LIST whose cars are `equal'.  Called from
2678   x-family-fonts and x-font-family-list to remove duplicate font
2679   entries.  */
2680
2681static void
2682remove_duplicates (list)
2683     Lisp_Object list;
2684{
2685  Lisp_Object tail = list;
2686
2687  while (!NILP (tail) && !NILP (XCDR (tail)))
2688    {
2689      Lisp_Object next = XCDR (tail);
2690      if (!NILP (Fequal (XCAR (next), XCAR (tail))))
2691	XCDR (tail) = XCDR (next);
2692      else
2693	tail = XCDR (tail);
2694    }
2695}
2696
2697
2698DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0,
2699  "Return a list of available fonts of family FAMILY on FRAME.\n\
2700If FAMILY is omitted or nil, list all families.\n\
2701Otherwise, FAMILY must be a string, possibly containing wildcards\n\
2702`?' and `*'.\n\
2703If FRAME is omitted or nil, use the selected frame.\n\
2704Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT\n\
2705SLANT FIXED-P FULL REGISTRY-AND-ENCODING].\n\
2706FAMILY is the font family name.  POINT-SIZE is the size of the\n\
2707font in 1/10 pt.  WIDTH, WEIGHT, and SLANT are symbols describing the\n\
2708width, weight and slant of the font.  These symbols are the same as for\n\
2709face attributes.  FIXED-P is non-nil if the font is fixed-pitch.\n\
2710FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string\n\
2711giving the registry and encoding of the font.\n\
2712The result list is sorted according to the current setting of\n\
2713the face font sort order.")
2714  (family, frame)
2715     Lisp_Object family, frame;
2716{
2717  struct frame *f = check_x_frame (frame);
2718  struct font_name *fonts;
2719  int i, nfonts;
2720  Lisp_Object result;
2721  struct gcpro gcpro1;
2722
2723  if (!NILP (family))
2724    CHECK_STRING (family, 1);
2725
2726  result = Qnil;
2727  GCPRO1 (result);
2728  nfonts = font_list (f, Qnil, family, Qnil, &fonts);
2729  for (i = nfonts - 1; i >= 0; --i)
2730    {
2731      Lisp_Object v = Fmake_vector (make_number (8), Qnil);
2732      char *tem;
2733
2734      ASET (v, 0, build_string (fonts[i].fields[XLFD_FAMILY]));
2735      ASET (v, 1, xlfd_symbolic_swidth (fonts + i));
2736      ASET (v, 2, make_number (xlfd_point_size (f, fonts + i)));
2737      ASET (v, 3, xlfd_symbolic_weight (fonts + i));
2738      ASET (v, 4, xlfd_symbolic_slant (fonts + i));
2739      ASET (v, 5, xlfd_fixed_p (fonts + i) ? Qt : Qnil);
2740      tem = build_font_name (fonts + i);
2741      ASET (v, 6, build_string (tem));
2742      sprintf (tem, "%s-%s", fonts[i].fields[XLFD_REGISTRY],
2743	       fonts[i].fields[XLFD_ENCODING]);
2744      ASET (v, 7, build_string (tem));
2745      xfree (tem);
2746
2747      result = Fcons (v, result);
2748    }
2749
2750  remove_duplicates (result);
2751  free_font_names (fonts, nfonts);
2752  UNGCPRO;
2753  return result;
2754}
2755
2756
2757DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
2758       0, 1, 0,
2759  "Return a list of available font families on FRAME.\n\
2760If FRAME is omitted or nil, use the selected frame.\n\
2761Value is a list of conses (FAMILY . FIXED-P) where FAMILY\n\
2762is a font family, and FIXED-P is non-nil if fonts of that family\n\
2763are fixed-pitch.")
2764  (frame)
2765     Lisp_Object frame;
2766{
2767  struct frame *f = check_x_frame (frame);
2768  int nfonts, i;
2769  struct font_name *fonts;
2770  Lisp_Object result;
2771  struct gcpro gcpro1;
2772  int count = specpdl_ptr - specpdl;
2773  int limit;
2774
2775  /* Let's consider all fonts.  Increase the limit for matching
2776     fonts until we have them all.  */
2777  for (limit = 500;;)
2778    {
2779      specbind (intern ("font-list-limit"), make_number (limit));
2780      nfonts = font_list (f, Qnil, Qnil, Qnil, &fonts);
2781
2782      if (nfonts == limit)
2783	{
2784	  free_font_names (fonts, nfonts);
2785	  limit *= 2;
2786	}
2787      else
2788	break;
2789    }
2790
2791  result = Qnil;
2792  GCPRO1 (result);
2793  for (i = nfonts - 1; i >= 0; --i)
2794    result = Fcons (Fcons (build_string (fonts[i].fields[XLFD_FAMILY]),
2795			   xlfd_fixed_p (fonts + i) ? Qt : Qnil),
2796		    result);
2797
2798  remove_duplicates (result);
2799  free_font_names (fonts, nfonts);
2800  UNGCPRO;
2801  return unbind_to (count, result);
2802}
2803
2804
2805DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
2806  "Return a list of the names of available fonts matching PATTERN.\n\
2807If optional arguments FACE and FRAME are specified, return only fonts\n\
2808the same size as FACE on FRAME.\n\
2809PATTERN is a string, perhaps with wildcard characters;\n\
2810  the * character matches any substring, and\n\
2811  the ? character matches any single character.\n\
2812  PATTERN is case-insensitive.\n\
2813FACE is a face name--a symbol.\n\
2814\n\
2815The return value is a list of strings, suitable as arguments to\n\
2816set-face-font.\n\
2817\n\
2818Fonts Emacs can't use may or may not be excluded\n\
2819even if they match PATTERN and FACE.\n\
2820The optional fourth argument MAXIMUM sets a limit on how many\n\
2821fonts to match.  The first MAXIMUM fonts are reported.\n\
2822The optional fifth argument WIDTH, if specified, is a number of columns\n\
2823occupied by a character of a font.  In that case, return only fonts\n\
2824the WIDTH times as wide as FACE on FRAME.")
2825  (pattern, face, frame, maximum, width)
2826    Lisp_Object pattern, face, frame, maximum, width;
2827{
2828  struct frame *f;
2829  int size;
2830  int maxnames;
2831
2832  check_x ();
2833  CHECK_STRING (pattern, 0);
2834
2835  if (NILP (maximum))
2836    maxnames = 2000;
2837  else
2838    {
2839      CHECK_NATNUM (maximum, 0);
2840      maxnames = XINT (maximum);
2841    }
2842
2843  if (!NILP (width))
2844    CHECK_NUMBER (width, 4);
2845
2846  /* We can't simply call check_x_frame because this function may be
2847     called before any frame is created.  */
2848  f = frame_or_selected_frame (frame, 2);
2849  if (!FRAME_WINDOW_P (f))
2850    {
2851      /* Perhaps we have not yet created any frame.  */
2852      f = NULL;
2853      face = Qnil;
2854    }
2855
2856  /* Determine the width standard for comparison with the fonts we find.  */
2857
2858  if (NILP (face))
2859    size = 0;
2860  else
2861    {
2862      /* This is of limited utility since it works with character
2863	 widths.  Keep it for compatibility.  --gerd.  */
2864      int face_id = lookup_named_face (f, face, 0);
2865      struct face *face = (face_id < 0
2866			   ? NULL
2867			   : FACE_FROM_ID (f, face_id));
2868
2869      if (face && face->font)
2870	size = FONT_WIDTH (face->font);
2871      else
2872	size = FONT_WIDTH (FRAME_FONT (f));
2873
2874      if (!NILP (width))
2875	size *= XINT (width);
2876    }
2877
2878  {
2879    Lisp_Object args[2];
2880
2881    args[0] = x_list_fonts (f, pattern, size, maxnames);
2882    if (f == NULL)
2883      /* We don't have to check fontsets.  */
2884      return args[0];
2885    args[1] = list_fontsets (f, pattern, size);
2886    return Fnconc (2, args);
2887  }
2888}
2889
2890#endif /* HAVE_WINDOW_SYSTEM */
2891
2892
2893
2894/***********************************************************************
2895			      Lisp Faces
2896 ***********************************************************************/
2897
2898/* Access face attributes of face LFACE, a Lisp vector.  */
2899
2900#define LFACE_FAMILY(LFACE)	    AREF ((LFACE), LFACE_FAMILY_INDEX)
2901#define LFACE_HEIGHT(LFACE)	    AREF ((LFACE), LFACE_HEIGHT_INDEX)
2902#define LFACE_WEIGHT(LFACE)	    AREF ((LFACE), LFACE_WEIGHT_INDEX)
2903#define LFACE_SLANT(LFACE)	    AREF ((LFACE), LFACE_SLANT_INDEX)
2904#define LFACE_UNDERLINE(LFACE)      AREF ((LFACE), LFACE_UNDERLINE_INDEX)
2905#define LFACE_INVERSE(LFACE)	    AREF ((LFACE), LFACE_INVERSE_INDEX)
2906#define LFACE_FOREGROUND(LFACE)     AREF ((LFACE), LFACE_FOREGROUND_INDEX)
2907#define LFACE_BACKGROUND(LFACE)     AREF ((LFACE), LFACE_BACKGROUND_INDEX)
2908#define LFACE_STIPPLE(LFACE)	    AREF ((LFACE), LFACE_STIPPLE_INDEX)
2909#define LFACE_SWIDTH(LFACE)	    AREF ((LFACE), LFACE_SWIDTH_INDEX)
2910#define LFACE_OVERLINE(LFACE)	    AREF ((LFACE), LFACE_OVERLINE_INDEX)
2911#define LFACE_STRIKE_THROUGH(LFACE) AREF ((LFACE), LFACE_STRIKE_THROUGH_INDEX)
2912#define LFACE_BOX(LFACE)	    AREF ((LFACE), LFACE_BOX_INDEX)
2913#define LFACE_FONT(LFACE)	    AREF ((LFACE), LFACE_FONT_INDEX)
2914#define LFACE_INHERIT(LFACE)	    AREF ((LFACE), LFACE_INHERIT_INDEX)
2915#define LFACE_AVGWIDTH(LFACE)	    AREF ((LFACE), LFACE_AVGWIDTH_INDEX)
2916
2917/* Non-zero if LFACE is a Lisp face.  A Lisp face is a vector of size
2918   LFACE_VECTOR_SIZE which has the symbol `face' in slot 0.  */
2919
2920#define LFACEP(LFACE)					\
2921     (VECTORP (LFACE)					\
2922      && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE	\
2923      && EQ (AREF (LFACE, 0), Qface))
2924
2925
2926#if GLYPH_DEBUG
2927
2928/* Check consistency of Lisp face attribute vector ATTRS.  */
2929
2930static void
2931check_lface_attrs (attrs)
2932     Lisp_Object *attrs;
2933{
2934  xassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
2935	   || STRINGP (attrs[LFACE_FAMILY_INDEX]));
2936  xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
2937	   || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
2938  xassert (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX])
2939	   || INTEGERP (attrs[LFACE_AVGWIDTH_INDEX]));
2940  xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
2941	   || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
2942	   || FLOATP (attrs[LFACE_HEIGHT_INDEX])
2943	   || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX]));
2944  xassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
2945	   || SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
2946  xassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
2947	   || SYMBOLP (attrs[LFACE_SLANT_INDEX]));
2948  xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
2949	   || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
2950	   || STRINGP (attrs[LFACE_UNDERLINE_INDEX]));
2951  xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
2952	   || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
2953	   || STRINGP (attrs[LFACE_OVERLINE_INDEX]));
2954  xassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
2955	   || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
2956	   || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
2957  xassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
2958	   || SYMBOLP (attrs[LFACE_BOX_INDEX])
2959	   || STRINGP (attrs[LFACE_BOX_INDEX])
2960	   || INTEGERP (attrs[LFACE_BOX_INDEX])
2961	   || CONSP (attrs[LFACE_BOX_INDEX]));
2962  xassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
2963	   || SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
2964  xassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
2965	   || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
2966  xassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
2967	   || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
2968  xassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX])
2969	   || NILP (attrs[LFACE_INHERIT_INDEX])
2970	   || SYMBOLP (attrs[LFACE_INHERIT_INDEX])
2971	   || CONSP (attrs[LFACE_INHERIT_INDEX]));
2972#ifdef HAVE_WINDOW_SYSTEM
2973  xassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
2974	   || SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
2975	   || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
2976  xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
2977	   || NILP (attrs[LFACE_FONT_INDEX])
2978	   || STRINGP (attrs[LFACE_FONT_INDEX]));
2979#endif
2980}
2981
2982
2983/* Check consistency of attributes of Lisp face LFACE (a Lisp vector).  */
2984
2985static void
2986check_lface (lface)
2987     Lisp_Object lface;
2988{
2989  if (!NILP (lface))
2990    {
2991      xassert (LFACEP (lface));
2992      check_lface_attrs (XVECTOR (lface)->contents);
2993    }
2994}
2995
2996#else /* GLYPH_DEBUG == 0 */
2997
2998#define check_lface_attrs(attrs)	(void) 0
2999#define check_lface(lface)		(void) 0
3000
3001#endif /* GLYPH_DEBUG == 0 */
3002
3003
3004/* Resolve face name FACE_NAME.  If FACE_NAME is a string, intern it
3005   to make it a symvol.  If FACE_NAME is an alias for another face,
3006   return that face's name.  */
3007
3008static Lisp_Object
3009resolve_face_name (face_name)
3010     Lisp_Object face_name;
3011{
3012  Lisp_Object aliased;
3013
3014  if (STRINGP (face_name))
3015    face_name = intern (XSTRING (face_name)->data);
3016
3017  while (SYMBOLP (face_name))
3018    {
3019      aliased = Fget (face_name, Qface_alias);
3020      if (NILP (aliased))
3021	break;
3022      else
3023	face_name = aliased;
3024    }
3025
3026  return face_name;
3027}
3028
3029
3030/* Return the face definition of FACE_NAME on frame F.  F null means
3031   return the definition for new frames.  FACE_NAME may be a string or
3032   a symbol (apparently Emacs 20.2 allowed strings as face names in
3033   face text properties; Ediff uses that).  If FACE_NAME is an alias
3034   for another face, return that face's definition.  If SIGNAL_P is
3035   non-zero, signal an error if FACE_NAME is not a valid face name.
3036   If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
3037   name.  */
3038
3039static INLINE Lisp_Object
3040lface_from_face_name (f, face_name, signal_p)
3041     struct frame *f;
3042     Lisp_Object face_name;
3043     int signal_p;
3044{
3045  Lisp_Object lface;
3046
3047  face_name = resolve_face_name (face_name);
3048
3049  if (f)
3050    lface = assq_no_quit (face_name, f->face_alist);
3051  else
3052    lface = assq_no_quit (face_name, Vface_new_frame_defaults);
3053
3054  if (CONSP (lface))
3055    lface = XCDR (lface);
3056  else if (signal_p)
3057    signal_error ("Invalid face", face_name);
3058
3059  check_lface (lface);
3060  return lface;
3061}
3062
3063
3064/* Get face attributes of face FACE_NAME from frame-local faces on
3065   frame F.  Store the resulting attributes in ATTRS which must point
3066   to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE.  If SIGNAL_P
3067   is non-zero, signal an error if FACE_NAME does not name a face.
3068   Otherwise, value is zero if FACE_NAME is not a face.  */
3069
3070static INLINE int
3071get_lface_attributes (f, face_name, attrs, signal_p)
3072     struct frame *f;
3073     Lisp_Object face_name;
3074     Lisp_Object *attrs;
3075     int signal_p;
3076{
3077  Lisp_Object lface;
3078  int success_p;
3079
3080  lface = lface_from_face_name (f, face_name, signal_p);
3081  if (!NILP (lface))
3082    {
3083      bcopy (XVECTOR (lface)->contents, attrs,
3084	     LFACE_VECTOR_SIZE * sizeof *attrs);
3085      success_p = 1;
3086    }
3087  else
3088    success_p = 0;
3089
3090  return success_p;
3091}
3092
3093
3094/* Non-zero if all attributes in face attribute vector ATTRS are
3095   specified, i.e. are non-nil.  */
3096
3097static int
3098lface_fully_specified_p (attrs)
3099     Lisp_Object *attrs;
3100{
3101  int i;
3102
3103  for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3104    if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX
3105	&& i != LFACE_AVGWIDTH_INDEX)
3106      if (UNSPECIFIEDP (attrs[i]))
3107        break;
3108
3109  return i == LFACE_VECTOR_SIZE;
3110}
3111
3112#ifdef HAVE_WINDOW_SYSTEM
3113
3114/* Set font-related attributes of Lisp face LFACE from the fullname of
3115   the font opened by FONTNAME.  If FORCE_P is zero, set only
3116   unspecified attributes of LFACE.  The exception is `font'
3117   attribute.  It is set to FONTNAME as is regardless of FORCE_P.
3118
3119   If FONTNAME is not available on frame F,
3120	return 0 if MAY_FAIL_P is non-zero, otherwise abort.
3121   If the fullname is not in a valid XLFD format,
3122   	return 0 if MAY_FAIL_P is non-zero, otherwise set normal values
3123	in LFACE and return 1.
3124   Otherwise, return 1.  */
3125
3126static int
3127set_lface_from_font_name (f, lface, fontname, force_p, may_fail_p)
3128     struct frame *f;
3129     Lisp_Object lface;
3130     Lisp_Object fontname;
3131     int force_p, may_fail_p;
3132{
3133  struct font_name font;
3134  char *buffer;
3135  int pt;
3136  int have_xlfd_p;
3137  int fontset;
3138  char *font_name = XSTRING (fontname)->data;
3139  struct font_info *font_info;
3140
3141  /* If FONTNAME is actually a fontset name, get ASCII font name of it.  */
3142  fontset = fs_query_fontset (fontname, 0);
3143  if (fontset >= 0)
3144    font_name = XSTRING (fontset_ascii (fontset))->data;
3145
3146  /* Check if FONT_NAME is surely available on the system.  Usually
3147     FONT_NAME is already cached for the frame F and FS_LOAD_FONT
3148     returns quickly.  But, even if FONT_NAME is not yet cached,
3149     caching it now is not futail because we anyway load the font
3150     later.  */
3151  BLOCK_INPUT;
3152  font_info = FS_LOAD_FONT (f, 0, font_name, -1);
3153  UNBLOCK_INPUT;
3154
3155  if (!font_info)
3156    {
3157      if (may_fail_p)
3158	return 0;
3159      abort ();
3160    }
3161
3162  font.name = STRDUPA (font_info->full_name);
3163  have_xlfd_p = split_font_name (f, &font, 1);
3164
3165  /* Set attributes only if unspecified, otherwise face defaults for
3166     new frames would never take effect.  If we couldn't get a font
3167     name conforming to XLFD, set normal values.  */
3168
3169  if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
3170    {
3171      Lisp_Object val;
3172      if (have_xlfd_p)
3173	{
3174	  buffer = (char *) alloca (strlen (font.fields[XLFD_FAMILY])
3175				    + strlen (font.fields[XLFD_FOUNDRY])
3176				    + 2);
3177	  sprintf (buffer, "%s-%s", font.fields[XLFD_FOUNDRY],
3178		   font.fields[XLFD_FAMILY]);
3179	  val = build_string (buffer);
3180	}
3181      else
3182	val = build_string ("*");
3183      LFACE_FAMILY (lface) = val;
3184    }
3185
3186  if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
3187    {
3188      if (have_xlfd_p)
3189	pt = xlfd_point_size (f, &font);
3190      else
3191	pt = pixel_point_size (f, font_info->height * 10);
3192      xassert (pt > 0);
3193      LFACE_HEIGHT (lface) = make_number (pt);
3194    }
3195
3196  if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
3197    LFACE_SWIDTH (lface)
3198      = have_xlfd_p ? xlfd_symbolic_swidth (&font) : Qnormal;
3199
3200  if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface)))
3201    LFACE_AVGWIDTH (lface)
3202      = (have_xlfd_p
3203	 ? make_number (font.numeric[XLFD_AVGWIDTH])
3204	 : Qunspecified);
3205
3206  if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
3207    LFACE_WEIGHT (lface)
3208      = have_xlfd_p ? xlfd_symbolic_weight (&font) : Qnormal;
3209
3210  if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
3211    LFACE_SLANT (lface)
3212      = have_xlfd_p ? xlfd_symbolic_slant (&font) : Qnormal;
3213
3214  LFACE_FONT (lface) = fontname;
3215
3216  return 1;
3217}
3218
3219#endif /* HAVE_WINDOW_SYSTEM */
3220
3221
3222/* Merges the face height FROM with the face height TO, and returns the
3223   merged height.  If FROM is an invalid height, then INVALID is
3224   returned instead.  FROM may be a either an absolute face height or a
3225   `relative' height, and TO must be an absolute height.  The returned
3226   value is always an absolute height.  GCPRO is a lisp value that will
3227   be protected from garbage-collection if this function makes a call
3228   into lisp.  */
3229
3230Lisp_Object
3231merge_face_heights (from, to, invalid, gcpro)
3232     Lisp_Object from, to, invalid, gcpro;
3233{
3234  int result = 0;
3235
3236  if (INTEGERP (from))
3237    result = XINT (from);
3238  else if (NUMBERP (from))
3239    result = XFLOATINT (from) * XINT (to);
3240#if 0 /* Probably not so useful.  */
3241  else if (CONSP (from) && CONSP (XCDR (from)))
3242    {
3243      if (EQ (XCAR(from), Qplus) || EQ (XCAR(from), Qminus))
3244	{
3245	  if (INTEGERP (XCAR (XCDR (from))))
3246	    {
3247	      int inc = XINT (XCAR (XCDR (from)));
3248	      if (EQ (XCAR (from), Qminus))
3249		inc = -inc;
3250
3251	      result = XFASTINT (to);
3252	      if (result + inc > 0)
3253		/* Note that `underflows' don't mean FROM is invalid, so
3254		   we just pin the result at TO if it would otherwise be
3255		   negative or 0.  */
3256		result += inc;
3257	    }
3258	}
3259    }
3260#endif
3261  else if (FUNCTIONP (from))
3262    {
3263      /* Call function with current height as argument.
3264	 From is the new height.  */
3265      Lisp_Object args[2], height;
3266      struct gcpro gcpro1;
3267
3268      GCPRO1 (gcpro);
3269
3270      args[0] = from;
3271      args[1] = to;
3272      height = safe_call (2, args);
3273
3274      UNGCPRO;
3275
3276      if (NUMBERP (height))
3277	result = XFLOATINT (height);
3278    }
3279
3280  if (result > 0)
3281    return make_number (result);
3282  else
3283    return invalid;
3284}
3285
3286
3287/* Merge two Lisp face attribute vectors on frame F, FROM and TO, and
3288   store the resulting attributes in TO, which must be already be
3289   completely specified and contain only absolute attributes.  Every
3290   specified attribute of FROM overrides the corresponding attribute of
3291   TO; relative attributes in FROM are merged with the absolute value in
3292   TO and replace it.  CYCLE_CHECK is used internally to detect loops in
3293   face inheritance; it should be Qnil when called from other places.  */
3294
3295static INLINE void
3296merge_face_vectors (f, from, to, cycle_check)
3297     struct frame *f;
3298     Lisp_Object *from, *to;
3299     Lisp_Object cycle_check;
3300{
3301  int i;
3302
3303  /* If FROM inherits from some other faces, merge their attributes into
3304     TO before merging FROM's direct attributes.  Note that an :inherit
3305     attribute of `unspecified' is the same as one of nil; we never
3306     merge :inherit attributes, so nil is more correct, but lots of
3307     other code uses `unspecified' as a generic value for face attributes. */
3308  if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
3309      && !NILP (from[LFACE_INHERIT_INDEX]))
3310    merge_face_inheritance (f, from[LFACE_INHERIT_INDEX], to, cycle_check);
3311
3312  /* If TO specifies a :font attribute, and FROM specifies some
3313     font-related attribute, we need to clear TO's :font attribute
3314     (because it will be inconsistent with whatever FROM specifies, and
3315     FROM takes precedence).  */
3316  if (!NILP (to[LFACE_FONT_INDEX])
3317      && (!UNSPECIFIEDP (from[LFACE_FAMILY_INDEX])
3318	  || !UNSPECIFIEDP (from[LFACE_HEIGHT_INDEX])
3319	  || !UNSPECIFIEDP (from[LFACE_WEIGHT_INDEX])
3320	  || !UNSPECIFIEDP (from[LFACE_SLANT_INDEX])
3321	  || !UNSPECIFIEDP (from[LFACE_SWIDTH_INDEX])
3322	  || !UNSPECIFIEDP (from[LFACE_AVGWIDTH_INDEX])))
3323    to[LFACE_FONT_INDEX] = Qnil;
3324
3325  for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3326    if (!UNSPECIFIEDP (from[i]))
3327      if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
3328	to[i] = merge_face_heights (from[i], to[i], to[i], cycle_check);
3329      else
3330	to[i] = from[i];
3331
3332  /* TO is always an absolute face, which should inherit from nothing.
3333     We blindly copy the :inherit attribute above and fix it up here.  */
3334  to[LFACE_INHERIT_INDEX] = Qnil;
3335}
3336
3337
3338/* Checks the `cycle check' variable CHECK to see if it indicates that
3339   EL is part of a cycle; CHECK must be either Qnil or a value returned
3340   by an earlier use of CYCLE_CHECK.  SUSPICIOUS is the number of
3341   elements after which a cycle might be suspected; after that many
3342   elements, this macro begins consing in order to keep more precise
3343   track of elements.
3344
3345   Returns NIL if a cycle was detected, otherwise a new value for CHECK
3346   that includes EL.
3347
3348   CHECK is evaluated multiple times, EL and SUSPICIOUS 0 or 1 times, so
3349   the caller should make sure that's ok.  */
3350
3351#define CYCLE_CHECK(check, el, suspicious)	\
3352  (NILP (check)					\
3353   ? make_number (0)				\
3354   : (INTEGERP (check)				\
3355      ? (XFASTINT (check) < (suspicious)	\
3356	 ? make_number (XFASTINT (check) + 1)	\
3357	 : Fcons (el, Qnil))			\
3358      : (!NILP (Fmemq ((el), (check)))		\
3359	 ? Qnil					\
3360	 : Fcons ((el), (check)))))
3361
3362
3363/* Merge face attributes from the face on frame F whose name is
3364   INHERITS, into the vector of face attributes TO; INHERITS may also be
3365   a list of face names, in which case they are applied in order.
3366   CYCLE_CHECK is used to detect loops in face inheritance.
3367   Returns true if any of the inherited attributes are `font-related'.  */
3368
3369static void
3370merge_face_inheritance (f, inherit, to, cycle_check)
3371     struct frame *f;
3372     Lisp_Object inherit;
3373     Lisp_Object *to;
3374     Lisp_Object cycle_check;
3375{
3376  if (SYMBOLP (inherit) && !EQ (inherit, Qunspecified))
3377    /* Inherit from the named face INHERIT.  */
3378    {
3379      Lisp_Object lface;
3380
3381      /* Make sure we're not in an inheritance loop.  */
3382      cycle_check = CYCLE_CHECK (cycle_check, inherit, 15);
3383      if (NILP (cycle_check))
3384	/* Cycle detected, ignore any further inheritance.  */
3385	return;
3386
3387      lface = lface_from_face_name (f, inherit, 0);
3388      if (!NILP (lface))
3389	merge_face_vectors (f, XVECTOR (lface)->contents, to, cycle_check);
3390    }
3391  else if (CONSP (inherit))
3392    /* Handle a list of inherited faces by calling ourselves recursively
3393       on each element.  Note that we only do so for symbol elements, so
3394       it's not possible to infinitely recurse.  */
3395    {
3396      while (CONSP (inherit))
3397	{
3398	  if (SYMBOLP (XCAR (inherit)))
3399	    merge_face_inheritance (f, XCAR (inherit), to, cycle_check);
3400
3401	  /* Check for a circular inheritance list.  */
3402	  cycle_check = CYCLE_CHECK (cycle_check, inherit, 15);
3403	  if (NILP (cycle_check))
3404	    /* Cycle detected.  */
3405	    break;
3406
3407	  inherit = XCDR (inherit);
3408	}
3409    }
3410}
3411
3412
3413/* Given a Lisp face attribute vector TO and a Lisp object PROP that
3414   is a face property, determine the resulting face attributes on
3415   frame F, and store them in TO.  PROP may be a single face
3416   specification or a list of such specifications.  Each face
3417   specification can be
3418
3419   1. A symbol or string naming a Lisp face.
3420
3421   2. A property list of the form (KEYWORD VALUE ...) where each
3422   KEYWORD is a face attribute name, and value is an appropriate value
3423   for that attribute.
3424
3425   3. Conses or the form (FOREGROUND-COLOR . COLOR) or
3426   (BACKGROUND-COLOR . COLOR) where COLOR is a color name.  This is
3427   for compatibility with 20.2.
3428
3429   Face specifications earlier in lists take precedence over later
3430   specifications.  */
3431
3432static void
3433merge_face_vector_with_property (f, to, prop)
3434     struct frame *f;
3435     Lisp_Object *to;
3436     Lisp_Object prop;
3437{
3438  if (CONSP (prop))
3439    {
3440      Lisp_Object first = XCAR (prop);
3441
3442      if (EQ (first, Qforeground_color)
3443	  || EQ (first, Qbackground_color))
3444	{
3445	  /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
3446	     . COLOR).  COLOR must be a string.  */
3447	  Lisp_Object color_name = XCDR (prop);
3448	  Lisp_Object color = first;
3449
3450	  if (STRINGP (color_name))
3451	    {
3452	      if (EQ (color, Qforeground_color))
3453		to[LFACE_FOREGROUND_INDEX] = color_name;
3454	      else
3455		to[LFACE_BACKGROUND_INDEX] = color_name;
3456	    }
3457	  else
3458	    add_to_log ("Invalid face color", color_name, Qnil);
3459	}
3460      else if (SYMBOLP (first)
3461	       && *XSYMBOL (first)->name->data == ':')
3462	{
3463	  /* Assume this is the property list form.  */
3464	  while (CONSP (prop) && CONSP (XCDR (prop)))
3465	    {
3466	      Lisp_Object keyword = XCAR (prop);
3467	      Lisp_Object value = XCAR (XCDR (prop));
3468
3469	      if (EQ (keyword, QCfamily))
3470		{
3471		  if (STRINGP (value))
3472		    to[LFACE_FAMILY_INDEX] = value;
3473		  else
3474		    add_to_log ("Invalid face font family", value, Qnil);
3475		}
3476	      else if (EQ (keyword, QCheight))
3477		{
3478		  Lisp_Object new_height =
3479		    merge_face_heights (value, to[LFACE_HEIGHT_INDEX],
3480					Qnil, Qnil);
3481
3482		  if (NILP (new_height))
3483		    add_to_log ("Invalid face font height", value, Qnil);
3484		  else
3485		    to[LFACE_HEIGHT_INDEX] = new_height;
3486		}
3487	      else if (EQ (keyword, QCweight))
3488		{
3489		  if (SYMBOLP (value)
3490		      && face_numeric_weight (value) >= 0)
3491		    to[LFACE_WEIGHT_INDEX] = value;
3492		  else
3493		    add_to_log ("Invalid face weight", value, Qnil);
3494		}
3495	      else if (EQ (keyword, QCslant))
3496		{
3497		  if (SYMBOLP (value)
3498		      && face_numeric_slant (value) >= 0)
3499		    to[LFACE_SLANT_INDEX] = value;
3500		  else
3501		    add_to_log ("Invalid face slant", value, Qnil);
3502		}
3503	      else if (EQ (keyword, QCunderline))
3504		{
3505		  if (EQ (value, Qt)
3506		      || NILP (value)
3507		      || STRINGP (value))
3508		    to[LFACE_UNDERLINE_INDEX] = value;
3509		  else
3510		    add_to_log ("Invalid face underline", value, Qnil);
3511		}
3512	      else if (EQ (keyword, QCoverline))
3513		{
3514		  if (EQ (value, Qt)
3515		      || NILP (value)
3516		      || STRINGP (value))
3517		    to[LFACE_OVERLINE_INDEX] = value;
3518		  else
3519		    add_to_log ("Invalid face overline", value, Qnil);
3520		}
3521	      else if (EQ (keyword, QCstrike_through))
3522		{
3523		  if (EQ (value, Qt)
3524		      || NILP (value)
3525		      || STRINGP (value))
3526		    to[LFACE_STRIKE_THROUGH_INDEX] = value;
3527		  else
3528		    add_to_log ("Invalid face strike-through", value, Qnil);
3529		}
3530	      else if (EQ (keyword, QCbox))
3531		{
3532		  if (EQ (value, Qt))
3533		    value = make_number (1);
3534		  if (INTEGERP (value)
3535		      || STRINGP (value)
3536		      || CONSP (value)
3537		      || NILP (value))
3538		    to[LFACE_BOX_INDEX] = value;
3539		  else
3540		    add_to_log ("Invalid face box", value, Qnil);
3541		}
3542	      else if (EQ (keyword, QCinverse_video)
3543		       || EQ (keyword, QCreverse_video))
3544		{
3545		  if (EQ (value, Qt) || NILP (value))
3546		    to[LFACE_INVERSE_INDEX] = value;
3547		  else
3548		    add_to_log ("Invalid face inverse-video", value, Qnil);
3549		}
3550	      else if (EQ (keyword, QCforeground))
3551		{
3552		  if (STRINGP (value))
3553		    to[LFACE_FOREGROUND_INDEX] = value;
3554		  else
3555		    add_to_log ("Invalid face foreground", value, Qnil);
3556		}
3557	      else if (EQ (keyword, QCbackground))
3558		{
3559		  if (STRINGP (value))
3560		    to[LFACE_BACKGROUND_INDEX] = value;
3561		  else
3562		    add_to_log ("Invalid face background", value, Qnil);
3563		}
3564	      else if (EQ (keyword, QCstipple))
3565		{
3566#ifdef HAVE_X_WINDOWS
3567		  Lisp_Object pixmap_p = Fbitmap_spec_p (value);
3568		  if (!NILP (pixmap_p))
3569		    to[LFACE_STIPPLE_INDEX] = value;
3570		  else
3571		    add_to_log ("Invalid face stipple", value, Qnil);
3572#endif
3573		}
3574	      else if (EQ (keyword, QCwidth))
3575		{
3576		  if (SYMBOLP (value)
3577		      && face_numeric_swidth (value) >= 0)
3578		    to[LFACE_SWIDTH_INDEX] = value;
3579		  else
3580		    add_to_log ("Invalid face width", value, Qnil);
3581		}
3582	      else if (EQ (keyword, QCinherit))
3583		{
3584		  if (SYMBOLP (value))
3585		    to[LFACE_INHERIT_INDEX] = value;
3586		  else
3587		    {
3588		      Lisp_Object tail;
3589		      for (tail = value; CONSP (tail); tail = XCDR (tail))
3590			if (!SYMBOLP (XCAR (tail)))
3591			  break;
3592		      if (NILP (tail))
3593			to[LFACE_INHERIT_INDEX] = value;
3594		      else
3595			add_to_log ("Invalid face inherit", value, Qnil);
3596		    }
3597		}
3598	      else
3599		add_to_log ("Invalid attribute %s in face property",
3600			    keyword, Qnil);
3601
3602	      prop = XCDR (XCDR (prop));
3603	    }
3604	}
3605      else
3606	{
3607	  /* This is a list of face specs.  Specifications at the
3608	     beginning of the list take precedence over later
3609	     specifications, so we have to merge starting with the
3610	     last specification.  */
3611	  Lisp_Object next = XCDR (prop);
3612	  if (!NILP (next))
3613	    merge_face_vector_with_property (f, to, next);
3614	  merge_face_vector_with_property (f, to, first);
3615	}
3616    }
3617  else
3618    {
3619      /* PROP ought to be a face name.  */
3620      Lisp_Object lface = lface_from_face_name (f, prop, 0);
3621      if (NILP (lface))
3622	add_to_log ("Invalid face text property value: %s", prop, Qnil);
3623      else
3624	merge_face_vectors (f, XVECTOR (lface)->contents, to, Qnil);
3625    }
3626}
3627
3628
3629DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face,
3630       Sinternal_make_lisp_face, 1, 2, 0,
3631  "Make FACE, a symbol, a Lisp face with all attributes nil.\n\
3632If FACE was not known as a face before, create a new one.\n\
3633If optional argument FRAME is specified, make a frame-local face\n\
3634for that frame.  Otherwise operate on the global face definition.\n\
3635Value is a vector of face attributes.")
3636  (face, frame)
3637     Lisp_Object face, frame;
3638{
3639  Lisp_Object global_lface, lface;
3640  struct frame *f;
3641  int i;
3642
3643  CHECK_SYMBOL (face, 0);
3644  global_lface = lface_from_face_name (NULL, face, 0);
3645
3646  if (!NILP (frame))
3647    {
3648      CHECK_LIVE_FRAME (frame, 1);
3649      f = XFRAME (frame);
3650      lface = lface_from_face_name (f, face, 0);
3651    }
3652  else
3653    f = NULL, lface = Qnil;
3654
3655  /* Add a global definition if there is none.  */
3656  if (NILP (global_lface))
3657    {
3658      global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
3659				   Qunspecified);
3660      AREF (global_lface, 0) = Qface;
3661      Vface_new_frame_defaults = Fcons (Fcons (face, global_lface),
3662					Vface_new_frame_defaults);
3663
3664      /* Assign the new Lisp face a unique ID.  The mapping from Lisp
3665	 face id to Lisp face is given by the vector lface_id_to_name.
3666	 The mapping from Lisp face to Lisp face id is given by the
3667	 property `face' of the Lisp face name.  */
3668      if (next_lface_id == lface_id_to_name_size)
3669	{
3670	  int new_size = max (50, 2 * lface_id_to_name_size);
3671	  int sz = new_size * sizeof *lface_id_to_name;
3672	  lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz);
3673	  lface_id_to_name_size = new_size;
3674	}
3675
3676      lface_id_to_name[next_lface_id] = face;
3677      Fput (face, Qface, make_number (next_lface_id));
3678      ++next_lface_id;
3679    }
3680  else if (f == NULL)
3681    for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3682      AREF (global_lface, i) = Qunspecified;
3683
3684  /* Add a frame-local definition.  */
3685  if (f)
3686    {
3687      if (NILP (lface))
3688	{
3689	  lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
3690				Qunspecified);
3691	  AREF (lface, 0) = Qface;
3692	  f->face_alist = Fcons (Fcons (face, lface), f->face_alist);
3693	}
3694      else
3695	for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3696	  AREF (lface, i) = Qunspecified;
3697    }
3698  else
3699    lface = global_lface;
3700
3701  xassert (LFACEP (lface));
3702  check_lface (lface);
3703  return lface;
3704}
3705
3706
3707DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
3708       Sinternal_lisp_face_p, 1, 2, 0,
3709  "Return non-nil if FACE names a face.\n\
3710If optional second parameter FRAME is non-nil, check for the\n\
3711existence of a frame-local face with name FACE on that frame.\n\
3712Otherwise check for the existence of a global face.")
3713  (face, frame)
3714     Lisp_Object face, frame;
3715{
3716  Lisp_Object lface;
3717
3718  if (!NILP (frame))
3719    {
3720      CHECK_LIVE_FRAME (frame, 1);
3721      lface = lface_from_face_name (XFRAME (frame), face, 0);
3722    }
3723  else
3724    lface = lface_from_face_name (NULL, face, 0);
3725
3726  return lface;
3727}
3728
3729
3730DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
3731       Sinternal_copy_lisp_face, 4, 4, 0,
3732  "Copy face FROM to TO.\n\
3733If FRAME it t, copy the global face definition of FROM to the\n\
3734global face definition of TO.  Otherwise, copy the frame-local\n\
3735definition of FROM on FRAME to the frame-local definition of TO\n\
3736on NEW-FRAME, or FRAME if NEW-FRAME is nil.\n\
3737\n\
3738Value is TO.")
3739  (from, to, frame, new_frame)
3740     Lisp_Object from, to, frame, new_frame;
3741{
3742  Lisp_Object lface, copy;
3743
3744  CHECK_SYMBOL (from, 0);
3745  CHECK_SYMBOL (to, 1);
3746  if (NILP (new_frame))
3747    new_frame = frame;
3748
3749  if (EQ (frame, Qt))
3750    {
3751      /* Copy global definition of FROM.  We don't make copies of
3752	 strings etc. because 20.2 didn't do it either.  */
3753      lface = lface_from_face_name (NULL, from, 1);
3754      copy = Finternal_make_lisp_face (to, Qnil);
3755    }
3756  else
3757    {
3758      /* Copy frame-local definition of FROM.  */
3759      CHECK_LIVE_FRAME (frame, 2);
3760      CHECK_LIVE_FRAME (new_frame, 3);
3761      lface = lface_from_face_name (XFRAME (frame), from, 1);
3762      copy = Finternal_make_lisp_face (to, new_frame);
3763    }
3764
3765  bcopy (XVECTOR (lface)->contents, XVECTOR (copy)->contents,
3766	 LFACE_VECTOR_SIZE * sizeof (Lisp_Object));
3767
3768  return to;
3769}
3770
3771
3772DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
3773       Sinternal_set_lisp_face_attribute, 3, 4, 0,
3774  "Set attribute ATTR of FACE to VALUE.\n\
3775FRAME being a frame means change the face on that frame.\n\
3776FRAME nil means change the face of the selected frame.\n\
3777FRAME t means change the default for new frames.\n\
3778FRAME 0 means change the face on all frames, and change the default\n\
3779  for new frames.")
3780  (face, attr, value, frame)
3781     Lisp_Object face, attr, value, frame;
3782{
3783  Lisp_Object lface;
3784  Lisp_Object old_value = Qnil;
3785  /* Set 1 if ATTR is QCfont.  */
3786  int font_attr_p = 0;
3787  /* Set 1 if ATTR is one of font-related attributes other than QCfont.  */
3788  int font_related_attr_p = 0;
3789
3790  CHECK_SYMBOL (face, 0);
3791  CHECK_SYMBOL (attr, 1);
3792
3793  face = resolve_face_name (face);
3794
3795  /* If FRAME is 0, change face on all frames, and change the
3796     default for new frames.  */
3797  if (INTEGERP (frame) && XINT (frame) == 0)
3798    {
3799      Lisp_Object tail;
3800      Finternal_set_lisp_face_attribute (face, attr, value, Qt);
3801      FOR_EACH_FRAME (tail, frame)
3802	Finternal_set_lisp_face_attribute (face, attr, value, frame);
3803      return face;
3804    }
3805
3806  /* Set lface to the Lisp attribute vector of FACE.  */
3807  if (EQ (frame, Qt))
3808    lface = lface_from_face_name (NULL, face, 1);
3809  else
3810    {
3811      if (NILP (frame))
3812	frame = selected_frame;
3813
3814      CHECK_LIVE_FRAME (frame, 3);
3815      lface = lface_from_face_name (XFRAME (frame), face, 0);
3816
3817      /* If a frame-local face doesn't exist yet, create one.  */
3818      if (NILP (lface))
3819	lface = Finternal_make_lisp_face (face, frame);
3820    }
3821
3822  if (EQ (attr, QCfamily))
3823    {
3824      if (!UNSPECIFIEDP (value))
3825	{
3826	  CHECK_STRING (value, 3);
3827	  if (XSTRING (value)->size == 0)
3828	    signal_error ("Invalid face family", value);
3829	}
3830      old_value = LFACE_FAMILY (lface);
3831      LFACE_FAMILY (lface) = value;
3832      font_related_attr_p = 1;
3833    }
3834  else if (EQ (attr, QCheight))
3835    {
3836      if (!UNSPECIFIEDP (value))
3837	{
3838	  Lisp_Object test =
3839	    (EQ (face, Qdefault) ? value :
3840	     /* The default face must have an absolute size, otherwise, we do
3841		a test merge with a random height to see if VALUE's ok. */
3842	     merge_face_heights (value, make_number(10), Qnil, Qnil));
3843
3844	  if (!INTEGERP(test) || XINT(test) <= 0)
3845	    signal_error ("Invalid face height", value);
3846	}
3847
3848      old_value = LFACE_HEIGHT (lface);
3849      LFACE_HEIGHT (lface) = value;
3850      font_related_attr_p = 1;
3851    }
3852  else if (EQ (attr, QCweight))
3853    {
3854      if (!UNSPECIFIEDP (value))
3855	{
3856	  CHECK_SYMBOL (value, 3);
3857	  if (face_numeric_weight (value) < 0)
3858	    signal_error ("Invalid face weight", value);
3859	}
3860      old_value = LFACE_WEIGHT (lface);
3861      LFACE_WEIGHT (lface) = value;
3862      font_related_attr_p = 1;
3863    }
3864  else if (EQ (attr, QCslant))
3865    {
3866      if (!UNSPECIFIEDP (value))
3867	{
3868	  CHECK_SYMBOL (value, 3);
3869	  if (face_numeric_slant (value) < 0)
3870	    signal_error ("Invalid face slant", value);
3871	}
3872      old_value = LFACE_SLANT (lface);
3873      LFACE_SLANT (lface) = value;
3874      font_related_attr_p = 1;
3875    }
3876  else if (EQ (attr, QCunderline))
3877    {
3878      if (!UNSPECIFIEDP (value))
3879	if ((SYMBOLP (value)
3880	     && !EQ (value, Qt)
3881	     && !EQ (value, Qnil))
3882	    /* Underline color.  */
3883	    || (STRINGP (value)
3884		&& XSTRING (value)->size == 0))
3885	  signal_error ("Invalid face underline", value);
3886
3887      old_value = LFACE_UNDERLINE (lface);
3888      LFACE_UNDERLINE (lface) = value;
3889    }
3890  else if (EQ (attr, QCoverline))
3891    {
3892      if (!UNSPECIFIEDP (value))
3893	if ((SYMBOLP (value)
3894	     && !EQ (value, Qt)
3895	     && !EQ (value, Qnil))
3896	    /* Overline color.  */
3897	    || (STRINGP (value)
3898		&& XSTRING (value)->size == 0))
3899	  signal_error ("Invalid face overline", value);
3900
3901      old_value = LFACE_OVERLINE (lface);
3902      LFACE_OVERLINE (lface) = value;
3903    }
3904  else if (EQ (attr, QCstrike_through))
3905    {
3906      if (!UNSPECIFIEDP (value))
3907	if ((SYMBOLP (value)
3908	     && !EQ (value, Qt)
3909	     && !EQ (value, Qnil))
3910	    /* Strike-through color.  */
3911	    || (STRINGP (value)
3912		&& XSTRING (value)->size == 0))
3913	  signal_error ("Invalid face strike-through", value);
3914
3915      old_value = LFACE_STRIKE_THROUGH (lface);
3916      LFACE_STRIKE_THROUGH (lface) = value;
3917    }
3918  else if (EQ (attr, QCbox))
3919    {
3920      int valid_p;
3921
3922      /* Allow t meaning a simple box of width 1 in foreground color
3923         of the face.  */
3924      if (EQ (value, Qt))
3925	value = make_number (1);
3926
3927      if (UNSPECIFIEDP (value))
3928	valid_p = 1;
3929      else if (NILP (value))
3930	valid_p = 1;
3931      else if (INTEGERP (value))
3932	valid_p = XINT (value) != 0;
3933      else if (STRINGP (value))
3934	valid_p = XSTRING (value)->size > 0;
3935      else if (CONSP (value))
3936	{
3937	  Lisp_Object tem;
3938
3939	  tem = value;
3940	  while (CONSP (tem))
3941	    {
3942	      Lisp_Object k, v;
3943
3944	      k = XCAR (tem);
3945	      tem = XCDR (tem);
3946	      if (!CONSP (tem))
3947		break;
3948	      v = XCAR (tem);
3949	      tem = XCDR (tem);
3950
3951	      if (EQ (k, QCline_width))
3952		{
3953		  if (!INTEGERP (v) || XINT (v) == 0)
3954		    break;
3955		}
3956	      else if (EQ (k, QCcolor))
3957		{
3958		  if (!STRINGP (v) || XSTRING (v)->size == 0)
3959		    break;
3960		}
3961	      else if (EQ (k, QCstyle))
3962		{
3963		  if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button))
3964		    break;
3965		}
3966	      else
3967		break;
3968	    }
3969
3970	  valid_p = NILP (tem);
3971	}
3972      else
3973	valid_p = 0;
3974
3975      if (!valid_p)
3976	signal_error ("Invalid face box", value);
3977
3978      old_value = LFACE_BOX (lface);
3979      LFACE_BOX (lface) = value;
3980    }
3981  else if (EQ (attr, QCinverse_video)
3982	   || EQ (attr, QCreverse_video))
3983    {
3984      if (!UNSPECIFIEDP (value))
3985	{
3986	  CHECK_SYMBOL (value, 3);
3987	  if (!EQ (value, Qt) && !NILP (value))
3988	    signal_error ("Invalid inverse-video face attribute value", value);
3989	}
3990      old_value = LFACE_INVERSE (lface);
3991      LFACE_INVERSE (lface) = value;
3992    }
3993  else if (EQ (attr, QCforeground))
3994    {
3995      if (!UNSPECIFIEDP (value))
3996	{
3997	  /* Don't check for valid color names here because it depends
3998	     on the frame (display) whether the color will be valid
3999	     when the face is realized.  */
4000	  CHECK_STRING (value, 3);
4001	  if (XSTRING (value)->size == 0)
4002	    signal_error ("Empty foreground color value", value);
4003	}
4004      old_value = LFACE_FOREGROUND (lface);
4005      LFACE_FOREGROUND (lface) = value;
4006    }
4007  else if (EQ (attr, QCbackground))
4008    {
4009      if (!UNSPECIFIEDP (value))
4010	{
4011	  /* Don't check for valid color names here because it depends
4012	     on the frame (display) whether the color will be valid
4013	     when the face is realized.  */
4014	  CHECK_STRING (value, 3);
4015	  if (XSTRING (value)->size == 0)
4016	    signal_error ("Empty background color value", value);
4017	}
4018      old_value = LFACE_BACKGROUND (lface);
4019      LFACE_BACKGROUND (lface) = value;
4020    }
4021  else if (EQ (attr, QCstipple))
4022    {
4023#ifdef HAVE_X_WINDOWS
4024      if (!UNSPECIFIEDP (value)
4025	  && !NILP (value)
4026	  && NILP (Fbitmap_spec_p (value)))
4027	signal_error ("Invalid stipple attribute", value);
4028      old_value = LFACE_STIPPLE (lface);
4029      LFACE_STIPPLE (lface) = value;
4030#endif /* HAVE_X_WINDOWS */
4031    }
4032  else if (EQ (attr, QCwidth))
4033    {
4034      if (!UNSPECIFIEDP (value))
4035	{
4036	  CHECK_SYMBOL (value, 3);
4037	  if (face_numeric_swidth (value) < 0)
4038	    signal_error ("Invalid face width", value);
4039	}
4040      old_value = LFACE_SWIDTH (lface);
4041      LFACE_SWIDTH (lface) = value;
4042      font_related_attr_p = 1;
4043    }
4044  else if (EQ (attr, QCfont))
4045    {
4046#ifdef HAVE_WINDOW_SYSTEM
4047      /* Set font-related attributes of the Lisp face from an
4048	 XLFD font name.  */
4049      struct frame *f;
4050      Lisp_Object tmp;
4051
4052      CHECK_STRING (value, 3);
4053      if (EQ (frame, Qt))
4054	f = SELECTED_FRAME ();
4055      else
4056	f = check_x_frame (frame);
4057
4058      /* VALUE may be a fontset name or an alias of fontset.  In such
4059         a case, use the base fontset name.  */
4060      tmp = Fquery_fontset (value, Qnil);
4061      if (!NILP (tmp))
4062	value = tmp;
4063
4064      if (!set_lface_from_font_name (f, lface, value, 1, 1))
4065	signal_error ("Invalid font or fontset name", value);
4066
4067      font_attr_p = 1;
4068#endif /* HAVE_WINDOW_SYSTEM */
4069    }
4070  else if (EQ (attr, QCinherit))
4071    {
4072      Lisp_Object tail;
4073      if (SYMBOLP (value))
4074	tail = Qnil;
4075      else
4076	for (tail = value; CONSP (tail); tail = XCDR (tail))
4077	  if (!SYMBOLP (XCAR (tail)))
4078	    break;
4079      if (NILP (tail))
4080	LFACE_INHERIT (lface) = value;
4081      else
4082	signal_error ("Invalid face inheritance", value);
4083    }
4084  else if (EQ (attr, QCbold))
4085    {
4086      old_value = LFACE_WEIGHT (lface);
4087      LFACE_WEIGHT (lface) = NILP (value) ? Qnormal : Qbold;
4088      font_related_attr_p = 1;
4089    }
4090  else if (EQ (attr, QCitalic))
4091    {
4092      old_value = LFACE_SLANT (lface);
4093      LFACE_SLANT (lface) = NILP (value) ? Qnormal : Qitalic;
4094      font_related_attr_p = 1;
4095    }
4096  else
4097    signal_error ("Invalid face attribute name", attr);
4098
4099  if (font_related_attr_p
4100      && !UNSPECIFIEDP (value))
4101    /* If a font-related attribute other than QCfont is specified, the
4102       original `font' attribute nor that of default face is useless
4103       to determine a new font.  Thus, we set it to nil so that font
4104       selection mechanism doesn't use it.  */
4105    LFACE_FONT (lface) = Qnil;
4106
4107  /* Changing a named face means that all realized faces depending on
4108     that face are invalid.  Since we cannot tell which realized faces
4109     depend on the face, make sure they are all removed.  This is done
4110     by incrementing face_change_count.  The next call to
4111     init_iterator will then free realized faces.  */
4112  if (!EQ (frame, Qt)
4113      && (EQ (attr, QCfont)
4114	  || NILP (Fequal (old_value, value))))
4115    {
4116      ++face_change_count;
4117      ++windows_or_buffers_changed;
4118    }
4119
4120  if (!UNSPECIFIEDP (value)
4121      && NILP (Fequal (old_value, value)))
4122    {
4123      Lisp_Object param;
4124
4125      param = Qnil;
4126
4127      if (EQ (face, Qdefault))
4128	{
4129#ifdef HAVE_WINDOW_SYSTEM
4130	  /* Changed font-related attributes of the `default' face are
4131	     reflected in changed `font' frame parameters. */
4132	  if (FRAMEP (frame)
4133	      && (font_related_attr_p || font_attr_p)
4134	      && lface_fully_specified_p (XVECTOR (lface)->contents))
4135	    set_font_frame_param (frame, lface);
4136	  else
4137#endif /* HAVE_WINDOW_SYSTEM */
4138
4139	  if (EQ (attr, QCforeground))
4140	    param = Qforeground_color;
4141	  else if (EQ (attr, QCbackground))
4142	    param = Qbackground_color;
4143	}
4144#ifdef HAVE_WINDOW_SYSTEM
4145#ifndef WINDOWSNT
4146      else if (EQ (face, Qscroll_bar))
4147	{
4148	  /* Changing the colors of `scroll-bar' sets frame parameters
4149	     `scroll-bar-foreground' and `scroll-bar-background'. */
4150	  if (EQ (attr, QCforeground))
4151	    param = Qscroll_bar_foreground;
4152	  else if (EQ (attr, QCbackground))
4153	    param = Qscroll_bar_background;
4154	}
4155#endif /* not WINDOWSNT */
4156      else if (EQ (face, Qborder))
4157	{
4158	  /* Changing background color of `border' sets frame parameter
4159	     `border-color'.  */
4160	  if (EQ (attr, QCbackground))
4161	    param = Qborder_color;
4162	}
4163      else if (EQ (face, Qcursor))
4164	{
4165	  /* Changing background color of `cursor' sets frame parameter
4166	     `cursor-color'.  */
4167	  if (EQ (attr, QCbackground))
4168	    param = Qcursor_color;
4169	}
4170      else if (EQ (face, Qmouse))
4171	{
4172	  /* Changing background color of `mouse' sets frame parameter
4173	     `mouse-color'.  */
4174	  if (EQ (attr, QCbackground))
4175	    param = Qmouse_color;
4176	}
4177#endif /* HAVE_WINDOW_SYSTEM */
4178      else if (EQ (face, Qmenu))
4179	{
4180	  /* Indicate that we have to update the menu bar when
4181	     realizing faces on FRAME.  FRAME t change the
4182	     default for new frames.  We do this by setting
4183	     setting the flag in new face caches   */
4184	  if (FRAMEP (frame))
4185	    {
4186	      struct frame *f = XFRAME (frame);
4187	      if (FRAME_FACE_CACHE (f) == NULL)
4188		FRAME_FACE_CACHE (f) = make_face_cache (f);
4189	      FRAME_FACE_CACHE (f)->menu_face_changed_p = 1;
4190	    }
4191	  else
4192	    menu_face_changed_default = 1;
4193	}
4194
4195      if (!NILP (param))
4196	if (EQ (frame, Qt))
4197	  /* Update `default-frame-alist', which is used for new frames.  */
4198	  {
4199	    store_in_alist (&Vdefault_frame_alist, param, value);
4200	  }
4201	else
4202	  /* Update the current frame's parameters.  */
4203	  {
4204	    Lisp_Object cons;
4205	    cons = XCAR (Vparam_value_alist);
4206	    XCAR (cons) = param;
4207	    XCDR (cons) = value;
4208	    Fmodify_frame_parameters (frame, Vparam_value_alist);
4209	  }
4210    }
4211
4212  return face;
4213}
4214
4215
4216#ifdef HAVE_WINDOW_SYSTEM
4217
4218/* Set the `font' frame parameter of FRAME determined from `default'
4219   face attributes LFACE.  If a face or fontset name is explicitely
4220   specfied in LFACE, use it as is.  Otherwise, determine a font name
4221   from the other font-related atrributes of LFACE.  In that case, if
4222   there's no matching font, signals an error.  */
4223
4224static void
4225set_font_frame_param (frame, lface)
4226     Lisp_Object frame, lface;
4227{
4228  struct frame *f = XFRAME (frame);
4229
4230  if (FRAME_WINDOW_P (f))
4231    {
4232      Lisp_Object font_name;
4233      char *font;
4234
4235      if (STRINGP (LFACE_FONT (lface)))
4236	font_name = LFACE_FONT (lface);
4237      else
4238	{
4239	  /* Choose a font name that reflects LFACE's attributes and has
4240	     the registry and encoding pattern specified in the default
4241	     fontset (3rd arg: -1) for ASCII characters (4th arg: 0).  */
4242	  font = choose_face_font (f, XVECTOR (lface)->contents, -1, 0);
4243	  if (!font)
4244	    error ("No font matches the specified attribute");
4245	  font_name = build_string (font);
4246	  xfree (font);
4247	}
4248
4249      Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font_name), Qnil));
4250    }
4251}
4252
4253
4254/* Update the corresponding face when frame parameter PARAM on frame F
4255   has been assigned the value NEW_VALUE.  */
4256
4257void
4258update_face_from_frame_parameter (f, param, new_value)
4259     struct frame *f;
4260     Lisp_Object param, new_value;
4261{
4262  Lisp_Object lface;
4263
4264  /* If there are no faces yet, give up.  This is the case when called
4265     from Fx_create_frame, and we do the necessary things later in
4266     face-set-after-frame-defaults.  */
4267  if (NILP (f->face_alist))
4268    return;
4269
4270  if (EQ (param, Qforeground_color))
4271    {
4272      lface = lface_from_face_name (f, Qdefault, 1);
4273      LFACE_FOREGROUND (lface) = (STRINGP (new_value)
4274				  ? new_value : Qunspecified);
4275      realize_basic_faces (f);
4276    }
4277  else if (EQ (param, Qbackground_color))
4278    {
4279      Lisp_Object frame;
4280
4281      /* Changing the background color might change the background
4282	 mode, so that we have to load new defface specs.  Call
4283	 frame-update-face-colors to do that.  */
4284      XSETFRAME (frame, f);
4285      call1 (Qframe_update_face_colors, frame);
4286
4287      lface = lface_from_face_name (f, Qdefault, 1);
4288      LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4289				  ? new_value : Qunspecified);
4290      realize_basic_faces (f);
4291    }
4292  else if (EQ (param, Qborder_color))
4293    {
4294      lface = lface_from_face_name (f, Qborder, 1);
4295      LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4296				  ? new_value : Qunspecified);
4297    }
4298  else if (EQ (param, Qcursor_color))
4299    {
4300      lface = lface_from_face_name (f, Qcursor, 1);
4301      LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4302				  ? new_value : Qunspecified);
4303    }
4304  else if (EQ (param, Qmouse_color))
4305    {
4306      lface = lface_from_face_name (f, Qmouse, 1);
4307      LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4308				  ? new_value : Qunspecified);
4309    }
4310}
4311
4312
4313/* Get the value of X resource RESOURCE, class CLASS for the display
4314   of frame FRAME.  This is here because ordinary `x-get-resource'
4315   doesn't take a frame argument.  */
4316
4317DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
4318       Sinternal_face_x_get_resource, 3, 3, 0, "")
4319  (resource, class, frame)
4320     Lisp_Object resource, class, frame;
4321{
4322  Lisp_Object value = Qnil;
4323#ifndef WINDOWSNT
4324#ifndef macintosh
4325  CHECK_STRING (resource, 0);
4326  CHECK_STRING (class, 1);
4327  CHECK_LIVE_FRAME (frame, 2);
4328  BLOCK_INPUT;
4329  value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)),
4330				  resource, class, Qnil, Qnil);
4331  UNBLOCK_INPUT;
4332#endif /* not macintosh */
4333#endif /* not WINDOWSNT */
4334  return value;
4335}
4336
4337
4338/* Return resource string VALUE as a boolean value, i.e. nil, or t.
4339   If VALUE is "on" or "true", return t.  If VALUE is "off" or
4340   "false", return nil.  Otherwise, if SIGNAL_P is non-zero, signal an
4341   error; if SIGNAL_P is zero, return 0.  */
4342
4343static Lisp_Object
4344face_boolean_x_resource_value (value, signal_p)
4345     Lisp_Object value;
4346     int signal_p;
4347{
4348  Lisp_Object result = make_number (0);
4349
4350  xassert (STRINGP (value));
4351
4352  if (xstricmp (XSTRING (value)->data, "on") == 0
4353      || xstricmp (XSTRING (value)->data, "true") == 0)
4354    result = Qt;
4355  else if (xstricmp (XSTRING (value)->data, "off") == 0
4356	   || xstricmp (XSTRING (value)->data, "false") == 0)
4357    result = Qnil;
4358  else if (xstricmp (XSTRING (value)->data, "unspecified") == 0)
4359    result = Qunspecified;
4360  else if (signal_p)
4361    signal_error ("Invalid face attribute value from X resource", value);
4362
4363  return result;
4364}
4365
4366
4367DEFUN ("internal-set-lisp-face-attribute-from-resource",
4368       Finternal_set_lisp_face_attribute_from_resource,
4369       Sinternal_set_lisp_face_attribute_from_resource,
4370       3, 4, 0, "")
4371  (face, attr, value, frame)
4372     Lisp_Object face, attr, value, frame;
4373{
4374  CHECK_SYMBOL (face, 0);
4375  CHECK_SYMBOL (attr, 1);
4376  CHECK_STRING (value, 2);
4377
4378  if (xstricmp (XSTRING (value)->data, "unspecified") == 0)
4379    value = Qunspecified;
4380  else if (EQ (attr, QCheight))
4381    {
4382      value = Fstring_to_number (value, make_number (10));
4383      if (XINT (value) <= 0)
4384	signal_error ("Invalid face height from X resource", value);
4385    }
4386  else if (EQ (attr, QCbold) || EQ (attr, QCitalic))
4387    value = face_boolean_x_resource_value (value, 1);
4388  else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
4389    value = intern (XSTRING (value)->data);
4390  else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
4391    value = face_boolean_x_resource_value (value, 1);
4392  else if (EQ (attr, QCunderline)
4393	   || EQ (attr, QCoverline)
4394	   || EQ (attr, QCstrike_through))
4395    {
4396      Lisp_Object boolean_value;
4397
4398      /* If the result of face_boolean_x_resource_value is t or nil,
4399	 VALUE does NOT specify a color. */
4400      boolean_value = face_boolean_x_resource_value (value, 0);
4401      if (SYMBOLP (boolean_value))
4402	value = boolean_value;
4403    }
4404  else if (EQ (attr, QCbox))
4405    value = Fcar (Fread_from_string (value, Qnil, Qnil));
4406
4407  return Finternal_set_lisp_face_attribute (face, attr, value, frame);
4408}
4409
4410#endif /* HAVE_WINDOW_SYSTEM */
4411
4412
4413/***********************************************************************
4414			      Menu face
4415 ***********************************************************************/
4416
4417#if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
4418
4419/* Make menus on frame F appear as specified by the `menu' face.  */
4420
4421static void
4422x_update_menu_appearance (f)
4423     struct frame *f;
4424{
4425  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
4426  XrmDatabase rdb;
4427
4428  if (dpyinfo
4429      && (rdb = XrmGetDatabase (FRAME_X_DISPLAY (f)),
4430	  rdb != NULL))
4431    {
4432      char line[512];
4433      Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
4434      struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
4435      char *myname = XSTRING (Vx_resource_name)->data;
4436      int changed_p = 0;
4437#ifdef USE_MOTIF
4438      const char *popup_path = "popup_menu";
4439#else
4440      const char *popup_path = "menu.popup";
4441#endif
4442
4443      if (STRINGP (LFACE_FOREGROUND (lface)))
4444	{
4445	  sprintf (line, "%s.%s*foreground: %s",
4446		   myname, popup_path,
4447		   XSTRING (LFACE_FOREGROUND (lface))->data);
4448	  XrmPutLineResource (&rdb, line);
4449	  sprintf (line, "%s.pane.menubar*foreground: %s",
4450		   myname, XSTRING (LFACE_FOREGROUND (lface))->data);
4451	  XrmPutLineResource (&rdb, line);
4452	  changed_p = 1;
4453	}
4454
4455      if (STRINGP (LFACE_BACKGROUND (lface)))
4456	{
4457	  sprintf (line, "%s.%s*background: %s",
4458		   myname, popup_path,
4459		   XSTRING (LFACE_BACKGROUND (lface))->data);
4460	  XrmPutLineResource (&rdb, line);
4461	  sprintf (line, "%s.pane.menubar*background: %s",
4462		   myname, XSTRING (LFACE_BACKGROUND (lface))->data);
4463	  XrmPutLineResource (&rdb, line);
4464	  changed_p = 1;
4465	}
4466
4467      if (face->font_name
4468	  && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
4469	      || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
4470	      || !UNSPECIFIEDP (LFACE_AVGWIDTH (lface))
4471	      || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
4472	      || !UNSPECIFIEDP (LFACE_SLANT (lface))
4473	      || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
4474	{
4475#ifdef USE_MOTIF
4476	  const char *suffix = "List";
4477#else
4478	  const char *suffix = "";
4479#endif
4480	  sprintf (line, "%s.pane.menubar*font%s: %s",
4481		   myname, suffix, face->font_name);
4482	  XrmPutLineResource (&rdb, line);
4483	  sprintf (line, "%s.%s*font%s: %s",
4484		   myname, popup_path, suffix, face->font_name);
4485	  XrmPutLineResource (&rdb, line);
4486	  changed_p = 1;
4487	}
4488
4489      if (changed_p && f->output_data.x->menubar_widget)
4490	free_frame_menubar (f);
4491    }
4492}
4493
4494#endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
4495
4496
4497
4498DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute,
4499       Sinternal_get_lisp_face_attribute,
4500       2, 3, 0,
4501  "Return face attribute KEYWORD of face SYMBOL.\n\
4502If SYMBOL does not name a valid Lisp face or KEYWORD isn't a valid\n\
4503face attribute name, signal an error.\n\
4504If the optional argument FRAME is given, report on face FACE in that\n\
4505frame.  If FRAME is t, report on the defaults for face FACE (for new\n\
4506frames).  If FRAME is omitted or nil, use the selected frame.")
4507  (symbol, keyword, frame)
4508     Lisp_Object symbol, keyword, frame;
4509{
4510  Lisp_Object lface, value = Qnil;
4511
4512  CHECK_SYMBOL (symbol, 0);
4513  CHECK_SYMBOL (keyword, 1);
4514
4515  if (EQ (frame, Qt))
4516    lface = lface_from_face_name (NULL, symbol, 1);
4517  else
4518    {
4519      if (NILP (frame))
4520	frame = selected_frame;
4521      CHECK_LIVE_FRAME (frame, 2);
4522      lface = lface_from_face_name (XFRAME (frame), symbol, 1);
4523    }
4524
4525  if (EQ (keyword, QCfamily))
4526    value = LFACE_FAMILY (lface);
4527  else if (EQ (keyword, QCheight))
4528    value = LFACE_HEIGHT (lface);
4529  else if (EQ (keyword, QCweight))
4530    value = LFACE_WEIGHT (lface);
4531  else if (EQ (keyword, QCslant))
4532    value = LFACE_SLANT (lface);
4533  else if (EQ (keyword, QCunderline))
4534    value = LFACE_UNDERLINE (lface);
4535  else if (EQ (keyword, QCoverline))
4536    value = LFACE_OVERLINE (lface);
4537  else if (EQ (keyword, QCstrike_through))
4538    value = LFACE_STRIKE_THROUGH (lface);
4539  else if (EQ (keyword, QCbox))
4540    value = LFACE_BOX (lface);
4541  else if (EQ (keyword, QCinverse_video)
4542	   || EQ (keyword, QCreverse_video))
4543    value = LFACE_INVERSE (lface);
4544  else if (EQ (keyword, QCforeground))
4545    value = LFACE_FOREGROUND (lface);
4546  else if (EQ (keyword, QCbackground))
4547    value = LFACE_BACKGROUND (lface);
4548  else if (EQ (keyword, QCstipple))
4549    value = LFACE_STIPPLE (lface);
4550  else if (EQ (keyword, QCwidth))
4551    value = LFACE_SWIDTH (lface);
4552  else if (EQ (keyword, QCinherit))
4553    value = LFACE_INHERIT (lface);
4554  else if (EQ (keyword, QCfont))
4555    value = LFACE_FONT (lface);
4556  else
4557    signal_error ("Invalid face attribute name", keyword);
4558
4559  return value;
4560}
4561
4562
4563DEFUN ("internal-lisp-face-attribute-values",
4564       Finternal_lisp_face_attribute_values,
4565       Sinternal_lisp_face_attribute_values, 1, 1, 0,
4566  "Return a list of valid discrete values for face attribute ATTR.\n\
4567Value is nil if ATTR doesn't have a discrete set of valid values.")
4568  (attr)
4569     Lisp_Object attr;
4570{
4571  Lisp_Object result = Qnil;
4572
4573  CHECK_SYMBOL (attr, 0);
4574
4575  if (EQ (attr, QCweight)
4576      || EQ (attr, QCslant)
4577      || EQ (attr, QCwidth))
4578    {
4579      /* Extract permissible symbols from tables.  */
4580      struct table_entry *table;
4581      int i, dim;
4582
4583      if (EQ (attr, QCweight))
4584	table = weight_table, dim = DIM (weight_table);
4585      else if (EQ (attr, QCslant))
4586	table = slant_table, dim = DIM (slant_table);
4587      else
4588	table = swidth_table, dim = DIM (swidth_table);
4589
4590      for (i = 0; i < dim; ++i)
4591	{
4592	  Lisp_Object symbol = *table[i].symbol;
4593	  Lisp_Object tail = result;
4594
4595	  while (!NILP (tail)
4596		 && !EQ (XCAR (tail), symbol))
4597	    tail = XCDR (tail);
4598
4599	  if (NILP (tail))
4600	    result = Fcons (symbol, result);
4601	}
4602    }
4603  else if (EQ (attr, QCunderline))
4604    result = Fcons (Qt, Fcons (Qnil, Qnil));
4605  else if (EQ (attr, QCoverline))
4606    result = Fcons (Qt, Fcons (Qnil, Qnil));
4607  else if (EQ (attr, QCstrike_through))
4608    result = Fcons (Qt, Fcons (Qnil, Qnil));
4609  else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
4610    result = Fcons (Qt, Fcons (Qnil, Qnil));
4611
4612  return result;
4613}
4614
4615
4616DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face,
4617       Sinternal_merge_in_global_face, 2, 2, 0,
4618  "Add attributes from frame-default definition of FACE to FACE on FRAME.\n\
4619Default face attributes override any local face attributes.")
4620  (face, frame)
4621     Lisp_Object face, frame;
4622{
4623  int i;
4624  Lisp_Object global_lface, local_lface, *gvec, *lvec;
4625
4626  CHECK_LIVE_FRAME (frame, 1);
4627  global_lface = lface_from_face_name (NULL, face, 1);
4628  local_lface = lface_from_face_name (XFRAME (frame), face, 0);
4629  if (NILP (local_lface))
4630    local_lface = Finternal_make_lisp_face (face, frame);
4631
4632  /* Make every specified global attribute override the local one.
4633     BEWARE!! This is only used from `face-set-after-frame-default' where
4634     the local frame is defined from default specs in `face-defface-spec'
4635     and those should be overridden by global settings.  Hence the strange
4636     "global before local" priority.  */
4637  lvec = XVECTOR (local_lface)->contents;
4638  gvec = XVECTOR (global_lface)->contents;
4639  for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4640    if (! UNSPECIFIEDP (gvec[i]))
4641      lvec[i] = gvec[i];
4642
4643  return Qnil;
4644}
4645
4646
4647/* The following function is implemented for compatibility with 20.2.
4648   The function is used in x-resolve-fonts when it is asked to
4649   return fonts with the same size as the font of a face.  This is
4650   done in fontset.el.  */
4651
4652DEFUN ("face-font", Fface_font, Sface_font, 1, 2, 0,
4653  "Return the font name of face FACE, or nil if it is unspecified.\n\
4654If the optional argument FRAME is given, report on face FACE in that frame.\n\
4655If FRAME is t, report on the defaults for face FACE (for new frames).\n\
4656  The font default for a face is either nil, or a list\n\
4657  of the form (bold), (italic) or (bold italic).\n\
4658If FRAME is omitted or nil, use the selected frame.")
4659  (face, frame)
4660     Lisp_Object face, frame;
4661{
4662  if (EQ (frame, Qt))
4663    {
4664      Lisp_Object result = Qnil;
4665      Lisp_Object lface = lface_from_face_name (NULL, face, 1);
4666
4667      if (!UNSPECIFIEDP (LFACE_WEIGHT (lface))
4668	  && !EQ (LFACE_WEIGHT (lface), Qnormal))
4669	result = Fcons (Qbold, result);
4670
4671      if (!UNSPECIFIEDP (LFACE_SLANT (lface))
4672	  && !EQ (LFACE_SLANT (lface), Qnormal))
4673	result = Fcons (Qitalic, result);
4674
4675      return result;
4676    }
4677  else
4678    {
4679      struct frame *f = frame_or_selected_frame (frame, 1);
4680      int face_id = lookup_named_face (f, face, 0);
4681      struct face *face = FACE_FROM_ID (f, face_id);
4682      return face ? build_string (face->font_name) : Qnil;
4683    }
4684}
4685
4686
4687/* Compare face vectors V1 and V2 for equality.  Value is non-zero if
4688   all attributes are `equal'.  Tries to be fast because this function
4689   is called quite often.  */
4690
4691static INLINE int
4692lface_equal_p (v1, v2)
4693     Lisp_Object *v1, *v2;
4694{
4695  int i, equal_p = 1;
4696
4697  for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
4698    {
4699      Lisp_Object a = v1[i];
4700      Lisp_Object b = v2[i];
4701
4702      /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
4703	 and the other is specified.  */
4704      equal_p = XTYPE (a) == XTYPE (b);
4705      if (!equal_p)
4706	break;
4707
4708      if (!EQ (a, b))
4709	{
4710	  switch (XTYPE (a))
4711	    {
4712	    case Lisp_String:
4713	      equal_p = ((STRING_BYTES (XSTRING (a))
4714			  == STRING_BYTES (XSTRING (b)))
4715			 && bcmp (XSTRING (a)->data, XSTRING (b)->data,
4716				  STRING_BYTES (XSTRING (a))) == 0);
4717	      break;
4718
4719	    case Lisp_Int:
4720	    case Lisp_Symbol:
4721	      equal_p = 0;
4722	      break;
4723
4724	    default:
4725	      equal_p = !NILP (Fequal (a, b));
4726	      break;
4727	    }
4728	}
4729    }
4730
4731  return equal_p;
4732}
4733
4734
4735DEFUN ("internal-lisp-face-equal-p", Finternal_lisp_face_equal_p,
4736       Sinternal_lisp_face_equal_p, 2, 3, 0,
4737  "True if FACE1 and FACE2 are equal.\n\
4738If the optional argument FRAME is given, report on face FACE in that frame.\n\
4739If FRAME is t, report on the defaults for face FACE (for new frames).\n\
4740If FRAME is omitted or nil, use the selected frame.")
4741  (face1, face2, frame)
4742     Lisp_Object face1, face2, frame;
4743{
4744  int equal_p;
4745  struct frame *f;
4746  Lisp_Object lface1, lface2;
4747
4748  if (EQ (frame, Qt))
4749    f = NULL;
4750  else
4751    /* Don't use check_x_frame here because this function is called
4752       before X frames exist.  At that time, if FRAME is nil,
4753       selected_frame will be used which is the frame dumped with
4754       Emacs.  That frame is not an X frame.  */
4755    f = frame_or_selected_frame (frame, 2);
4756
4757  lface1 = lface_from_face_name (NULL, face1, 1);
4758  lface2 = lface_from_face_name (NULL, face2, 1);
4759  equal_p = lface_equal_p (XVECTOR (lface1)->contents,
4760			   XVECTOR (lface2)->contents);
4761  return equal_p ? Qt : Qnil;
4762}
4763
4764
4765DEFUN ("internal-lisp-face-empty-p", Finternal_lisp_face_empty_p,
4766       Sinternal_lisp_face_empty_p, 1, 2, 0,
4767  "True if FACE has no attribute specified.\n\
4768If the optional argument FRAME is given, report on face FACE in that frame.\n\
4769If FRAME is t, report on the defaults for face FACE (for new frames).\n\
4770If FRAME is omitted or nil, use the selected frame.")
4771  (face, frame)
4772     Lisp_Object face, frame;
4773{
4774  struct frame *f;
4775  Lisp_Object lface;
4776  int i;
4777
4778  if (NILP (frame))
4779    frame = selected_frame;
4780  CHECK_LIVE_FRAME (frame, 0);
4781  f = XFRAME (frame);
4782
4783  if (EQ (frame, Qt))
4784    lface = lface_from_face_name (NULL, face, 1);
4785  else
4786    lface = lface_from_face_name (f, face, 1);
4787
4788  for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4789    if (!UNSPECIFIEDP (AREF (lface, i)))
4790      break;
4791
4792  return i == LFACE_VECTOR_SIZE ? Qt : Qnil;
4793}
4794
4795
4796DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
4797       0, 1, 0,
4798  "Return an alist of frame-local faces defined on FRAME.\n\
4799For internal use only.")
4800  (frame)
4801     Lisp_Object frame;
4802{
4803  struct frame *f = frame_or_selected_frame (frame, 0);
4804  return f->face_alist;
4805}
4806
4807
4808/* Return a hash code for Lisp string STRING with case ignored.  Used
4809   below in computing a hash value for a Lisp face.  */
4810
4811static INLINE unsigned
4812hash_string_case_insensitive (string)
4813     Lisp_Object string;
4814{
4815  unsigned char *s;
4816  unsigned hash = 0;
4817  xassert (STRINGP (string));
4818  for (s = XSTRING (string)->data; *s; ++s)
4819    hash = (hash << 1) ^ tolower (*s);
4820  return hash;
4821}
4822
4823
4824/* Return a hash code for face attribute vector V.  */
4825
4826static INLINE unsigned
4827lface_hash (v)
4828     Lisp_Object *v;
4829{
4830  return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
4831	  ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
4832	  ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
4833	  ^ XFASTINT (v[LFACE_WEIGHT_INDEX])
4834	  ^ XFASTINT (v[LFACE_SLANT_INDEX])
4835	  ^ XFASTINT (v[LFACE_SWIDTH_INDEX])
4836	  ^ XFASTINT (v[LFACE_HEIGHT_INDEX]));
4837}
4838
4839
4840/* Return non-zero if LFACE1 and LFACE2 specify the same font (without
4841   considering charsets/registries).  They do if they specify the same
4842   family, point size, weight, width, slant, and fontset.  Both LFACE1
4843   and LFACE2 must be fully-specified.  */
4844
4845static INLINE int
4846lface_same_font_attributes_p (lface1, lface2)
4847     Lisp_Object *lface1, *lface2;
4848{
4849  xassert (lface_fully_specified_p (lface1)
4850	   && lface_fully_specified_p (lface2));
4851  return (xstricmp (XSTRING (lface1[LFACE_FAMILY_INDEX])->data,
4852		    XSTRING (lface2[LFACE_FAMILY_INDEX])->data) == 0
4853	  && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
4854	  && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
4855	  && EQ (lface1[LFACE_AVGWIDTH_INDEX], lface2[LFACE_AVGWIDTH_INDEX])
4856	  && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
4857	  && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX])
4858	  && (EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
4859	      || (STRINGP (lface1[LFACE_FONT_INDEX])
4860		  && STRINGP (lface2[LFACE_FONT_INDEX])
4861		  && xstricmp (XSTRING (lface1[LFACE_FONT_INDEX])->data,
4862			       XSTRING (lface2[LFACE_FONT_INDEX])->data))));
4863}
4864
4865
4866
4867/***********************************************************************
4868			    Realized Faces
4869 ***********************************************************************/
4870
4871/* Allocate and return a new realized face for Lisp face attribute
4872   vector ATTR.  */
4873
4874static struct face *
4875make_realized_face (attr)
4876     Lisp_Object *attr;
4877{
4878  struct face *face = (struct face *) xmalloc (sizeof *face);
4879  bzero (face, sizeof *face);
4880  face->ascii_face = face;
4881  bcopy (attr, face->lface, sizeof face->lface);
4882  return face;
4883}
4884
4885
4886/* Free realized face FACE, including its X resources.  FACE may
4887   be null.  */
4888
4889static void
4890free_realized_face (f, face)
4891     struct frame *f;
4892     struct face *face;
4893{
4894  if (face)
4895    {
4896#ifdef HAVE_WINDOW_SYSTEM
4897      if (FRAME_WINDOW_P (f))
4898	{
4899	  /* Free fontset of FACE if it is ASCII face.  */
4900	  if (face->fontset >= 0 && face == face->ascii_face)
4901	    free_face_fontset (f, face);
4902	  if (face->gc)
4903	    {
4904	      x_free_gc (f, face->gc);
4905	      face->gc = 0;
4906	    }
4907
4908	  free_face_colors (f, face);
4909	  x_destroy_bitmap (f, face->stipple);
4910	}
4911#endif /* HAVE_WINDOW_SYSTEM */
4912
4913      xfree (face);
4914    }
4915}
4916
4917
4918/* Prepare face FACE for subsequent display on frame F.  This
4919   allocated GCs if they haven't been allocated yet or have been freed
4920   by clearing the face cache.  */
4921
4922void
4923prepare_face_for_display (f, face)
4924     struct frame *f;
4925     struct face *face;
4926{
4927#ifdef HAVE_WINDOW_SYSTEM
4928  xassert (FRAME_WINDOW_P (f));
4929
4930  if (face->gc == 0)
4931    {
4932      XGCValues xgcv;
4933      unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
4934
4935      xgcv.foreground = face->foreground;
4936      xgcv.background = face->background;
4937#ifdef HAVE_X_WINDOWS
4938      xgcv.graphics_exposures = False;
4939#endif
4940      /* The font of FACE may be null if we couldn't load it.  */
4941      if (face->font)
4942	{
4943#ifdef HAVE_X_WINDOWS
4944	  xgcv.font = face->font->fid;
4945#endif
4946#ifdef WINDOWSNT
4947	  xgcv.font = face->font;
4948#endif
4949#ifdef macintosh
4950	  xgcv.font = face->font;
4951#endif
4952	  mask |= GCFont;
4953	}
4954
4955      BLOCK_INPUT;
4956#ifdef HAVE_X_WINDOWS
4957      if (face->stipple)
4958	{
4959	  xgcv.fill_style = FillOpaqueStippled;
4960	  xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
4961	  mask |= GCFillStyle | GCStipple;
4962	}
4963#endif
4964      face->gc = x_create_gc (f, mask, &xgcv);
4965      UNBLOCK_INPUT;
4966    }
4967#endif /* HAVE_WINDOW_SYSTEM */
4968}
4969
4970
4971/***********************************************************************
4972			      Face Cache
4973 ***********************************************************************/
4974
4975/* Return a new face cache for frame F.  */
4976
4977static struct face_cache *
4978make_face_cache (f)
4979     struct frame *f;
4980{
4981  struct face_cache *c;
4982  int size;
4983
4984  c = (struct face_cache *) xmalloc (sizeof *c);
4985  bzero (c, sizeof *c);
4986  size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4987  c->buckets = (struct face **) xmalloc (size);
4988  bzero (c->buckets, size);
4989  c->size = 50;
4990  c->faces_by_id = (struct face **) xmalloc (c->size * sizeof *c->faces_by_id);
4991  c->f = f;
4992  c->menu_face_changed_p = menu_face_changed_default;
4993  return c;
4994}
4995
4996
4997/* Clear out all graphics contexts for all realized faces, except for
4998   the basic faces.  This should be done from time to time just to avoid
4999   keeping too many graphics contexts that are no longer needed.  */
5000
5001static void
5002clear_face_gcs (c)
5003     struct face_cache *c;
5004{
5005  if (c && FRAME_WINDOW_P (c->f))
5006    {
5007#ifdef HAVE_WINDOW_SYSTEM
5008      int i;
5009      for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
5010	{
5011	  struct face *face = c->faces_by_id[i];
5012	  if (face && face->gc)
5013	    {
5014	      x_free_gc (c->f, face->gc);
5015	      face->gc = 0;
5016	    }
5017	}
5018#endif /* HAVE_WINDOW_SYSTEM */
5019    }
5020}
5021
5022
5023/* Free all realized faces in face cache C, including basic faces.  C
5024   may be null.  If faces are freed, make sure the frame's current
5025   matrix is marked invalid, so that a display caused by an expose
5026   event doesn't try to use faces we destroyed.  */
5027
5028static void
5029free_realized_faces (c)
5030     struct face_cache *c;
5031{
5032  if (c && c->used)
5033    {
5034      int i, size;
5035      struct frame *f = c->f;
5036
5037      /* We must block input here because we can't process X events
5038	 safely while only some faces are freed, or when the frame's
5039	 current matrix still references freed faces.  */
5040      BLOCK_INPUT;
5041
5042      for (i = 0; i < c->used; ++i)
5043	{
5044	  free_realized_face (f, c->faces_by_id[i]);
5045	  c->faces_by_id[i] = NULL;
5046	}
5047
5048      c->used = 0;
5049      size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
5050      bzero (c->buckets, size);
5051
5052      /* Must do a thorough redisplay the next time.  Mark current
5053	 matrices as invalid because they will reference faces freed
5054	 above.  This function is also called when a frame is
5055	 destroyed.  In this case, the root window of F is nil.  */
5056      if (WINDOWP (f->root_window))
5057	{
5058	  clear_current_matrices (f);
5059	  ++windows_or_buffers_changed;
5060	}
5061
5062      UNBLOCK_INPUT;
5063    }
5064}
5065
5066
5067/* Free all faces realized for multibyte characters on frame F that
5068   has FONTSET.  */
5069
5070void
5071free_realized_multibyte_face (f, fontset)
5072     struct frame *f;
5073     int fontset;
5074{
5075  struct face_cache *cache = FRAME_FACE_CACHE (f);
5076  struct face *face;
5077  int i;
5078
5079  /* We must block input here because we can't process X events safely
5080     while only some faces are freed, or when the frame's current
5081     matrix still references freed faces.  */
5082  BLOCK_INPUT;
5083
5084  for (i = 0; i < cache->used; i++)
5085    {
5086      face = cache->faces_by_id[i];
5087      if (face
5088	  && face != face->ascii_face
5089	  && face->fontset == fontset)
5090	{
5091	  uncache_face (cache, face);
5092	  free_realized_face (f, face);
5093	}
5094    }
5095
5096  /* Must do a thorough redisplay the next time.  Mark current
5097     matrices as invalid because they will reference faces freed
5098     above.  This function is also called when a frame is destroyed.
5099     In this case, the root window of F is nil.  */
5100  if (WINDOWP (f->root_window))
5101    {
5102      clear_current_matrices (f);
5103      ++windows_or_buffers_changed;
5104    }
5105
5106  UNBLOCK_INPUT;
5107}
5108
5109
5110/* Free all realized faces on FRAME or on all frames if FRAME is nil.
5111   This is done after attributes of a named face have been changed,
5112   because we can't tell which realized faces depend on that face.  */
5113
5114void
5115free_all_realized_faces (frame)
5116     Lisp_Object frame;
5117{
5118  if (NILP (frame))
5119    {
5120      Lisp_Object rest;
5121      FOR_EACH_FRAME (rest, frame)
5122	free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
5123    }
5124  else
5125    free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
5126}
5127
5128
5129/* Free face cache C and faces in it, including their X resources.  */
5130
5131static void
5132free_face_cache (c)
5133     struct face_cache *c;
5134{
5135  if (c)
5136    {
5137      free_realized_faces (c);
5138      xfree (c->buckets);
5139      xfree (c->faces_by_id);
5140      xfree (c);
5141    }
5142}
5143
5144
5145/* Cache realized face FACE in face cache C.  HASH is the hash value
5146   of FACE.  If FACE->fontset >= 0, add the new face to the end of the
5147   collision list of the face hash table of C.  This is done because
5148   otherwise lookup_face would find FACE for every character, even if
5149   faces with the same attributes but for specific characters exist.  */
5150
5151static void
5152cache_face (c, face, hash)
5153     struct face_cache *c;
5154     struct face *face;
5155     unsigned hash;
5156{
5157  int i = hash % FACE_CACHE_BUCKETS_SIZE;
5158
5159  face->hash = hash;
5160
5161  if (face->fontset >= 0)
5162    {
5163      struct face *last = c->buckets[i];
5164      if (last)
5165	{
5166	  while (last->next)
5167	    last = last->next;
5168	  last->next = face;
5169	  face->prev = last;
5170	  face->next = NULL;
5171	}
5172      else
5173	{
5174	  c->buckets[i] = face;
5175	  face->prev = face->next = NULL;
5176	}
5177    }
5178  else
5179    {
5180      face->prev = NULL;
5181      face->next = c->buckets[i];
5182      if (face->next)
5183	face->next->prev = face;
5184      c->buckets[i] = face;
5185    }
5186
5187  /* Find a free slot in C->faces_by_id and use the index of the free
5188     slot as FACE->id.  */
5189  for (i = 0; i < c->used; ++i)
5190    if (c->faces_by_id[i] == NULL)
5191      break;
5192  face->id = i;
5193
5194  /* Maybe enlarge C->faces_by_id.  */
5195  if (i == c->used && c->used == c->size)
5196    {
5197      int new_size = 2 * c->size;
5198      int sz = new_size * sizeof *c->faces_by_id;
5199      c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
5200      c->size = new_size;
5201    }
5202
5203#if GLYPH_DEBUG
5204  /* Check that FACE got a unique id.  */
5205  {
5206    int j, n;
5207    struct face *face;
5208
5209    for (j = n = 0; j < FACE_CACHE_BUCKETS_SIZE; ++j)
5210      for (face = c->buckets[j]; face; face = face->next)
5211	if (face->id == i)
5212	  ++n;
5213
5214    xassert (n == 1);
5215  }
5216#endif /* GLYPH_DEBUG */
5217
5218  c->faces_by_id[i] = face;
5219  if (i == c->used)
5220    ++c->used;
5221}
5222
5223
5224/* Remove face FACE from cache C.  */
5225
5226static void
5227uncache_face (c, face)
5228     struct face_cache *c;
5229     struct face *face;
5230{
5231  int i = face->hash % FACE_CACHE_BUCKETS_SIZE;
5232
5233  if (face->prev)
5234    face->prev->next = face->next;
5235  else
5236    c->buckets[i] = face->next;
5237
5238  if (face->next)
5239    face->next->prev = face->prev;
5240
5241  c->faces_by_id[face->id] = NULL;
5242  if (face->id == c->used)
5243    --c->used;
5244}
5245
5246
5247/* Look up a realized face with face attributes ATTR in the face cache
5248   of frame F.  The face will be used to display character C.  Value
5249   is the ID of the face found.  If no suitable face is found, realize
5250   a new one.  In that case, if C is a multibyte character, BASE_FACE
5251   is a face that has the same attributes.  */
5252
5253INLINE int
5254lookup_face (f, attr, c, base_face)
5255     struct frame *f;
5256     Lisp_Object *attr;
5257     int c;
5258     struct face *base_face;
5259{
5260  struct face_cache *cache = FRAME_FACE_CACHE (f);
5261  unsigned hash;
5262  int i;
5263  struct face *face;
5264
5265  xassert (cache != NULL);
5266  check_lface_attrs (attr);
5267
5268  /* Look up ATTR in the face cache.  */
5269  hash = lface_hash (attr);
5270  i = hash % FACE_CACHE_BUCKETS_SIZE;
5271
5272  for (face = cache->buckets[i]; face; face = face->next)
5273    if (face->hash == hash
5274	&& (!FRAME_WINDOW_P (f)
5275	    || FACE_SUITABLE_FOR_CHAR_P (face, c))
5276	&& lface_equal_p (face->lface, attr))
5277      break;
5278
5279  /* If not found, realize a new face.  */
5280  if (face == NULL)
5281    face = realize_face (cache, attr, c, base_face, -1);
5282
5283#if GLYPH_DEBUG
5284  xassert (face == FACE_FROM_ID (f, face->id));
5285
5286/* When this function is called from face_for_char (in this case, C is
5287   a multibyte character), a fontset of a face returned by
5288   realize_face is not yet set, i.e. FACE_SUITABLE_FOR_CHAR_P (FACE,
5289   C) is not sutisfied.  The fontset is set for this face by
5290   face_for_char later.  */
5291#if 0
5292  if (FRAME_WINDOW_P (f))
5293    xassert (FACE_SUITABLE_FOR_CHAR_P (face, c));
5294#endif
5295#endif /* GLYPH_DEBUG */
5296
5297  return face->id;
5298}
5299
5300
5301/* Return the face id of the realized face for named face SYMBOL on
5302   frame F suitable for displaying character C.  Value is -1 if the
5303   face couldn't be determined, which might happen if the default face
5304   isn't realized and cannot be realized.  */
5305
5306int
5307lookup_named_face (f, symbol, c)
5308     struct frame *f;
5309     Lisp_Object symbol;
5310     int c;
5311{
5312  Lisp_Object attrs[LFACE_VECTOR_SIZE];
5313  Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
5314  struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5315
5316  if (default_face == NULL)
5317    {
5318      if (!realize_basic_faces (f))
5319	return -1;
5320      default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5321    }
5322
5323  get_lface_attributes (f, symbol, symbol_attrs, 1);
5324  bcopy (default_face->lface, attrs, sizeof attrs);
5325  merge_face_vectors (f, symbol_attrs, attrs, Qnil);
5326  return lookup_face (f, attrs, c, NULL);
5327}
5328
5329
5330/* Return the ID of the realized ASCII face of Lisp face with ID
5331   LFACE_ID on frame F.  Value is -1 if LFACE_ID isn't valid.  */
5332
5333int
5334ascii_face_of_lisp_face (f, lface_id)
5335     struct frame *f;
5336     int lface_id;
5337{
5338  int face_id;
5339
5340  if (lface_id >= 0 && lface_id < lface_id_to_name_size)
5341    {
5342      Lisp_Object face_name = lface_id_to_name[lface_id];
5343      face_id = lookup_named_face (f, face_name, 0);
5344    }
5345  else
5346    face_id = -1;
5347
5348  return face_id;
5349}
5350
5351
5352/* Return a face for charset ASCII that is like the face with id
5353   FACE_ID on frame F, but has a font that is STEPS steps smaller.
5354   STEPS < 0 means larger.  Value is the id of the face.  */
5355
5356int
5357smaller_face (f, face_id, steps)
5358     struct frame *f;
5359     int face_id, steps;
5360{
5361#ifdef HAVE_WINDOW_SYSTEM
5362  struct face *face;
5363  Lisp_Object attrs[LFACE_VECTOR_SIZE];
5364  int pt, last_pt, last_height;
5365  int delta;
5366  int new_face_id;
5367  struct face *new_face;
5368
5369  /* If not called for an X frame, just return the original face.  */
5370  if (FRAME_TERMCAP_P (f))
5371    return face_id;
5372
5373  /* Try in increments of 1/2 pt.  */
5374  delta = steps < 0 ? 5 : -5;
5375  steps = abs (steps);
5376
5377  face = FACE_FROM_ID (f, face_id);
5378  bcopy (face->lface, attrs, sizeof attrs);
5379  pt = last_pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
5380  new_face_id = face_id;
5381  last_height = FONT_HEIGHT (face->font);
5382
5383  while (steps
5384	 && pt + delta > 0
5385	 /* Give up if we cannot find a font within 10pt.  */
5386	 && abs (last_pt - pt) < 100)
5387    {
5388      /* Look up a face for a slightly smaller/larger font.  */
5389      pt += delta;
5390      attrs[LFACE_HEIGHT_INDEX] = make_number (pt);
5391      new_face_id = lookup_face (f, attrs, 0, NULL);
5392      new_face = FACE_FROM_ID (f, new_face_id);
5393
5394      /* If height changes, count that as one step.  */
5395      if ((delta < 0 && FONT_HEIGHT (new_face->font) < last_height)
5396	  || (delta > 0 && FONT_HEIGHT (new_face->font) > last_height))
5397	{
5398	  --steps;
5399	  last_height = FONT_HEIGHT (new_face->font);
5400	  last_pt = pt;
5401	}
5402    }
5403
5404  return new_face_id;
5405
5406#else /* not HAVE_WINDOW_SYSTEM */
5407
5408  return face_id;
5409
5410#endif /* not HAVE_WINDOW_SYSTEM */
5411}
5412
5413
5414/* Return a face for charset ASCII that is like the face with id
5415   FACE_ID on frame F, but has height HEIGHT.  */
5416
5417int
5418face_with_height (f, face_id, height)
5419     struct frame *f;
5420     int face_id;
5421     int height;
5422{
5423#ifdef HAVE_WINDOW_SYSTEM
5424  struct face *face;
5425  Lisp_Object attrs[LFACE_VECTOR_SIZE];
5426
5427  if (FRAME_TERMCAP_P (f)
5428      || height <= 0)
5429    return face_id;
5430
5431  face = FACE_FROM_ID (f, face_id);
5432  bcopy (face->lface, attrs, sizeof attrs);
5433  attrs[LFACE_HEIGHT_INDEX] = make_number (height);
5434  face_id = lookup_face (f, attrs, 0, NULL);
5435#endif /* HAVE_WINDOW_SYSTEM */
5436
5437  return face_id;
5438}
5439
5440
5441/* Return the face id of the realized face for named face SYMBOL on
5442   frame F suitable for displaying character C, and use attributes of
5443   the face FACE_ID for attributes that aren't completely specified by
5444   SYMBOL.  This is like lookup_named_face, except that the default
5445   attributes come from FACE_ID, not from the default face.  FACE_ID
5446   is assumed to be already realized.  */
5447
5448int
5449lookup_derived_face (f, symbol, c, face_id)
5450     struct frame *f;
5451     Lisp_Object symbol;
5452     int c;
5453     int face_id;
5454{
5455  Lisp_Object attrs[LFACE_VECTOR_SIZE];
5456  Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
5457  struct face *default_face = FACE_FROM_ID (f, face_id);
5458
5459  if (!default_face)
5460    abort ();
5461
5462  get_lface_attributes (f, symbol, symbol_attrs, 1);
5463  bcopy (default_face->lface, attrs, sizeof attrs);
5464  merge_face_vectors (f, symbol_attrs, attrs, Qnil);
5465  return lookup_face (f, attrs, c, default_face);
5466}
5467
5468
5469
5470/***********************************************************************
5471			    Font selection
5472 ***********************************************************************/
5473
5474DEFUN ("internal-set-font-selection-order",
5475       Finternal_set_font_selection_order,
5476       Sinternal_set_font_selection_order, 1, 1, 0,
5477  "Set font selection order for face font selection to ORDER.\n\
5478ORDER must be a list of length 4 containing the symbols `:width',\n\
5479`:height', `:weight', and `:slant'.  Face attributes appearing\n\
5480first in ORDER are matched first, e.g. if `:height' appears before\n\
5481`:weight' in ORDER, font selection first tries to find a font with\n\
5482a suitable height, and then tries to match the font weight.\n\
5483Value is ORDER.")
5484  (order)
5485       Lisp_Object order;
5486{
5487  Lisp_Object list;
5488  int i;
5489  int indices[DIM (font_sort_order)];
5490
5491  CHECK_LIST (order, 0);
5492  bzero (indices, sizeof indices);
5493  i = 0;
5494
5495  for (list = order;
5496       CONSP (list) && i < DIM (indices);
5497       list = XCDR (list), ++i)
5498    {
5499      Lisp_Object attr = XCAR (list);
5500      int xlfd;
5501
5502      if (EQ (attr, QCwidth))
5503	xlfd = XLFD_SWIDTH;
5504      else if (EQ (attr, QCheight))
5505	xlfd = XLFD_POINT_SIZE;
5506      else if (EQ (attr, QCweight))
5507	xlfd = XLFD_WEIGHT;
5508      else if (EQ (attr, QCslant))
5509	xlfd = XLFD_SLANT;
5510      else
5511	break;
5512
5513      if (indices[i] != 0)
5514	break;
5515      indices[i] = xlfd;
5516    }
5517
5518  if (!NILP (list) || i != DIM (indices))
5519    signal_error ("Invalid font sort order", order);
5520  for (i = 0; i < DIM (font_sort_order); ++i)
5521    if (indices[i] == 0)
5522      signal_error ("Invalid font sort order", order);
5523
5524  if (bcmp (indices, font_sort_order, sizeof indices) != 0)
5525    {
5526      bcopy (indices, font_sort_order, sizeof font_sort_order);
5527      free_all_realized_faces (Qnil);
5528    }
5529
5530  return Qnil;
5531}
5532
5533
5534DEFUN ("internal-set-alternative-font-family-alist",
5535       Finternal_set_alternative_font_family_alist,
5536       Sinternal_set_alternative_font_family_alist, 1, 1, 0,
5537  "Define alternative font families to try in face font selection.\n\
5538ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.\n\
5539Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can\n\
5540be found.  Value is ALIST.")
5541  (alist)
5542     Lisp_Object alist;
5543{
5544  CHECK_LIST (alist, 0);
5545  Vface_alternative_font_family_alist = alist;
5546  free_all_realized_faces (Qnil);
5547  return alist;
5548}
5549
5550
5551DEFUN ("internal-set-alternative-font-registry-alist",
5552       Finternal_set_alternative_font_registry_alist,
5553       Sinternal_set_alternative_font_registry_alist, 1, 1, 0,
5554  "Define alternative font registries to try in face font selection.\n\
5555ALIST is an alist of (REGISTRY ALTERNATIVE1 ALTERNATIVE2 ...) entries.\n\
5556Each ALTERNATIVE is tried in order if no fonts of font registry REGISTRY can\n\
5557be found.  Value is ALIST.")
5558  (alist)
5559     Lisp_Object alist;
5560{
5561  CHECK_LIST (alist, 0);
5562  Vface_alternative_font_registry_alist = alist;
5563  free_all_realized_faces (Qnil);
5564  return alist;
5565}
5566
5567
5568#ifdef HAVE_WINDOW_SYSTEM
5569
5570/* Value is non-zero if FONT is the name of a scalable font.  The
5571   X11R6 XLFD spec says that point size, pixel size, and average width
5572   are zero for scalable fonts.  Intlfonts contain at least one
5573   scalable font ("*-muleindian-1") for which this isn't true, so we
5574   just test average width.  */
5575
5576static int
5577font_scalable_p (font)
5578     struct font_name *font;
5579{
5580  char *s = font->fields[XLFD_AVGWIDTH];
5581  return (*s == '0' && *(s + 1) == '\0')
5582#ifdef WINDOWSNT
5583  /* Windows implementation of XLFD is slightly broken for backward
5584     compatibility with previous broken versions, so test for
5585     wildcards as well as 0. */
5586  || *s == '*'
5587#endif
5588    ;
5589}
5590
5591
5592/* Ignore the difference of font point size less than this value.  */
5593
5594#define FONT_POINT_SIZE_QUANTUM 5
5595
5596/* Value is non-zero if FONT1 is a better match for font attributes
5597   VALUES than FONT2.  VALUES is an array of face attribute values in
5598   font sort order.  COMPARE_PT_P zero means don't compare point
5599   sizes.  AVGWIDTH, if not zero, is a specified font average width
5600   to compare with.  */
5601
5602static int
5603better_font_p (values, font1, font2, compare_pt_p, avgwidth)
5604     int *values;
5605     struct font_name *font1, *font2;
5606     int compare_pt_p, avgwidth;
5607{
5608  int i;
5609
5610  for (i = 0; i < DIM (font_sort_order); ++i)
5611    {
5612      int xlfd_idx = font_sort_order[i];
5613
5614      if (compare_pt_p || xlfd_idx != XLFD_POINT_SIZE)
5615	{
5616	  int delta1 = abs (values[i] - font1->numeric[xlfd_idx]);
5617	  int delta2 = abs (values[i] - font2->numeric[xlfd_idx]);
5618
5619	  if (xlfd_idx == XLFD_POINT_SIZE
5620	      && abs (delta1 - delta2) < FONT_POINT_SIZE_QUANTUM)
5621	    continue;
5622	  if (delta1 > delta2)
5623	    return 0;
5624	  else if (delta1 < delta2)
5625	    return 1;
5626	  else
5627	    {
5628	      /* The difference may be equal because, e.g., the face
5629		 specifies `italic' but we have only `regular' and
5630		 `oblique'.  Prefer `oblique' in this case.  */
5631	      if ((xlfd_idx == XLFD_WEIGHT || xlfd_idx == XLFD_SLANT)
5632		  && font1->numeric[xlfd_idx] > values[i]
5633		  && font2->numeric[xlfd_idx] < values[i])
5634		return 1;
5635	    }
5636	}
5637    }
5638
5639  if (avgwidth)
5640    {
5641      int delta1 = abs (avgwidth - font1->numeric[XLFD_AVGWIDTH]);
5642      int delta2 = abs (avgwidth - font2->numeric[XLFD_AVGWIDTH]);
5643      if (delta1 > delta2)
5644	return 0;
5645      else if (delta1 < delta2)
5646	return 1;
5647    }
5648
5649  return font1->registry_priority < font2->registry_priority;
5650}
5651
5652
5653/* Value is non-zero if FONT is an exact match for face attributes in
5654   SPECIFIED.  SPECIFIED is an array of face attribute values in font
5655   sort order.  AVGWIDTH, if non-zero, is an average width to compare
5656   with.  */
5657
5658static int
5659exact_face_match_p (specified, font, avgwidth)
5660     int *specified;
5661     struct font_name *font;
5662     int avgwidth;
5663{
5664  int i;
5665
5666  for (i = 0; i < DIM (font_sort_order); ++i)
5667    if (specified[i] != font->numeric[font_sort_order[i]])
5668      break;
5669
5670  return (i == DIM (font_sort_order)
5671	  && (avgwidth <= 0
5672	      || avgwidth == font->numeric[XLFD_AVGWIDTH]));
5673}
5674
5675
5676/* Value is the name of a scaled font, generated from scalable font
5677   FONT on frame F.  SPECIFIED_PT is the point-size to scale FONT to.
5678   Value is allocated from heap.  */
5679
5680static char *
5681build_scalable_font_name (f, font, specified_pt)
5682     struct frame *f;
5683     struct font_name *font;
5684     int specified_pt;
5685{
5686  char point_size[20], pixel_size[20];
5687  int pixel_value;
5688  double resy = FRAME_X_DISPLAY_INFO (f)->resy;
5689  double pt;
5690
5691  /* If scalable font is for a specific resolution, compute
5692     the point size we must specify from the resolution of
5693     the display and the specified resolution of the font.  */
5694  if (font->numeric[XLFD_RESY] != 0)
5695    {
5696      pt = resy / font->numeric[XLFD_RESY] * specified_pt + 0.5;
5697      pixel_value = font->numeric[XLFD_RESY] / (PT_PER_INCH * 10.0) * pt;
5698    }
5699  else
5700    {
5701      pt = specified_pt;
5702      pixel_value = resy / (PT_PER_INCH * 10.0) * pt;
5703    }
5704
5705  /* Set point size of the font.  */
5706  sprintf (point_size, "%d", (int) pt);
5707  font->fields[XLFD_POINT_SIZE] = point_size;
5708  font->numeric[XLFD_POINT_SIZE] = pt;
5709
5710  /* Set pixel size.  */
5711  sprintf (pixel_size, "%d", pixel_value);
5712  font->fields[XLFD_PIXEL_SIZE] = pixel_size;
5713  font->numeric[XLFD_PIXEL_SIZE] = pixel_value;
5714
5715  /* If font doesn't specify its resolution, use the
5716     resolution of the display.  */
5717  if (font->numeric[XLFD_RESY] == 0)
5718    {
5719      char buffer[20];
5720      sprintf (buffer, "%d", (int) resy);
5721      font->fields[XLFD_RESY] = buffer;
5722      font->numeric[XLFD_RESY] = resy;
5723    }
5724
5725  if (strcmp (font->fields[XLFD_RESX], "0") == 0)
5726    {
5727      char buffer[20];
5728      int resx = FRAME_X_DISPLAY_INFO (f)->resx;
5729      sprintf (buffer, "%d", resx);
5730      font->fields[XLFD_RESX] = buffer;
5731      font->numeric[XLFD_RESX] = resx;
5732    }
5733
5734  return build_font_name (font);
5735}
5736
5737
5738/* Value is non-zero if we are allowed to use scalable font FONT.  We
5739   can't run a Lisp function here since this function may be called
5740   with input blocked.  */
5741
5742static int
5743may_use_scalable_font_p (font)
5744     char *font;
5745{
5746  if (EQ (Vscalable_fonts_allowed, Qt))
5747    return 1;
5748  else if (CONSP (Vscalable_fonts_allowed))
5749    {
5750      Lisp_Object tail, regexp;
5751
5752      for (tail = Vscalable_fonts_allowed; CONSP (tail); tail = XCDR (tail))
5753	{
5754	  regexp = XCAR (tail);
5755	  if (STRINGP (regexp)
5756	      && fast_c_string_match_ignore_case (regexp, font) >= 0)
5757	    return 1;
5758	}
5759    }
5760
5761  return 0;
5762}
5763
5764
5765
5766/* Return the name of the best matching font for face attributes ATTRS
5767   in the array of font_name structures FONTS which contains NFONTS
5768   elements.  WIDTH_RATIO is a factor with which to multiply average
5769   widths if ATTRS specifies such a width.
5770
5771   Value is a font name which is allocated from the heap.  FONTS is
5772   freed by this function.  */
5773
5774static char *
5775best_matching_font (f, attrs, fonts, nfonts, width_ratio)
5776     struct frame *f;
5777     Lisp_Object *attrs;
5778     struct font_name *fonts;
5779     int nfonts;
5780     int width_ratio;
5781{
5782  char *font_name;
5783  struct font_name *best;
5784  int i, pt = 0;
5785  int specified[5];
5786  int exact_p, avgwidth;
5787
5788  if (nfonts == 0)
5789    return NULL;
5790
5791  /* Make specified font attributes available in `specified',
5792     indexed by sort order.  */
5793  for (i = 0; i < DIM (font_sort_order); ++i)
5794    {
5795      int xlfd_idx = font_sort_order[i];
5796
5797      if (xlfd_idx == XLFD_SWIDTH)
5798	specified[i] = face_numeric_swidth (attrs[LFACE_SWIDTH_INDEX]);
5799      else if (xlfd_idx == XLFD_POINT_SIZE)
5800	specified[i] = pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
5801      else if (xlfd_idx == XLFD_WEIGHT)
5802	specified[i] = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
5803      else if (xlfd_idx == XLFD_SLANT)
5804	specified[i] = face_numeric_slant (attrs[LFACE_SLANT_INDEX]);
5805      else
5806	abort ();
5807    }
5808
5809  avgwidth = (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX])
5810	      ? 0
5811	      : XFASTINT (attrs[LFACE_AVGWIDTH_INDEX]) * width_ratio);
5812
5813  exact_p = 0;
5814
5815  /* Start with the first non-scalable font in the list.  */
5816  for (i = 0; i < nfonts; ++i)
5817    if (!font_scalable_p (fonts + i))
5818      break;
5819
5820  /* Find the best match among the non-scalable fonts.  */
5821  if (i < nfonts)
5822    {
5823      best = fonts + i;
5824
5825      for (i = 1; i < nfonts; ++i)
5826	if (!font_scalable_p (fonts + i)
5827	    && better_font_p (specified, fonts + i, best, 1, avgwidth))
5828	  {
5829	    best = fonts + i;
5830
5831	    exact_p = exact_face_match_p (specified, best, avgwidth);
5832	    if (exact_p)
5833	      break;
5834	  }
5835
5836    }
5837  else
5838    best = NULL;
5839
5840  /* Unless we found an exact match among non-scalable fonts, see if
5841     we can find a better match among scalable fonts.  */
5842  if (!exact_p)
5843    {
5844      /* A scalable font is better if
5845
5846	 1. its weight, slant, swidth attributes are better, or.
5847
5848	 2. the best non-scalable font doesn't have the required
5849	 point size, and the scalable fonts weight, slant, swidth
5850	 isn't worse.  */
5851
5852      int non_scalable_has_exact_height_p;
5853
5854      if (best && best->numeric[XLFD_POINT_SIZE] == pt)
5855	non_scalable_has_exact_height_p = 1;
5856      else
5857	non_scalable_has_exact_height_p = 0;
5858
5859      for (i = 0; i < nfonts; ++i)
5860	if (font_scalable_p (fonts + i))
5861	  {
5862	    if (best == NULL
5863		|| better_font_p (specified, fonts + i, best, 0, 0)
5864		|| (!non_scalable_has_exact_height_p
5865		    && !better_font_p (specified, best, fonts + i, 0, 0)))
5866	      best = fonts + i;
5867	  }
5868    }
5869
5870  if (font_scalable_p (best))
5871    font_name = build_scalable_font_name (f, best, pt);
5872  else
5873    font_name = build_font_name (best);
5874
5875  /* Free font_name structures.  */
5876  free_font_names (fonts, nfonts);
5877
5878  return font_name;
5879}
5880
5881
5882/* Get a list of matching fonts on frame F, considering FAMILY
5883   and alternative font families from Vface_alternative_font_registry_alist.
5884
5885   FAMILY is the font family whose alternatives are considered.
5886
5887   REGISTRY, if a string, specifies a font registry and encoding to
5888   match.  A value of nil means include fonts of any registry and
5889   encoding.
5890
5891   Return in *FONTS a pointer to a vector of font_name structures for
5892   the fonts matched.  Value is the number of fonts found.  */
5893
5894static int
5895try_alternative_families (f, family, registry, fonts)
5896     struct frame *f;
5897     Lisp_Object family, registry;
5898     struct font_name **fonts;
5899{
5900  Lisp_Object alter;
5901  int nfonts = 0;
5902
5903  nfonts = font_list (f, Qnil, family, registry, fonts);
5904  if (nfonts == 0)
5905    {
5906      /* Try alternative font families.  */
5907      alter = Fassoc (family, Vface_alternative_font_family_alist);
5908      if (CONSP (alter))
5909	{
5910	  for (alter = XCDR (alter);
5911	       CONSP (alter) && nfonts == 0;
5912	       alter = XCDR (alter))
5913	    {
5914	      if (STRINGP (XCAR (alter)))
5915		nfonts = font_list (f, Qnil, XCAR (alter), registry, fonts);
5916	    }
5917	}
5918
5919      /* Try scalable fonts before giving up.  */
5920      if (nfonts == 0 && NILP (Vscalable_fonts_allowed))
5921	{
5922	  int count = BINDING_STACK_SIZE ();
5923	  specbind (Qscalable_fonts_allowed, Qt);
5924	  nfonts = try_alternative_families (f, family, registry, fonts);
5925	  unbind_to (count, Qnil);
5926	}
5927    }
5928  return nfonts;
5929}
5930
5931
5932/* Get a list of matching fonts on frame F.
5933
5934   FAMILY, if a string, specifies a font family derived from the fontset.
5935   It is only used if the face does not specify any family in ATTRS or
5936   if we cannot find any font of the face's family.
5937
5938   REGISTRY, if a string, specifies a font registry and encoding to
5939   match.  A value of nil means include fonts of any registry and
5940   encoding.
5941
5942   Return in *FONTS a pointer to a vector of font_name structures for
5943   the fonts matched.  Value is the number of fonts found.  */
5944
5945static int
5946try_font_list (f, attrs, family, registry, fonts)
5947     struct frame *f;
5948     Lisp_Object *attrs;
5949     Lisp_Object family, registry;
5950     struct font_name **fonts;
5951{
5952  int nfonts = 0;
5953  Lisp_Object face_family = attrs[LFACE_FAMILY_INDEX];
5954
5955  if (STRINGP (face_family))
5956    nfonts = try_alternative_families (f, face_family, registry, fonts);
5957
5958  if (nfonts == 0 && !NILP (family))
5959    nfonts = try_alternative_families (f, family, registry, fonts);
5960
5961  /* Try font family of the default face or "fixed".  */
5962  if (nfonts == 0)
5963    {
5964      struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5965      if (default_face)
5966	family = default_face->lface[LFACE_FAMILY_INDEX];
5967      else
5968	family = build_string ("fixed");
5969      nfonts = font_list (f, Qnil, family, registry, fonts);
5970    }
5971
5972  /* Try any family with the given registry.  */
5973  if (nfonts == 0)
5974    nfonts = font_list (f, Qnil, Qnil, registry, fonts);
5975
5976  return nfonts;
5977}
5978
5979
5980/* Return the fontset id of the base fontset name or alias name given
5981   by the fontset attribute of ATTRS.  Value is -1 if the fontset
5982   attribute of ATTRS doesn't name a fontset.  */
5983
5984static int
5985face_fontset (attrs)
5986     Lisp_Object *attrs;
5987{
5988  Lisp_Object name;
5989
5990  name = attrs[LFACE_FONT_INDEX];
5991  if (!STRINGP (name))
5992    return -1;
5993  return fs_query_fontset (name, 0);
5994}
5995
5996
5997/* Choose a name of font to use on frame F to display character C with
5998   Lisp face attributes specified by ATTRS.  The font name is
5999   determined by the font-related attributes in ATTRS and the name
6000   pattern for C in FONTSET.  Value is the font name which is
6001   allocated from the heap and must be freed by the caller, or NULL if
6002   we can get no information about the font name of C.  It is assured
6003   that we always get some information for a single byte
6004   character.  */
6005
6006static char *
6007choose_face_font (f, attrs, fontset, c)
6008     struct frame *f;
6009     Lisp_Object *attrs;
6010     int fontset, c;
6011{
6012  Lisp_Object pattern;
6013  char *font_name = NULL;
6014  struct font_name *fonts;
6015  int nfonts, width_ratio;
6016
6017  /* Get (foundry and) family name and registry (and encoding) name of
6018     a font for C.  */
6019  pattern = fontset_font_pattern (f, fontset, c);
6020  if (NILP (pattern))
6021    {
6022      xassert (!SINGLE_BYTE_CHAR_P (c));
6023      return NULL;
6024    }
6025
6026  /* If what we got is a name pattern, return it.  */
6027  if (STRINGP (pattern))
6028    return xstrdup (XSTRING (pattern)->data);
6029
6030  /* Get a list of fonts matching that pattern and choose the
6031     best match for the specified face attributes from it.  */
6032  nfonts = try_font_list (f, attrs, XCAR (pattern), XCDR (pattern), &fonts);
6033  width_ratio = (SINGLE_BYTE_CHAR_P (c)
6034		 ? 1
6035		 : CHARSET_WIDTH (CHAR_CHARSET (c)));
6036  font_name = best_matching_font (f, attrs, fonts, nfonts, width_ratio);
6037  return font_name;
6038}
6039
6040#endif /* HAVE_WINDOW_SYSTEM */
6041
6042
6043
6044/***********************************************************************
6045			   Face Realization
6046 ***********************************************************************/
6047
6048/* Realize basic faces on frame F.  Value is zero if frame parameters
6049   of F don't contain enough information needed to realize the default
6050   face.  */
6051
6052static int
6053realize_basic_faces (f)
6054     struct frame *f;
6055{
6056  int success_p = 0;
6057  int count = BINDING_STACK_SIZE ();
6058
6059  /* Block input here so that we won't be surprised by an X expose
6060     event, for instance, without having the faces set up.  */
6061  BLOCK_INPUT;
6062  specbind (Qscalable_fonts_allowed, Qt);
6063
6064  if (realize_default_face (f))
6065    {
6066      realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
6067      realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
6068      realize_named_face (f, Qfringe, BITMAP_AREA_FACE_ID);
6069      realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID);
6070      realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID);
6071      realize_named_face (f, Qborder, BORDER_FACE_ID);
6072      realize_named_face (f, Qcursor, CURSOR_FACE_ID);
6073      realize_named_face (f, Qmouse, MOUSE_FACE_ID);
6074      realize_named_face (f, Qmenu, MENU_FACE_ID);
6075
6076      /* Reflect changes in the `menu' face in menu bars.  */
6077      if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
6078	{
6079	  FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
6080#ifdef USE_X_TOOLKIT
6081	  x_update_menu_appearance (f);
6082#endif
6083	}
6084
6085      success_p = 1;
6086    }
6087
6088  unbind_to (count, Qnil);
6089  UNBLOCK_INPUT;
6090  return success_p;
6091}
6092
6093
6094/* Realize the default face on frame F.  If the face is not fully
6095   specified, make it fully-specified.  Attributes of the default face
6096   that are not explicitly specified are taken from frame parameters.  */
6097
6098static int
6099realize_default_face (f)
6100     struct frame *f;
6101{
6102  struct face_cache *c = FRAME_FACE_CACHE (f);
6103  Lisp_Object lface;
6104  Lisp_Object attrs[LFACE_VECTOR_SIZE];
6105  Lisp_Object frame_font;
6106  struct face *face;
6107
6108  /* If the `default' face is not yet known, create it.  */
6109  lface = lface_from_face_name (f, Qdefault, 0);
6110  if (NILP (lface))
6111    {
6112      Lisp_Object frame;
6113      XSETFRAME (frame, f);
6114      lface = Finternal_make_lisp_face (Qdefault, frame);
6115    }
6116
6117#ifdef HAVE_WINDOW_SYSTEM
6118  if (FRAME_WINDOW_P (f))
6119    {
6120      /* Set frame_font to the value of the `font' frame parameter.  */
6121      frame_font = Fassq (Qfont, f->param_alist);
6122      xassert (CONSP (frame_font) && STRINGP (XCDR (frame_font)));
6123      frame_font = XCDR (frame_font);
6124      set_lface_from_font_name (f, lface, frame_font, 1, 1);
6125    }
6126#endif /* HAVE_WINDOW_SYSTEM */
6127
6128  if (!FRAME_WINDOW_P (f))
6129    {
6130      LFACE_FAMILY (lface) = build_string ("default");
6131      LFACE_SWIDTH (lface) = Qnormal;
6132      LFACE_HEIGHT (lface) = make_number (1);
6133      LFACE_WEIGHT (lface) = Qnormal;
6134      LFACE_SLANT (lface) = Qnormal;
6135      LFACE_AVGWIDTH (lface) = Qunspecified;
6136    }
6137
6138  if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
6139    LFACE_UNDERLINE (lface) = Qnil;
6140
6141  if (UNSPECIFIEDP (LFACE_OVERLINE (lface)))
6142    LFACE_OVERLINE (lface) = Qnil;
6143
6144  if (UNSPECIFIEDP (LFACE_STRIKE_THROUGH (lface)))
6145    LFACE_STRIKE_THROUGH (lface) = Qnil;
6146
6147  if (UNSPECIFIEDP (LFACE_BOX (lface)))
6148    LFACE_BOX (lface) = Qnil;
6149
6150  if (UNSPECIFIEDP (LFACE_INVERSE (lface)))
6151    LFACE_INVERSE (lface) = Qnil;
6152
6153  if (UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
6154    {
6155      /* This function is called so early that colors are not yet
6156	 set in the frame parameter list.  */
6157      Lisp_Object color = Fassq (Qforeground_color, f->param_alist);
6158
6159      if (CONSP (color) && STRINGP (XCDR (color)))
6160	LFACE_FOREGROUND (lface) = XCDR (color);
6161      else if (FRAME_WINDOW_P (f))
6162	return 0;
6163      else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
6164	LFACE_FOREGROUND (lface) = build_string (unspecified_fg);
6165      else
6166	abort ();
6167    }
6168
6169  if (UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
6170    {
6171      /* This function is called so early that colors are not yet
6172	 set in the frame parameter list.  */
6173      Lisp_Object color = Fassq (Qbackground_color, f->param_alist);
6174      if (CONSP (color) && STRINGP (XCDR (color)))
6175	LFACE_BACKGROUND (lface) = XCDR (color);
6176      else if (FRAME_WINDOW_P (f))
6177	return 0;
6178      else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
6179	LFACE_BACKGROUND (lface) = build_string (unspecified_bg);
6180      else
6181	abort ();
6182    }
6183
6184  if (UNSPECIFIEDP (LFACE_STIPPLE (lface)))
6185    LFACE_STIPPLE (lface) = Qnil;
6186
6187  /* Realize the face; it must be fully-specified now.  */
6188  xassert (lface_fully_specified_p (XVECTOR (lface)->contents));
6189  check_lface (lface);
6190  bcopy (XVECTOR (lface)->contents, attrs, sizeof attrs);
6191  face = realize_face (c, attrs, 0, NULL, DEFAULT_FACE_ID);
6192  return 1;
6193}
6194
6195
6196/* Realize basic faces other than the default face in face cache C.
6197   SYMBOL is the face name, ID is the face id the realized face must
6198   have.  The default face must have been realized already.  */
6199
6200static void
6201realize_named_face (f, symbol, id)
6202     struct frame *f;
6203     Lisp_Object symbol;
6204     int id;
6205{
6206  struct face_cache *c = FRAME_FACE_CACHE (f);
6207  Lisp_Object lface = lface_from_face_name (f, symbol, 0);
6208  Lisp_Object attrs[LFACE_VECTOR_SIZE];
6209  Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
6210  struct face *new_face;
6211
6212  /* The default face must exist and be fully specified.  */
6213  get_lface_attributes (f, Qdefault, attrs, 1);
6214  check_lface_attrs (attrs);
6215  xassert (lface_fully_specified_p (attrs));
6216
6217  /* If SYMBOL isn't know as a face, create it.  */
6218  if (NILP (lface))
6219    {
6220      Lisp_Object frame;
6221      XSETFRAME (frame, f);
6222      lface = Finternal_make_lisp_face (symbol, frame);
6223    }
6224
6225  /* Merge SYMBOL's face with the default face.  */
6226  get_lface_attributes (f, symbol, symbol_attrs, 1);
6227  merge_face_vectors (f, symbol_attrs, attrs, Qnil);
6228
6229  /* Realize the face.  */
6230  new_face = realize_face (c, attrs, 0, NULL, id);
6231}
6232
6233
6234/* Realize the fully-specified face with attributes ATTRS in face
6235   cache CACHE for character C.  If C is a multibyte character,
6236   BASE_FACE is a face that has the same attributes.  Otherwise,
6237   BASE_FACE is ignored.  If FORMER_FACE_ID is non-negative, it is an
6238   ID of face to remove before caching the new face.  Value is a
6239   pointer to the newly created realized face.  */
6240
6241static struct face *
6242realize_face (cache, attrs, c, base_face, former_face_id)
6243     struct face_cache *cache;
6244     Lisp_Object *attrs;
6245     int c;
6246     struct face *base_face;
6247     int former_face_id;
6248{
6249  struct face *face;
6250
6251  /* LFACE must be fully specified.  */
6252  xassert (cache != NULL);
6253  check_lface_attrs (attrs);
6254
6255  if (former_face_id >= 0 && cache->used > former_face_id)
6256    {
6257      /* Remove the former face.  */
6258      struct face *former_face = cache->faces_by_id[former_face_id];
6259      uncache_face (cache, former_face);
6260      free_realized_face (cache->f, former_face);
6261    }
6262
6263  if (FRAME_WINDOW_P (cache->f))
6264    face = realize_x_face (cache, attrs, c, base_face);
6265  else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
6266    face = realize_tty_face (cache, attrs, c);
6267  else
6268    abort ();
6269
6270  /* Insert the new face.  */
6271  cache_face (cache, face, lface_hash (attrs));
6272#ifdef HAVE_WINDOW_SYSTEM
6273  if (FRAME_WINDOW_P (cache->f) && face->font == NULL)
6274    load_face_font (cache->f, face, c);
6275#endif  /* HAVE_WINDOW_SYSTEM */
6276  return face;
6277}
6278
6279
6280/* Realize the fully-specified face with attributes ATTRS in face
6281   cache CACHE for character C.  Do it for X frame CACHE->f.  If C is
6282   a multibyte character, BASE_FACE is a face that has the same
6283   attributes.  Otherwise, BASE_FACE is ignored.  If the new face
6284   doesn't share font with the default face, a fontname is allocated
6285   from the heap and set in `font_name' of the new face, but it is not
6286   yet loaded here.  Value is a pointer to the newly created realized
6287   face.  */
6288
6289static struct face *
6290realize_x_face (cache, attrs, c, base_face)
6291     struct face_cache *cache;
6292     Lisp_Object *attrs;
6293     int c;
6294     struct face *base_face;
6295{
6296#ifdef HAVE_WINDOW_SYSTEM
6297  struct face *face, *default_face;
6298  struct frame *f;
6299  Lisp_Object stipple, overline, strike_through, box;
6300
6301  xassert (FRAME_WINDOW_P (cache->f));
6302  xassert (SINGLE_BYTE_CHAR_P (c)
6303	   || base_face);
6304
6305  /* Allocate a new realized face.  */
6306  face = make_realized_face (attrs);
6307
6308  f = cache->f;
6309
6310  /* If C is a multibyte character, we share all face attirbutes with
6311     BASE_FACE including the realized fontset.  But, we must load a
6312     different font.  */
6313  if (!SINGLE_BYTE_CHAR_P (c))
6314    {
6315      bcopy (base_face, face, sizeof *face);
6316      face->gc = 0;
6317
6318      /* Don't try to free the colors copied bitwise from BASE_FACE.  */
6319      face->colors_copied_bitwise_p = 1;
6320
6321      /* to force realize_face to load font */
6322      face->font = NULL;
6323      return face;
6324    }
6325
6326  /* Now we are realizing a face for ASCII (and unibyte) characters.  */
6327
6328  /* Determine the font to use.  Most of the time, the font will be
6329     the same as the font of the default face, so try that first.  */
6330  default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6331  if (default_face
6332      && FACE_SUITABLE_FOR_CHAR_P (default_face, c)
6333      && lface_same_font_attributes_p (default_face->lface, attrs))
6334    {
6335      face->font = default_face->font;
6336      face->fontset = default_face->fontset;
6337      face->font_info_id = default_face->font_info_id;
6338      face->font_name = default_face->font_name;
6339      face->ascii_face = face;
6340
6341      /* But, as we can't share the fontset, make a new realized
6342	 fontset that has the same base fontset as of the default
6343	 face.  */
6344      face->fontset
6345	= make_fontset_for_ascii_face (f, default_face->fontset);
6346    }
6347  else
6348    {
6349      /* If the face attribute ATTRS specifies a fontset, use it as
6350	 the base of a new realized fontset.  Otherwise, use the same
6351	 base fontset as of the default face.  The base determines
6352	 registry and encoding of a font.  It may also determine
6353	 foundry and family.  The other fields of font name pattern
6354	 are constructed from ATTRS.  */
6355      int fontset = face_fontset (attrs);
6356
6357      if ((fontset == -1) && default_face)
6358	fontset = default_face->fontset;
6359      face->fontset = make_fontset_for_ascii_face (f, fontset);
6360      face->font = NULL;	/* to force realize_face to load font */
6361
6362#ifdef macintosh
6363      /* Load the font if it is specified in ATTRS.  This fixes
6364         changing frame font on the Mac.  */
6365      if (STRINGP (attrs[LFACE_FONT_INDEX]))
6366        {
6367          struct font_info *font_info =
6368            FS_LOAD_FONT (f, 0, XSTRING (attrs[LFACE_FONT_INDEX])->data, -1);
6369          if (font_info)
6370            face->font = font_info->font;
6371        }
6372#endif
6373    }
6374
6375  /* Load colors, and set remaining attributes.  */
6376
6377  load_face_colors (f, face, attrs);
6378
6379  /* Set up box.  */
6380  box = attrs[LFACE_BOX_INDEX];
6381  if (STRINGP (box))
6382    {
6383      /* A simple box of line width 1 drawn in color given by
6384	 the string.  */
6385      face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
6386				    LFACE_BOX_INDEX);
6387      face->box = FACE_SIMPLE_BOX;
6388      face->box_line_width = 1;
6389    }
6390  else if (INTEGERP (box))
6391    {
6392      /* Simple box of specified line width in foreground color of the
6393         face.  */
6394      xassert (XINT (box) != 0);
6395      face->box = FACE_SIMPLE_BOX;
6396      face->box_line_width = XINT (box);
6397      face->box_color = face->foreground;
6398      face->box_color_defaulted_p = 1;
6399    }
6400  else if (CONSP (box))
6401    {
6402      /* `(:width WIDTH :color COLOR :shadow SHADOW)'.  SHADOW
6403	 being one of `raised' or `sunken'.  */
6404      face->box = FACE_SIMPLE_BOX;
6405      face->box_color = face->foreground;
6406      face->box_color_defaulted_p = 1;
6407      face->box_line_width = 1;
6408
6409      while (CONSP (box))
6410	{
6411	  Lisp_Object keyword, value;
6412
6413	  keyword = XCAR (box);
6414	  box = XCDR (box);
6415
6416	  if (!CONSP (box))
6417	    break;
6418	  value = XCAR (box);
6419	  box = XCDR (box);
6420
6421	  if (EQ (keyword, QCline_width))
6422	    {
6423	      if (INTEGERP (value) && XINT (value) != 0)
6424		face->box_line_width = XINT (value);
6425	    }
6426	  else if (EQ (keyword, QCcolor))
6427	    {
6428	      if (STRINGP (value))
6429		{
6430		  face->box_color = load_color (f, face, value,
6431						LFACE_BOX_INDEX);
6432		  face->use_box_color_for_shadows_p = 1;
6433		}
6434	    }
6435	  else if (EQ (keyword, QCstyle))
6436	    {
6437	      if (EQ (value, Qreleased_button))
6438		face->box = FACE_RAISED_BOX;
6439	      else if (EQ (value, Qpressed_button))
6440		face->box = FACE_SUNKEN_BOX;
6441	    }
6442	}
6443    }
6444
6445  /* Text underline, overline, strike-through.  */
6446
6447  if (EQ (attrs[LFACE_UNDERLINE_INDEX], Qt))
6448    {
6449      /* Use default color (same as foreground color).  */
6450      face->underline_p = 1;
6451      face->underline_defaulted_p = 1;
6452      face->underline_color = 0;
6453    }
6454  else if (STRINGP (attrs[LFACE_UNDERLINE_INDEX]))
6455    {
6456      /* Use specified color.  */
6457      face->underline_p = 1;
6458      face->underline_defaulted_p = 0;
6459      face->underline_color
6460	= load_color (f, face, attrs[LFACE_UNDERLINE_INDEX],
6461		      LFACE_UNDERLINE_INDEX);
6462    }
6463  else if (NILP (attrs[LFACE_UNDERLINE_INDEX]))
6464    {
6465      face->underline_p = 0;
6466      face->underline_defaulted_p = 0;
6467      face->underline_color = 0;
6468    }
6469
6470  overline = attrs[LFACE_OVERLINE_INDEX];
6471  if (STRINGP (overline))
6472    {
6473      face->overline_color
6474	= load_color (f, face, attrs[LFACE_OVERLINE_INDEX],
6475		      LFACE_OVERLINE_INDEX);
6476      face->overline_p = 1;
6477    }
6478  else if (EQ (overline, Qt))
6479    {
6480      face->overline_color = face->foreground;
6481      face->overline_color_defaulted_p = 1;
6482      face->overline_p = 1;
6483    }
6484
6485  strike_through = attrs[LFACE_STRIKE_THROUGH_INDEX];
6486  if (STRINGP (strike_through))
6487    {
6488      face->strike_through_color
6489	= load_color (f, face, attrs[LFACE_STRIKE_THROUGH_INDEX],
6490		      LFACE_STRIKE_THROUGH_INDEX);
6491      face->strike_through_p = 1;
6492    }
6493  else if (EQ (strike_through, Qt))
6494    {
6495      face->strike_through_color = face->foreground;
6496      face->strike_through_color_defaulted_p = 1;
6497      face->strike_through_p = 1;
6498    }
6499
6500  stipple = attrs[LFACE_STIPPLE_INDEX];
6501  if (!NILP (stipple))
6502    face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
6503
6504  xassert (FACE_SUITABLE_FOR_CHAR_P (face, c));
6505  return face;
6506#endif /* HAVE_WINDOW_SYSTEM */
6507}
6508
6509
6510/* Map a specified color of face FACE on frame F to a tty color index.
6511   IDX is either LFACE_FOREGROUND_INDEX or LFACE_BACKGROUND_INDEX, and
6512   specifies which color to map.  Set *DEFAULTED to 1 if mapping to the
6513   default foreground/background colors.  */
6514
6515static void
6516map_tty_color (f, face, idx, defaulted)
6517     struct frame *f;
6518     struct face *face;
6519     enum lface_attribute_index idx;
6520     int *defaulted;
6521{
6522  Lisp_Object frame, color, def;
6523  int foreground_p = idx == LFACE_FOREGROUND_INDEX;
6524  unsigned long default_pixel, default_other_pixel, pixel;
6525
6526  xassert (idx == LFACE_FOREGROUND_INDEX || idx == LFACE_BACKGROUND_INDEX);
6527
6528  if (foreground_p)
6529    {
6530      pixel = default_pixel = FACE_TTY_DEFAULT_FG_COLOR;
6531      default_other_pixel = FACE_TTY_DEFAULT_BG_COLOR;
6532    }
6533  else
6534    {
6535      pixel = default_pixel = FACE_TTY_DEFAULT_BG_COLOR;
6536      default_other_pixel = FACE_TTY_DEFAULT_FG_COLOR;
6537    }
6538
6539  XSETFRAME (frame, f);
6540  color = face->lface[idx];
6541
6542  if (STRINGP (color)
6543      && XSTRING (color)->size
6544      && CONSP (Vtty_defined_color_alist)
6545      && (def = assq_no_quit (color, call1 (Qtty_color_alist, frame)),
6546	  CONSP (def)))
6547    {
6548      /* Associations in tty-defined-color-alist are of the form
6549	 (NAME INDEX R G B).  We need the INDEX part.  */
6550      pixel = XINT (XCAR (XCDR (def)));
6551    }
6552
6553  if (pixel == default_pixel && STRINGP (color))
6554    {
6555      pixel = load_color (f, face, color, idx);
6556
6557#if defined (MSDOS) || defined (WINDOWSNT)
6558      /* If the foreground of the default face is the default color,
6559	 use the foreground color defined by the frame.  */
6560#ifdef MSDOS
6561      if (FRAME_MSDOS_P (f))
6562	{
6563#endif /* MSDOS */
6564	  if (pixel == default_pixel
6565	      || pixel == FACE_TTY_DEFAULT_COLOR)
6566	    {
6567	      if (foreground_p)
6568		pixel = FRAME_FOREGROUND_PIXEL (f);
6569	      else
6570		pixel = FRAME_BACKGROUND_PIXEL (f);
6571	      face->lface[idx] = tty_color_name (f, pixel);
6572	      *defaulted = 1;
6573	    }
6574	  else if (pixel == default_other_pixel)
6575	    {
6576	      if (foreground_p)
6577		pixel = FRAME_BACKGROUND_PIXEL (f);
6578	      else
6579		pixel = FRAME_FOREGROUND_PIXEL (f);
6580	      face->lface[idx] = tty_color_name (f, pixel);
6581	      *defaulted = 1;
6582	    }
6583#ifdef MSDOS
6584	}
6585#endif
6586#endif /* MSDOS or WINDOWSNT */
6587    }
6588
6589  if (foreground_p)
6590    face->foreground = pixel;
6591  else
6592    face->background = pixel;
6593}
6594
6595
6596/* Realize the fully-specified face with attributes ATTRS in face
6597   cache CACHE for character C.  Do it for TTY frame CACHE->f.  Value is a
6598   pointer to the newly created realized face.  */
6599
6600static struct face *
6601realize_tty_face (cache, attrs, c)
6602     struct face_cache *cache;
6603     Lisp_Object *attrs;
6604     int c;
6605{
6606  struct face *face;
6607  int weight, slant;
6608  int face_colors_defaulted = 0;
6609  struct frame *f = cache->f;
6610
6611  /* Frame must be a termcap frame.  */
6612  xassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f));
6613
6614  /* Allocate a new realized face.  */
6615  face = make_realized_face (attrs);
6616  face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty";
6617
6618  /* Map face attributes to TTY appearances.  We map slant to
6619     dimmed text because we want italic text to appear differently
6620     and because dimmed text is probably used infrequently.  */
6621  weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
6622  slant = face_numeric_slant (attrs[LFACE_SLANT_INDEX]);
6623
6624  if (weight > XLFD_WEIGHT_MEDIUM)
6625    face->tty_bold_p = 1;
6626  if (weight < XLFD_WEIGHT_MEDIUM || slant != XLFD_SLANT_ROMAN)
6627    face->tty_dim_p = 1;
6628  if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
6629    face->tty_underline_p = 1;
6630  if (!NILP (attrs[LFACE_INVERSE_INDEX]))
6631    face->tty_reverse_p = 1;
6632
6633  /* Map color names to color indices.  */
6634  map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
6635  map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted);
6636
6637  /* Swap colors if face is inverse-video.  If the colors are taken
6638     from the frame colors, they are already inverted, since the
6639     frame-creation function calls x-handle-reverse-video.  */
6640  if (face->tty_reverse_p && !face_colors_defaulted)
6641    {
6642      unsigned long tem = face->foreground;
6643      face->foreground = face->background;
6644      face->background = tem;
6645    }
6646
6647  if (tty_suppress_bold_inverse_default_colors_p
6648      && face->tty_bold_p
6649      && face->background == FACE_TTY_DEFAULT_FG_COLOR
6650      && face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
6651    face->tty_bold_p = 0;
6652
6653  return face;
6654}
6655
6656
6657DEFUN ("tty-suppress-bold-inverse-default-colors",
6658       Ftty_suppress_bold_inverse_default_colors,
6659       Stty_suppress_bold_inverse_default_colors, 1, 1, 0,
6660  "Suppress/allow boldness of faces with inverse default colors.\n\
6661SUPPRESS non-nil means suppress it.\n\
6662This affects bold faces on TTYs whose foreground is the default background\n\
6663color of the display and whose background is the default foreground color.\n\
6664For such faces, the bold face attribute is ignored if this variable\n\
6665is non-nil.")
6666  (suppress)
6667     Lisp_Object suppress;
6668{
6669  tty_suppress_bold_inverse_default_colors_p = !NILP (suppress);
6670  ++face_change_count;
6671  return suppress;
6672}
6673
6674
6675
6676/***********************************************************************
6677			   Computing Faces
6678 ***********************************************************************/
6679
6680/* Return the ID of the face to use to display character CH with face
6681   property PROP on frame F in current_buffer.  */
6682
6683int
6684compute_char_face (f, ch, prop)
6685     struct frame *f;
6686     int ch;
6687     Lisp_Object prop;
6688{
6689  int face_id;
6690
6691  if (NILP (current_buffer->enable_multibyte_characters))
6692    ch = 0;
6693
6694  if (NILP (prop))
6695    {
6696      struct face *face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6697      face_id = FACE_FOR_CHAR (f, face, ch);
6698    }
6699  else
6700    {
6701      Lisp_Object attrs[LFACE_VECTOR_SIZE];
6702      struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6703      bcopy (default_face->lface, attrs, sizeof attrs);
6704      merge_face_vector_with_property (f, attrs, prop);
6705      face_id = lookup_face (f, attrs, ch, NULL);
6706    }
6707
6708  return face_id;
6709}
6710
6711
6712/* Return the face ID associated with buffer position POS for
6713   displaying ASCII characters.  Return in *ENDPTR the position at
6714   which a different face is needed, as far as text properties and
6715   overlays are concerned.  W is a window displaying current_buffer.
6716
6717   REGION_BEG, REGION_END delimit the region, so it can be
6718   highlighted.
6719
6720   LIMIT is a position not to scan beyond.  That is to limit the time
6721   this function can take.
6722
6723   If MOUSE is non-zero, use the character's mouse-face, not its face.
6724
6725   The face returned is suitable for displaying ASCII characters.  */
6726
6727int
6728face_at_buffer_position (w, pos, region_beg, region_end,
6729			 endptr, limit, mouse)
6730     struct window *w;
6731     int pos;
6732     int region_beg, region_end;
6733     int *endptr;
6734     int limit;
6735     int mouse;
6736{
6737  struct frame *f = XFRAME (w->frame);
6738  Lisp_Object attrs[LFACE_VECTOR_SIZE];
6739  Lisp_Object prop, position;
6740  int i, noverlays;
6741  Lisp_Object *overlay_vec;
6742  Lisp_Object frame;
6743  int endpos;
6744  Lisp_Object propname = mouse ? Qmouse_face : Qface;
6745  Lisp_Object limit1, end;
6746  struct face *default_face;
6747
6748  /* W must display the current buffer.  We could write this function
6749     to use the frame and buffer of W, but right now it doesn't.  */
6750  /* xassert (XBUFFER (w->buffer) == current_buffer); */
6751
6752  XSETFRAME (frame, f);
6753  XSETFASTINT (position, pos);
6754
6755  endpos = ZV;
6756  if (pos < region_beg && region_beg < endpos)
6757    endpos = region_beg;
6758
6759  /* Get the `face' or `mouse_face' text property at POS, and
6760     determine the next position at which the property changes.  */
6761  prop = Fget_text_property (position, propname, w->buffer);
6762  XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6763  end = Fnext_single_property_change (position, propname, w->buffer, limit1);
6764  if (INTEGERP (end))
6765    endpos = XINT (end);
6766
6767  /* Look at properties from overlays.  */
6768  {
6769    int next_overlay;
6770    int len;
6771
6772    /* First try with room for 40 overlays.  */
6773    len = 40;
6774    overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6775    noverlays = overlays_at (pos, 0, &overlay_vec, &len,
6776			     &next_overlay, NULL, 0);
6777
6778    /* If there are more than 40, make enough space for all, and try
6779       again.  */
6780    if (noverlays > len)
6781      {
6782	len = noverlays;
6783	overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6784	noverlays = overlays_at (pos, 0, &overlay_vec, &len,
6785				 &next_overlay, NULL, 0);
6786      }
6787
6788    if (next_overlay < endpos)
6789      endpos = next_overlay;
6790  }
6791
6792  *endptr = endpos;
6793
6794  default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6795
6796  /* Optimize common cases where we can use the default face.  */
6797  if (noverlays == 0
6798      && NILP (prop)
6799      && !(pos >= region_beg && pos < region_end))
6800    return DEFAULT_FACE_ID;
6801
6802  /* Begin with attributes from the default face.  */
6803  bcopy (default_face->lface, attrs, sizeof attrs);
6804
6805  /* Merge in attributes specified via text properties.  */
6806  if (!NILP (prop))
6807    merge_face_vector_with_property (f, attrs, prop);
6808
6809  /* Now merge the overlay data.  */
6810  noverlays = sort_overlays (overlay_vec, noverlays, w);
6811  for (i = 0; i < noverlays; i++)
6812    {
6813      Lisp_Object oend;
6814      int oendpos;
6815
6816      prop = Foverlay_get (overlay_vec[i], propname);
6817      if (!NILP (prop))
6818	merge_face_vector_with_property (f, attrs, prop);
6819
6820      oend = OVERLAY_END (overlay_vec[i]);
6821      oendpos = OVERLAY_POSITION (oend);
6822      if (oendpos < endpos)
6823	endpos = oendpos;
6824    }
6825
6826  /* If in the region, merge in the region face.  */
6827  if (pos >= region_beg && pos < region_end)
6828    {
6829      Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
6830      merge_face_vectors (f, XVECTOR (region_face)->contents, attrs, Qnil);
6831
6832      if (region_end < endpos)
6833	endpos = region_end;
6834    }
6835
6836  *endptr = endpos;
6837
6838  /* Look up a realized face with the given face attributes,
6839     or realize a new one for ASCII characters.  */
6840  return lookup_face (f, attrs, 0, NULL);
6841}
6842
6843
6844/* Compute the face at character position POS in Lisp string STRING on
6845   window W, for ASCII characters.
6846
6847   If STRING is an overlay string, it comes from position BUFPOS in
6848   current_buffer, otherwise BUFPOS is zero to indicate that STRING is
6849   not an overlay string.  W must display the current buffer.
6850   REGION_BEG and REGION_END give the start and end positions of the
6851   region; both are -1 if no region is visible.
6852
6853   BASE_FACE_ID is the id of a face to merge with.  For strings coming
6854   from overlays or the `display' property it is the face at BUFPOS.
6855
6856   If MOUSE_P is non-zero, use the character's mouse-face, not its face.
6857
6858   Set *ENDPTR to the next position where to check for faces in
6859   STRING; -1 if the face is constant from POS to the end of the
6860   string.
6861
6862   Value is the id of the face to use.  The face returned is suitable
6863   for displaying ASCII characters.  */
6864
6865int
6866face_at_string_position (w, string, pos, bufpos, region_beg,
6867			 region_end, endptr, base_face_id, mouse_p)
6868     struct window *w;
6869     Lisp_Object string;
6870     int pos, bufpos;
6871     int region_beg, region_end;
6872     int *endptr;
6873     enum face_id base_face_id;
6874     int mouse_p;
6875{
6876  Lisp_Object prop, position, end, limit;
6877  struct frame *f = XFRAME (WINDOW_FRAME (w));
6878  Lisp_Object attrs[LFACE_VECTOR_SIZE];
6879  struct face *base_face;
6880  int multibyte_p = STRING_MULTIBYTE (string);
6881  Lisp_Object prop_name = mouse_p ? Qmouse_face : Qface;
6882
6883  /* Get the value of the face property at the current position within
6884     STRING.  Value is nil if there is no face property.  */
6885  XSETFASTINT (position, pos);
6886  prop = Fget_text_property (position, prop_name, string);
6887
6888  /* Get the next position at which to check for faces.  Value of end
6889     is nil if face is constant all the way to the end of the string.
6890     Otherwise it is a string position where to check faces next.
6891     Limit is the maximum position up to which to check for property
6892     changes in Fnext_single_property_change.  Strings are usually
6893     short, so set the limit to the end of the string.  */
6894  XSETFASTINT (limit, XSTRING (string)->size);
6895  end = Fnext_single_property_change (position, prop_name, string, limit);
6896  if (INTEGERP (end))
6897    *endptr = XFASTINT (end);
6898  else
6899    *endptr = -1;
6900
6901  base_face = FACE_FROM_ID (f, base_face_id);
6902  xassert (base_face);
6903
6904  /* Optimize the default case that there is no face property and we
6905     are not in the region.  */
6906  if (NILP (prop)
6907      && (base_face_id != DEFAULT_FACE_ID
6908	  /* BUFPOS <= 0 means STRING is not an overlay string, so
6909	     that the region doesn't have to be taken into account.  */
6910	  || bufpos <= 0
6911	  || bufpos < region_beg
6912	  || bufpos >= region_end)
6913      && (multibyte_p
6914	  /* We can't realize faces for different charsets differently
6915	     if we don't have fonts, so we can stop here if not working
6916	     on a window-system frame.  */
6917	  || !FRAME_WINDOW_P (f)
6918	  || FACE_SUITABLE_FOR_CHAR_P (base_face, 0)))
6919    return base_face->id;
6920
6921  /* Begin with attributes from the base face.  */
6922  bcopy (base_face->lface, attrs, sizeof attrs);
6923
6924  /* Merge in attributes specified via text properties.  */
6925  if (!NILP (prop))
6926    merge_face_vector_with_property (f, attrs, prop);
6927
6928  /* If in the region, merge in the region face.  */
6929  if (bufpos
6930      && bufpos >= region_beg
6931      && bufpos < region_end)
6932    {
6933      Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
6934      merge_face_vectors (f, XVECTOR (region_face)->contents, attrs, Qnil);
6935    }
6936
6937  /* Look up a realized face with the given face attributes,
6938     or realize a new one for ASCII characters.  */
6939  return lookup_face (f, attrs, 0, NULL);
6940}
6941
6942
6943
6944/***********************************************************************
6945				Tests
6946 ***********************************************************************/
6947
6948#if GLYPH_DEBUG
6949
6950/* Print the contents of the realized face FACE to stderr.  */
6951
6952static void
6953dump_realized_face (face)
6954     struct face *face;
6955{
6956  fprintf (stderr, "ID: %d\n", face->id);
6957#ifdef HAVE_X_WINDOWS
6958  fprintf (stderr, "gc: %d\n", (int) face->gc);
6959#endif
6960  fprintf (stderr, "foreground: 0x%lx (%s)\n",
6961	   face->foreground,
6962	   XSTRING (face->lface[LFACE_FOREGROUND_INDEX])->data);
6963  fprintf (stderr, "background: 0x%lx (%s)\n",
6964	   face->background,
6965	   XSTRING (face->lface[LFACE_BACKGROUND_INDEX])->data);
6966  fprintf (stderr, "font_name: %s (%s)\n",
6967	   face->font_name,
6968	   XSTRING (face->lface[LFACE_FAMILY_INDEX])->data);
6969#ifdef HAVE_X_WINDOWS
6970  fprintf (stderr, "font = %p\n", face->font);
6971#endif
6972  fprintf (stderr, "font_info_id = %d\n", face->font_info_id);
6973  fprintf (stderr, "fontset: %d\n", face->fontset);
6974  fprintf (stderr, "underline: %d (%s)\n",
6975	   face->underline_p,
6976	   XSTRING (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))->data);
6977  fprintf (stderr, "hash: %d\n", face->hash);
6978  fprintf (stderr, "charset: %d\n", face->charset);
6979}
6980
6981
6982DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, "")
6983   (n)
6984     Lisp_Object n;
6985{
6986  if (NILP (n))
6987    {
6988      int i;
6989
6990      fprintf (stderr, "font selection order: ");
6991      for (i = 0; i < DIM (font_sort_order); ++i)
6992	fprintf (stderr, "%d ", font_sort_order[i]);
6993      fprintf (stderr, "\n");
6994
6995      fprintf (stderr, "alternative fonts: ");
6996      debug_print (Vface_alternative_font_family_alist);
6997      fprintf (stderr, "\n");
6998
6999      for (i = 0; i < FRAME_FACE_CACHE (SELECTED_FRAME ())->used; ++i)
7000	Fdump_face (make_number (i));
7001    }
7002  else
7003    {
7004      struct face *face;
7005      CHECK_NUMBER (n, 0);
7006      face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
7007      if (face == NULL)
7008	error ("Not a valid face");
7009      dump_realized_face (face);
7010    }
7011
7012  return Qnil;
7013}
7014
7015
7016DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
7017       0, 0, 0, "")
7018  ()
7019{
7020  fprintf (stderr, "number of colors = %d\n", ncolors_allocated);
7021  fprintf (stderr, "number of pixmaps = %d\n", npixmaps_allocated);
7022  fprintf (stderr, "number of GCs = %d\n", ngcs);
7023  return Qnil;
7024}
7025
7026#endif /* GLYPH_DEBUG != 0 */
7027
7028
7029
7030/***********************************************************************
7031			    Initialization
7032 ***********************************************************************/
7033
7034void
7035syms_of_xfaces ()
7036{
7037  Qface = intern ("face");
7038  staticpro (&Qface);
7039  Qbitmap_spec_p = intern ("bitmap-spec-p");
7040  staticpro (&Qbitmap_spec_p);
7041  Qframe_update_face_colors = intern ("frame-update-face-colors");
7042  staticpro (&Qframe_update_face_colors);
7043
7044  /* Lisp face attribute keywords.  */
7045  QCfamily = intern (":family");
7046  staticpro (&QCfamily);
7047  QCheight = intern (":height");
7048  staticpro (&QCheight);
7049  QCweight = intern (":weight");
7050  staticpro (&QCweight);
7051  QCslant = intern (":slant");
7052  staticpro (&QCslant);
7053  QCunderline = intern (":underline");
7054  staticpro (&QCunderline);
7055  QCinverse_video = intern (":inverse-video");
7056  staticpro (&QCinverse_video);
7057  QCreverse_video = intern (":reverse-video");
7058  staticpro (&QCreverse_video);
7059  QCforeground = intern (":foreground");
7060  staticpro (&QCforeground);
7061  QCbackground = intern (":background");
7062  staticpro (&QCbackground);
7063  QCstipple = intern (":stipple");;
7064  staticpro (&QCstipple);
7065  QCwidth = intern (":width");
7066  staticpro (&QCwidth);
7067  QCfont = intern (":font");
7068  staticpro (&QCfont);
7069  QCbold = intern (":bold");
7070  staticpro (&QCbold);
7071  QCitalic = intern (":italic");
7072  staticpro (&QCitalic);
7073  QCoverline = intern (":overline");
7074  staticpro (&QCoverline);
7075  QCstrike_through = intern (":strike-through");
7076  staticpro (&QCstrike_through);
7077  QCbox = intern (":box");
7078  staticpro (&QCbox);
7079  QCinherit = intern (":inherit");
7080  staticpro (&QCinherit);
7081
7082  /* Symbols used for Lisp face attribute values.  */
7083  QCcolor = intern (":color");
7084  staticpro (&QCcolor);
7085  QCline_width = intern (":line-width");
7086  staticpro (&QCline_width);
7087  QCstyle = intern (":style");
7088  staticpro (&QCstyle);
7089  Qreleased_button = intern ("released-button");
7090  staticpro (&Qreleased_button);
7091  Qpressed_button = intern ("pressed-button");
7092  staticpro (&Qpressed_button);
7093  Qnormal = intern ("normal");
7094  staticpro (&Qnormal);
7095  Qultra_light = intern ("ultra-light");
7096  staticpro (&Qultra_light);
7097  Qextra_light = intern ("extra-light");
7098  staticpro (&Qextra_light);
7099  Qlight = intern ("light");
7100  staticpro (&Qlight);
7101  Qsemi_light = intern ("semi-light");
7102  staticpro (&Qsemi_light);
7103  Qsemi_bold = intern ("semi-bold");
7104  staticpro (&Qsemi_bold);
7105  Qbold = intern ("bold");
7106  staticpro (&Qbold);
7107  Qextra_bold = intern ("extra-bold");
7108  staticpro (&Qextra_bold);
7109  Qultra_bold = intern ("ultra-bold");
7110  staticpro (&Qultra_bold);
7111  Qoblique = intern ("oblique");
7112  staticpro (&Qoblique);
7113  Qitalic = intern ("italic");
7114  staticpro (&Qitalic);
7115  Qreverse_oblique = intern ("reverse-oblique");
7116  staticpro (&Qreverse_oblique);
7117  Qreverse_italic = intern ("reverse-italic");
7118  staticpro (&Qreverse_italic);
7119  Qultra_condensed = intern ("ultra-condensed");
7120  staticpro (&Qultra_condensed);
7121  Qextra_condensed = intern ("extra-condensed");
7122  staticpro (&Qextra_condensed);
7123  Qcondensed = intern ("condensed");
7124  staticpro (&Qcondensed);
7125  Qsemi_condensed = intern ("semi-condensed");
7126  staticpro (&Qsemi_condensed);
7127  Qsemi_expanded = intern ("semi-expanded");
7128  staticpro (&Qsemi_expanded);
7129  Qexpanded = intern ("expanded");
7130  staticpro (&Qexpanded);
7131  Qextra_expanded = intern ("extra-expanded");
7132  staticpro (&Qextra_expanded);
7133  Qultra_expanded = intern ("ultra-expanded");
7134  staticpro (&Qultra_expanded);
7135  Qbackground_color = intern ("background-color");
7136  staticpro (&Qbackground_color);
7137  Qforeground_color = intern ("foreground-color");
7138  staticpro (&Qforeground_color);
7139  Qunspecified = intern ("unspecified");
7140  staticpro (&Qunspecified);
7141
7142  Qface_alias = intern ("face-alias");
7143  staticpro (&Qface_alias);
7144  Qdefault = intern ("default");
7145  staticpro (&Qdefault);
7146  Qtool_bar = intern ("tool-bar");
7147  staticpro (&Qtool_bar);
7148  Qregion = intern ("region");
7149  staticpro (&Qregion);
7150  Qfringe = intern ("fringe");
7151  staticpro (&Qfringe);
7152  Qheader_line = intern ("header-line");
7153  staticpro (&Qheader_line);
7154  Qscroll_bar = intern ("scroll-bar");
7155  staticpro (&Qscroll_bar);
7156  Qmenu = intern ("menu");
7157  staticpro (&Qmenu);
7158  Qcursor = intern ("cursor");
7159  staticpro (&Qcursor);
7160  Qborder = intern ("border");
7161  staticpro (&Qborder);
7162  Qmouse = intern ("mouse");
7163  staticpro (&Qmouse);
7164  Qtty_color_desc = intern ("tty-color-desc");
7165  staticpro (&Qtty_color_desc);
7166  Qtty_color_by_index = intern ("tty-color-by-index");
7167  staticpro (&Qtty_color_by_index);
7168  Qtty_color_alist = intern ("tty-color-alist");
7169  staticpro (&Qtty_color_alist);
7170  Qscalable_fonts_allowed = intern ("scalable-fonts-allowed");
7171  staticpro (&Qscalable_fonts_allowed);
7172
7173  Vparam_value_alist = Fcons (Fcons (Qnil, Qnil), Qnil);
7174  staticpro (&Vparam_value_alist);
7175  Vface_alternative_font_family_alist = Qnil;
7176  staticpro (&Vface_alternative_font_family_alist);
7177  Vface_alternative_font_registry_alist = Qnil;
7178  staticpro (&Vface_alternative_font_registry_alist);
7179
7180  defsubr (&Sinternal_make_lisp_face);
7181  defsubr (&Sinternal_lisp_face_p);
7182  defsubr (&Sinternal_set_lisp_face_attribute);
7183#ifdef HAVE_WINDOW_SYSTEM
7184  defsubr (&Sinternal_set_lisp_face_attribute_from_resource);
7185#endif
7186  defsubr (&Scolor_gray_p);
7187  defsubr (&Scolor_supported_p);
7188  defsubr (&Sinternal_get_lisp_face_attribute);
7189  defsubr (&Sinternal_lisp_face_attribute_values);
7190  defsubr (&Sinternal_lisp_face_equal_p);
7191  defsubr (&Sinternal_lisp_face_empty_p);
7192  defsubr (&Sinternal_copy_lisp_face);
7193  defsubr (&Sinternal_merge_in_global_face);
7194  defsubr (&Sface_font);
7195  defsubr (&Sframe_face_alist);
7196  defsubr (&Sinternal_set_font_selection_order);
7197  defsubr (&Sinternal_set_alternative_font_family_alist);
7198  defsubr (&Sinternal_set_alternative_font_registry_alist);
7199#if GLYPH_DEBUG
7200  defsubr (&Sdump_face);
7201  defsubr (&Sshow_face_resources);
7202#endif /* GLYPH_DEBUG */
7203  defsubr (&Sclear_face_cache);
7204  defsubr (&Stty_suppress_bold_inverse_default_colors);
7205
7206#if defined DEBUG_X_COLORS && defined HAVE_X_WINDOWS
7207  defsubr (&Sdump_colors);
7208#endif
7209
7210  DEFVAR_LISP ("font-list-limit", &Vfont_list_limit,
7211    "*Limit for font matching.\n\
7212If an integer > 0, font matching functions won't load more than\n\
7213that number of fonts when searching for a matching font.");
7214  Vfont_list_limit = make_number (DEFAULT_FONT_LIST_LIMIT);
7215
7216  DEFVAR_LISP ("face-new-frame-defaults", &Vface_new_frame_defaults,
7217    "List of global face definitions (for internal use only.)");
7218  Vface_new_frame_defaults = Qnil;
7219
7220  DEFVAR_LISP ("face-default-stipple", &Vface_default_stipple,
7221    "*Default stipple pattern used on monochrome displays.\n\
7222This stipple pattern is used on monochrome displays\n\
7223instead of shades of gray for a face background color.\n\
7224See `set-face-stipple' for possible values for this variable.");
7225  Vface_default_stipple = build_string ("gray3");
7226
7227  DEFVAR_LISP ("tty-defined-color-alist", &Vtty_defined_color_alist,
7228   "An alist of defined terminal colors and their RGB values.");
7229  Vtty_defined_color_alist = Qnil;
7230
7231  DEFVAR_LISP ("scalable-fonts-allowed", &Vscalable_fonts_allowed,
7232    "Allowed scalable fonts.\n\
7233A value of nil means don't allow any scalable fonts.\n\
7234A value of t means allow any scalable font.\n\
7235Otherwise, value must be a list of regular expressions.  A font may be\n\
7236scaled if its name matches a regular expression in the list.\n\
7237Note that if value is nil, a scalable font might still be used, if no\n\
7238other font of the appropriate family and registry is available.");
7239  Vscalable_fonts_allowed = Qnil;
7240
7241  DEFVAR_LISP ("face-ignored-fonts", &Vface_ignored_fonts,
7242    "List of ignored fonts.\n\
7243Each element is a regular expression that matches names of fonts to ignore.");
7244  Vface_ignored_fonts = Qnil;
7245
7246#ifdef HAVE_WINDOW_SYSTEM
7247  defsubr (&Sbitmap_spec_p);
7248  defsubr (&Sx_list_fonts);
7249  defsubr (&Sinternal_face_x_get_resource);
7250  defsubr (&Sx_family_fonts);
7251  defsubr (&Sx_font_family_list);
7252#endif /* HAVE_WINDOW_SYSTEM */
7253}
7254