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