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