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