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