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