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