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