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