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