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