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