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