*** empty log message ***
[emacs.git] / src / xfaces.c
blob31611082680f0440e331e0b36d99bb239326da2d
1 /* xfaces.c -- "Face" primitives.
2 Copyright (C) 1993, 1994, 1998, 1999, 2000 Free Software Foundation.
4 This file is part of GNU Emacs.
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.
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.
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. */
21 /* New face implementation by Gerd Moellmann <gerd@gnu.org>. */
23 /* Faces.
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:
29 1. Font family name.
31 2. Relative proportionate width, aka character set width or set
32 width (swidth), e.g. `semi-compressed'.
34 3. Font height in 1/10pt.
36 4. Font weight, e.g. `bold'.
38 5. Font slant, e.g. `italic'.
40 6. Foreground color.
42 7. Background color.
44 8. Whether or not characters should be underlined, and in what color.
46 9. Whether or not characters should be displayed in inverse video.
48 10. A background stipple, a bitmap.
50 11. Whether or not characters should be overlined, and in what color.
52 12. Whether or not characters should be strike-through, and in what
53 color.
55 13. Whether or not a box should be drawn around characters, the box
56 type, and, for simple boxes, in what color.
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).
68 15. A face name or list of face names from which to inherit attributes.
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.
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.
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'.
86 Face merging.
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.
96 Face realization.
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.
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.
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.
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.
121 Thus, all realzied face have a realized fontset.
124 Unibyte text.
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.
132 Font selection.
134 Font selection tries to find the best available matching font for a
135 given (character, face) combination.
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.
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.
148 Font selection can be influenced by the user.
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.
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.
164 Character compositition.
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.
175 Initialization of basic faces.
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. */
182 /* Define SCALABLE_FONTS to a non-zero value to enable scalable
183 font use. Define it to zero to disable scalable font use.
185 Use of too many or too large scalable fonts can crash XFree86
186 servers. That's why I've put the code dealing with scalable fonts
187 in #if's. */
189 #define SCALABLE_FONTS 1
191 #include <config.h>
192 #include <sys/types.h>
193 #include <sys/stat.h>
194 #include "lisp.h"
195 #include "charset.h"
196 #include "frame.h"
198 #ifdef HAVE_WINDOW_SYSTEM
199 #include "fontset.h"
200 #endif
201 #ifdef HAVE_X_WINDOWS
202 #include "xterm.h"
203 #ifdef USE_MOTIF
204 #include <Xm/Xm.h>
205 #include <Xm/XmStrDefs.h>
206 #endif /* USE_MOTIF */
207 #endif
209 #ifdef MSDOS
210 #include "dosfns.h"
211 #endif
213 #ifdef WINDOWSNT
214 #include "w32term.h"
215 #include "fontset.h"
216 /* Redefine X specifics to W32 equivalents to avoid cluttering the
217 code with #ifdef blocks. */
218 #define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
219 #define x_display_info w32_display_info
220 #define FRAME_X_FONT_TABLE FRAME_W32_FONT_TABLE
221 #define check_x check_w32
222 #define x_list_fonts w32_list_fonts
223 #define GCGraphicsExposures 0
224 /* For historic reasons, FONT_WIDTH refers to average width on W32,
225 not maximum as on X. Redefine here. */
226 #define FONT_WIDTH FONT_MAX_WIDTH
227 #endif
229 #include "buffer.h"
230 #include "dispextern.h"
231 #include "blockinput.h"
232 #include "window.h"
233 #include "intervals.h"
235 #ifdef HAVE_X_WINDOWS
237 /* Compensate for a bug in Xos.h on some systems, on which it requires
238 time.h. On some such systems, Xos.h tries to redefine struct
239 timeval and struct timezone if USG is #defined while it is
240 #included. */
242 #ifdef XOS_NEEDS_TIME_H
243 #include <time.h>
244 #undef USG
245 #include <X11/Xos.h>
246 #define USG
247 #define __TIMEVAL__
248 #else /* not XOS_NEEDS_TIME_H */
249 #include <X11/Xos.h>
250 #endif /* not XOS_NEEDS_TIME_H */
252 #endif /* HAVE_X_WINDOWS */
254 #include <stdio.h>
255 #include <ctype.h>
256 #include "keyboard.h"
258 #ifndef max
259 #define max(A, B) ((A) > (B) ? (A) : (B))
260 #define min(A, B) ((A) < (B) ? (A) : (B))
261 #define abs(X) ((X) < 0 ? -(X) : (X))
262 #endif
264 /* Non-zero if face attribute ATTR is unspecified. */
266 #define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
268 /* Value is the number of elements of VECTOR. */
270 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
272 /* Make a copy of string S on the stack using alloca. Value is a pointer
273 to the copy. */
275 #define STRDUPA(S) strcpy ((char *) alloca (strlen ((S)) + 1), (S))
277 /* Make a copy of the contents of Lisp string S on the stack using
278 alloca. Value is a pointer to the copy. */
280 #define LSTRDUPA(S) STRDUPA (XSTRING ((S))->data)
282 /* Size of hash table of realized faces in face caches (should be a
283 prime number). */
285 #define FACE_CACHE_BUCKETS_SIZE 1001
287 /* A definition of XColor for non-X frames. */
289 #ifndef HAVE_X_WINDOWS
291 typedef struct
293 unsigned long pixel;
294 unsigned short red, green, blue;
295 char flags;
296 char pad;
298 XColor;
300 #endif /* not HAVE_X_WINDOWS */
302 /* Keyword symbols used for face attribute names. */
304 Lisp_Object QCfamily, QCheight, QCweight, QCslant, QCunderline;
305 Lisp_Object QCinverse_video, QCforeground, QCbackground, QCstipple;
306 Lisp_Object QCwidth, QCfont, QCbold, QCitalic;
307 Lisp_Object QCreverse_video;
308 Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
310 /* Symbols used for attribute values. */
312 Lisp_Object Qnormal, Qbold, Qultra_light, Qextra_light, Qlight;
313 Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
314 Lisp_Object Qoblique, Qitalic, Qreverse_oblique, Qreverse_italic;
315 Lisp_Object Qultra_condensed, Qextra_condensed, Qcondensed;
316 Lisp_Object Qsemi_condensed, Qsemi_expanded, Qexpanded, Qextra_expanded;
317 Lisp_Object Qultra_expanded;
318 Lisp_Object Qreleased_button, Qpressed_button;
319 Lisp_Object QCstyle, QCcolor, QCline_width;
320 Lisp_Object Qunspecified;
322 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
324 /* The name of the function to call when the background of the frame
325 has changed, frame_update_face_colors. */
327 Lisp_Object Qframe_update_face_colors;
329 /* Names of basic faces. */
331 Lisp_Object Qdefault, Qtool_bar, Qregion, Qfringe;
332 Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu;
333 extern Lisp_Object Qmode_line;
335 /* The symbol `face-alias'. A symbols having that property is an
336 alias for another face. Value of the property is the name of
337 the aliased face. */
339 Lisp_Object Qface_alias;
341 /* Names of frame parameters related to faces. */
343 extern Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
344 extern Lisp_Object Qborder_color, Qcursor_color, Qmouse_color;
346 /* Default stipple pattern used on monochrome displays. This stipple
347 pattern is used on monochrome displays instead of shades of gray
348 for a face background color. See `set-face-stipple' for possible
349 values for this variable. */
351 Lisp_Object Vface_default_stipple;
353 /* Alist of alternative font families. Each element is of the form
354 (FAMILY FAMILY1 FAMILY2 ...). If fonts of FAMILY can't be loaded,
355 try FAMILY1, then FAMILY2, ... */
357 Lisp_Object Vface_alternative_font_family_alist;
359 /* Allowed scalable fonts. A value of nil means don't allow any
360 scalable fonts. A value of t means allow the use of any scalable
361 font. Otherwise, value must be a list of regular expressions. A
362 font may be scaled if its name matches a regular expression in the
363 list. */
365 #if SCALABLE_FONTS
366 Lisp_Object Vscalable_fonts_allowed;
367 #endif
369 /* Maximum number of fonts to consider in font_list. If not an
370 integer > 0, DEFAULT_FONT_LIST_LIMIT is used instead. */
372 Lisp_Object Vfont_list_limit;
373 #define DEFAULT_FONT_LIST_LIMIT 100
375 /* The symbols `foreground-color' and `background-color' which can be
376 used as part of a `face' property. This is for compatibility with
377 Emacs 20.2. */
379 Lisp_Object Qforeground_color, Qbackground_color;
381 /* The symbols `face' and `mouse-face' used as text properties. */
383 Lisp_Object Qface;
384 extern Lisp_Object Qmouse_face;
386 /* Error symbol for wrong_type_argument in load_pixmap. */
388 Lisp_Object Qbitmap_spec_p;
390 /* Alist of global face definitions. Each element is of the form
391 (FACE . LFACE) where FACE is a symbol naming a face and LFACE
392 is a Lisp vector of face attributes. These faces are used
393 to initialize faces for new frames. */
395 Lisp_Object Vface_new_frame_defaults;
397 /* The next ID to assign to Lisp faces. */
399 static int next_lface_id;
401 /* A vector mapping Lisp face Id's to face names. */
403 static Lisp_Object *lface_id_to_name;
404 static int lface_id_to_name_size;
406 /* TTY color-related functions (defined in tty-colors.el). */
408 Lisp_Object Qtty_color_desc, Qtty_color_by_index;
410 /* The name of the function used to compute colors on TTYs. */
412 Lisp_Object Qtty_color_alist;
414 /* An alist of defined terminal colors and their RGB values. */
416 Lisp_Object Vtty_defined_color_alist;
418 /* Counter for calls to clear_face_cache. If this counter reaches
419 CLEAR_FONT_TABLE_COUNT, and a frame has more than
420 CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed. */
422 static int clear_font_table_count;
423 #define CLEAR_FONT_TABLE_COUNT 100
424 #define CLEAR_FONT_TABLE_NFONTS 10
426 /* Non-zero means face attributes have been changed since the last
427 redisplay. Used in redisplay_internal. */
429 int face_change_count;
431 /* Non-zero means don't display bold text if a face's foreground
432 and background colors are the inverse of the default colors of the
433 display. This is a kluge to suppress `bold black' foreground text
434 which is hard to read on an LCD monitor. */
436 int tty_suppress_bold_inverse_default_colors_p;
438 /* The total number of colors currently allocated. */
440 #if GLYPH_DEBUG
441 static int ncolors_allocated;
442 static int npixmaps_allocated;
443 static int ngcs;
444 #endif
448 /* Function prototypes. */
450 struct font_name;
451 struct table_entry;
453 static void map_tty_color P_ ((struct frame *, struct face *,
454 enum lface_attribute_index, int *));
455 static Lisp_Object resolve_face_name P_ ((Lisp_Object));
456 static int may_use_scalable_font_p P_ ((struct font_name *, char *));
457 static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object));
458 static int better_font_p P_ ((int *, struct font_name *, struct font_name *,
459 int));
460 static int first_font_matching P_ ((struct frame *f, char *,
461 struct font_name *));
462 static int x_face_list_fonts P_ ((struct frame *, char *,
463 struct font_name *, int, int, int));
464 static int font_scalable_p P_ ((struct font_name *));
465 static int get_lface_attributes P_ ((struct frame *, Lisp_Object, Lisp_Object *, int));
466 static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *));
467 static unsigned char *xstrlwr P_ ((unsigned char *));
468 static void signal_error P_ ((char *, Lisp_Object));
469 static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int));
470 static void load_face_font P_ ((struct frame *, struct face *, int));
471 static void load_face_colors P_ ((struct frame *, struct face *, Lisp_Object *));
472 static void free_face_colors P_ ((struct frame *, struct face *));
473 static int face_color_gray_p P_ ((struct frame *, char *));
474 static char *build_font_name P_ ((struct font_name *));
475 static void free_font_names P_ ((struct font_name *, int));
476 static int sorted_font_list P_ ((struct frame *, char *,
477 int (*cmpfn) P_ ((const void *, const void *)),
478 struct font_name **));
479 static int font_list P_ ((struct frame *, Lisp_Object, Lisp_Object,
480 Lisp_Object, struct font_name **));
481 static int try_font_list P_ ((struct frame *, Lisp_Object *, Lisp_Object,
482 Lisp_Object, Lisp_Object, struct font_name **));
483 static int cmp_font_names P_ ((const void *, const void *));
484 static struct face *realize_face P_ ((struct face_cache *, Lisp_Object *, int,
485 struct face *, int));
486 static struct face *realize_x_face P_ ((struct face_cache *,
487 Lisp_Object *, int, struct face *));
488 static struct face *realize_tty_face P_ ((struct face_cache *,
489 Lisp_Object *, int));
490 static int realize_basic_faces P_ ((struct frame *));
491 static int realize_default_face P_ ((struct frame *));
492 static void realize_named_face P_ ((struct frame *, Lisp_Object, int));
493 static int lface_fully_specified_p P_ ((Lisp_Object *));
494 static int lface_equal_p P_ ((Lisp_Object *, Lisp_Object *));
495 static unsigned hash_string_case_insensitive P_ ((Lisp_Object));
496 static unsigned lface_hash P_ ((Lisp_Object *));
497 static int lface_same_font_attributes_p P_ ((Lisp_Object *, Lisp_Object *));
498 static struct face_cache *make_face_cache P_ ((struct frame *));
499 static void free_realized_face P_ ((struct frame *, struct face *));
500 static void clear_face_gcs P_ ((struct face_cache *));
501 static void free_face_cache P_ ((struct face_cache *));
502 static int face_numeric_weight P_ ((Lisp_Object));
503 static int face_numeric_slant P_ ((Lisp_Object));
504 static int face_numeric_swidth P_ ((Lisp_Object));
505 static int face_fontset P_ ((Lisp_Object *));
506 static char *choose_face_font P_ ((struct frame *, Lisp_Object *, int, int));
507 static void default_face_vector P_ ((Lisp_Object *, Lisp_Object*));
508 static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*, Lisp_Object));
509 static void merge_face_inheritance P_ ((struct frame *f, Lisp_Object,
510 Lisp_Object *, Lisp_Object));
511 static void merge_face_vector_with_property P_ ((struct frame *, Lisp_Object *,
512 Lisp_Object));
513 static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object,
514 Lisp_Object, int, int));
515 static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int));
516 static struct face *make_realized_face P_ ((Lisp_Object *));
517 static void free_realized_faces P_ ((struct face_cache *));
518 static char *best_matching_font P_ ((struct frame *, Lisp_Object *,
519 struct font_name *, int));
520 static void cache_face P_ ((struct face_cache *, struct face *, unsigned));
521 static void uncache_face P_ ((struct face_cache *, struct face *));
522 static int xlfd_numeric_slant P_ ((struct font_name *));
523 static int xlfd_numeric_weight P_ ((struct font_name *));
524 static int xlfd_numeric_swidth P_ ((struct font_name *));
525 static Lisp_Object xlfd_symbolic_slant P_ ((struct font_name *));
526 static Lisp_Object xlfd_symbolic_weight P_ ((struct font_name *));
527 static Lisp_Object xlfd_symbolic_swidth P_ ((struct font_name *));
528 static int xlfd_fixed_p P_ ((struct font_name *));
529 static int xlfd_numeric_value P_ ((struct table_entry *, int, struct font_name *,
530 int, int));
531 static Lisp_Object xlfd_symbolic_value P_ ((struct table_entry *, int,
532 struct font_name *, int,
533 Lisp_Object));
534 static struct table_entry *xlfd_lookup_field_contents P_ ((struct table_entry *, int,
535 struct font_name *, int));
537 #ifdef HAVE_WINDOW_SYSTEM
539 static int split_font_name P_ ((struct frame *, struct font_name *, int));
540 static int xlfd_point_size P_ ((struct frame *, struct font_name *));
541 static void sort_fonts P_ ((struct frame *, struct font_name *, int,
542 int (*cmpfn) P_ ((const void *, const void *))));
543 static GC x_create_gc P_ ((struct frame *, unsigned long, XGCValues *));
544 static void x_free_gc P_ ((struct frame *, GC));
545 static void clear_font_table P_ ((struct frame *));
547 #ifdef WINDOWSNT
548 extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
549 #endif /* WINDOWSNT */
551 #endif /* HAVE_WINDOW_SYSTEM */
554 /***********************************************************************
555 Utilities
556 ***********************************************************************/
558 #ifdef HAVE_X_WINDOWS
560 #ifdef DEBUG_X_COLORS
562 /* The following is a poor mans infrastructure for debugging X color
563 allocation problems on displays with PseudoColor-8. Some X servers
564 like 3.3.5 XF86_SVGA with Matrox cards apparently don't implement
565 color reference counts completely so that they don't signal an
566 error when a color is freed whose reference count is already 0.
567 Other X servers do. To help me debug this, the following code
568 implements a simple reference counting schema of its own, for a
569 single display/screen. --gerd. */
571 /* Reference counts for pixel colors. */
573 int color_count[256];
575 /* Register color PIXEL as allocated. */
577 void
578 register_color (pixel)
579 unsigned long pixel;
581 xassert (pixel < 256);
582 ++color_count[pixel];
586 /* Register color PIXEL as deallocated. */
588 void
589 unregister_color (pixel)
590 unsigned long pixel;
592 xassert (pixel < 256);
593 if (color_count[pixel] > 0)
594 --color_count[pixel];
595 else
596 abort ();
600 /* Register N colors from PIXELS as deallocated. */
602 void
603 unregister_colors (pixels, n)
604 unsigned long *pixels;
605 int n;
607 int i;
608 for (i = 0; i < n; ++i)
609 unregister_color (pixels[i]);
613 DEFUN ("dump-colors", Fdump_colors, Sdump_colors, 0, 0, 0,
614 "Dump currently allocated colors and their reference counts to stderr.")
617 int i, n;
619 fputc ('\n', stderr);
621 for (i = n = 0; i < sizeof color_count / sizeof color_count[0]; ++i)
622 if (color_count[i])
624 fprintf (stderr, "%3d: %5d", i, color_count[i]);
625 ++n;
626 if (n % 5 == 0)
627 fputc ('\n', stderr);
628 else
629 fputc ('\t', stderr);
632 if (n % 5 != 0)
633 fputc ('\n', stderr);
634 return Qnil;
638 #endif /* DEBUG_X_COLORS */
640 /* Free colors used on frame F. PIXELS is an array of NPIXELS pixel
641 color values. Interrupt input must be blocked when this function
642 is called. */
644 void
645 x_free_colors (f, pixels, npixels)
646 struct frame *f;
647 unsigned long *pixels;
648 int npixels;
650 int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
652 /* If display has an immutable color map, freeing colors is not
653 necessary and some servers don't allow it. So don't do it. */
654 if (class != StaticColor && class != StaticGray && class != TrueColor)
656 XFreeColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
657 pixels, npixels, 0);
658 #ifdef DEBUG_X_COLORS
659 unregister_colors (pixels, npixels);
660 #endif
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. */
669 void
670 x_free_dpy_colors (dpy, screen, cmap, pixels, npixels)
671 Display *dpy;
672 Screen *screen;
673 Colormap cmap;
674 unsigned long *pixels;
675 int npixels;
677 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
678 int class = dpyinfo->visual->class;
680 /* If display has an immutable color map, freeing colors is not
681 necessary and some servers don't allow it. So don't do it. */
682 if (class != StaticColor && class != StaticGray && class != TrueColor)
684 XFreeColors (dpy, cmap, pixels, npixels, 0);
685 #ifdef DEBUG_X_COLORS
686 unregister_colors (pixels, npixels);
687 #endif
692 /* Create and return a GC for use on frame F. GC values and mask
693 are given by XGCV and MASK. */
695 static INLINE GC
696 x_create_gc (f, mask, xgcv)
697 struct frame *f;
698 unsigned long mask;
699 XGCValues *xgcv;
701 GC gc;
702 BLOCK_INPUT;
703 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, xgcv);
704 UNBLOCK_INPUT;
705 IF_DEBUG (++ngcs);
706 return gc;
710 /* Free GC which was used on frame F. */
712 static INLINE void
713 x_free_gc (f, gc)
714 struct frame *f;
715 GC gc;
717 BLOCK_INPUT;
718 xassert (--ngcs >= 0);
719 XFreeGC (FRAME_X_DISPLAY (f), gc);
720 UNBLOCK_INPUT;
723 #endif /* HAVE_X_WINDOWS */
725 #ifdef WINDOWSNT
726 /* W32 emulation of GCs */
728 static INLINE GC
729 x_create_gc (f, mask, xgcv)
730 struct frame *f;
731 unsigned long mask;
732 XGCValues *xgcv;
734 GC gc;
735 BLOCK_INPUT;
736 gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, xgcv);
737 UNBLOCK_INPUT;
738 IF_DEBUG (++ngcs);
739 return gc;
743 /* Free GC which was used on frame F. */
745 static INLINE void
746 x_free_gc (f, gc)
747 struct frame *f;
748 GC gc;
750 BLOCK_INPUT;
751 xassert (--ngcs >= 0);
752 xfree (gc);
753 UNBLOCK_INPUT;
756 #endif /* WINDOWSNT */
758 /* Like stricmp. Used to compare parts of font names which are in
759 ISO8859-1. */
762 xstricmp (s1, s2)
763 unsigned char *s1, *s2;
765 while (*s1 && *s2)
767 unsigned char c1 = tolower (*s1);
768 unsigned char c2 = tolower (*s2);
769 if (c1 != c2)
770 return c1 < c2 ? -1 : 1;
771 ++s1, ++s2;
774 if (*s1 == 0)
775 return *s2 == 0 ? 0 : -1;
776 return 1;
780 /* Like strlwr, which might not always be available. */
782 static unsigned char *
783 xstrlwr (s)
784 unsigned char *s;
786 unsigned char *p = s;
788 for (p = s; *p; ++p)
789 *p = tolower (*p);
791 return s;
795 /* Signal `error' with message S, and additional argument ARG. */
797 static void
798 signal_error (s, arg)
799 char *s;
800 Lisp_Object arg;
802 Fsignal (Qerror, Fcons (build_string (s), Fcons (arg, Qnil)));
806 /* If FRAME is nil, return a pointer to the selected frame.
807 Otherwise, check that FRAME is a live frame, and return a pointer
808 to it. NPARAM is the parameter number of FRAME, for
809 CHECK_LIVE_FRAME. This is here because it's a frequent pattern in
810 Lisp function definitions. */
812 static INLINE struct frame *
813 frame_or_selected_frame (frame, nparam)
814 Lisp_Object frame;
815 int nparam;
817 if (NILP (frame))
818 frame = selected_frame;
820 CHECK_LIVE_FRAME (frame, nparam);
821 return XFRAME (frame);
825 /***********************************************************************
826 Frames and faces
827 ***********************************************************************/
829 /* Initialize face cache and basic faces for frame F. */
831 void
832 init_frame_faces (f)
833 struct frame *f;
835 /* Make a face cache, if F doesn't have one. */
836 if (FRAME_FACE_CACHE (f) == NULL)
837 FRAME_FACE_CACHE (f) = make_face_cache (f);
839 #ifdef HAVE_WINDOW_SYSTEM
840 /* Make the image cache. */
841 if (FRAME_WINDOW_P (f))
843 if (FRAME_X_IMAGE_CACHE (f) == NULL)
844 FRAME_X_IMAGE_CACHE (f) = make_image_cache ();
845 ++FRAME_X_IMAGE_CACHE (f)->refcount;
847 #endif /* HAVE_WINDOW_SYSTEM */
849 /* Realize basic faces. Must have enough information in frame
850 parameters to realize basic faces at this point. */
851 #ifdef HAVE_X_WINDOWS
852 if (!FRAME_X_P (f) || FRAME_X_WINDOW (f))
853 #endif
854 #ifdef WINDOWSNT
855 if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
856 #endif
857 if (!realize_basic_faces (f))
858 abort ();
862 /* Free face cache of frame F. Called from Fdelete_frame. */
864 void
865 free_frame_faces (f)
866 struct frame *f;
868 struct face_cache *face_cache = FRAME_FACE_CACHE (f);
870 if (face_cache)
872 free_face_cache (face_cache);
873 FRAME_FACE_CACHE (f) = NULL;
876 #ifdef HAVE_WINDOW_SYSTEM
877 if (FRAME_WINDOW_P (f))
879 struct image_cache *image_cache = FRAME_X_IMAGE_CACHE (f);
880 if (image_cache)
882 --image_cache->refcount;
883 if (image_cache->refcount == 0)
884 free_image_cache (f);
887 #endif /* HAVE_WINDOW_SYSTEM */
891 /* Clear face caches, and recompute basic faces for frame F. Call
892 this after changing frame parameters on which those faces depend,
893 or when realized faces have been freed due to changing attributes
894 of named faces. */
896 void
897 recompute_basic_faces (f)
898 struct frame *f;
900 if (FRAME_FACE_CACHE (f))
902 clear_face_cache (0);
903 if (!realize_basic_faces (f))
904 abort ();
909 /* Clear the face caches of all frames. CLEAR_FONTS_P non-zero means
910 try to free unused fonts, too. */
912 void
913 clear_face_cache (clear_fonts_p)
914 int clear_fonts_p;
916 #ifdef HAVE_WINDOW_SYSTEM
917 Lisp_Object tail, frame;
918 struct frame *f;
920 if (clear_fonts_p
921 || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
923 /* From time to time see if we can unload some fonts. This also
924 frees all realized faces on all frames. Fonts needed by
925 faces will be loaded again when faces are realized again. */
926 clear_font_table_count = 0;
928 FOR_EACH_FRAME (tail, frame)
930 f = XFRAME (frame);
931 if (FRAME_WINDOW_P (f)
932 && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
934 free_all_realized_faces (frame);
935 clear_font_table (f);
939 else
941 /* Clear GCs of realized faces. */
942 FOR_EACH_FRAME (tail, frame)
944 f = XFRAME (frame);
945 if (FRAME_WINDOW_P (f))
947 clear_face_gcs (FRAME_FACE_CACHE (f));
948 clear_image_cache (f, 0);
952 #endif /* HAVE_WINDOW_SYSTEM */
956 DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
957 "Clear face caches on all frames.\n\
958 Optional THOROUGHLY non-nil means try to free unused fonts, too.")
959 (thorougly)
960 Lisp_Object thorougly;
962 clear_face_cache (!NILP (thorougly));
963 ++face_change_count;
964 ++windows_or_buffers_changed;
965 return Qnil;
970 #ifdef HAVE_WINDOW_SYSTEM
973 /* Remove those fonts from the font table of frame F exept for the
974 default ASCII font for the frame. Called from clear_face_cache
975 from time to time. */
977 static void
978 clear_font_table (f)
979 struct frame *f;
981 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
982 int i;
984 xassert (FRAME_WINDOW_P (f));
986 /* Free those fonts that are not used by the frame F as the default. */
987 for (i = 0; i < dpyinfo->n_fonts; ++i)
989 struct font_info *font_info = dpyinfo->font_table + i;
991 if (!font_info->name
992 || font_info->font == FRAME_FONT (f))
993 continue;
995 /* Free names. */
996 if (font_info->full_name != font_info->name)
997 xfree (font_info->full_name);
998 xfree (font_info->name);
1000 /* Free the font. */
1001 BLOCK_INPUT;
1002 #ifdef HAVE_X_WINDOWS
1003 XFreeFont (dpyinfo->display, font_info->font);
1004 #endif
1005 #ifdef WINDOWSNT
1006 w32_unload_font (dpyinfo, font_info->font);
1007 #endif
1008 UNBLOCK_INPUT;
1010 /* Mark font table slot free. */
1011 font_info->font = NULL;
1012 font_info->name = font_info->full_name = NULL;
1016 #endif /* HAVE_WINDOW_SYSTEM */
1020 /***********************************************************************
1021 X Pixmaps
1022 ***********************************************************************/
1024 #ifdef HAVE_WINDOW_SYSTEM
1026 DEFUN ("bitmap-spec-p", Fbitmap_spec_p, Sbitmap_spec_p, 1, 1, 0,
1027 "Value is non-nil if OBJECT is a valid bitmap specification.\n\
1028 A bitmap specification is either a string, a file name, or a list\n\
1029 (WIDTH HEIGHT DATA) where WIDTH is the pixel width of the bitmap,\n\
1030 HEIGHT is its height, and DATA is a string containing the bits of\n\
1031 the pixmap. Bits are stored row by row, each row occupies\n\
1032 (WIDTH + 7)/8 bytes.")
1033 (object)
1034 Lisp_Object object;
1036 int pixmap_p = 0;
1038 if (STRINGP (object))
1039 /* If OBJECT is a string, it's a file name. */
1040 pixmap_p = 1;
1041 else if (CONSP (object))
1043 /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and
1044 HEIGHT must be integers > 0, and DATA must be string large
1045 enough to hold a bitmap of the specified size. */
1046 Lisp_Object width, height, data;
1048 height = width = data = Qnil;
1050 if (CONSP (object))
1052 width = XCAR (object);
1053 object = XCDR (object);
1054 if (CONSP (object))
1056 height = XCAR (object);
1057 object = XCDR (object);
1058 if (CONSP (object))
1059 data = XCAR (object);
1063 if (NATNUMP (width) && NATNUMP (height) && STRINGP (data))
1065 int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1)
1066 / BITS_PER_CHAR);
1067 if (STRING_BYTES (XSTRING (data)) >= bytes_per_row * XINT (height))
1068 pixmap_p = 1;
1072 return pixmap_p ? Qt : Qnil;
1076 /* Load a bitmap according to NAME (which is either a file name or a
1077 pixmap spec) for use on frame F. Value is the bitmap_id (see
1078 xfns.c). If NAME is nil, return with a bitmap id of zero. If
1079 bitmap cannot be loaded, display a message saying so, and return
1080 zero. Store the bitmap width in *W_PTR and its height in *H_PTR,
1081 if these pointers are not null. */
1083 static int
1084 load_pixmap (f, name, w_ptr, h_ptr)
1085 FRAME_PTR f;
1086 Lisp_Object name;
1087 unsigned int *w_ptr, *h_ptr;
1089 int bitmap_id;
1090 Lisp_Object tem;
1092 if (NILP (name))
1093 return 0;
1095 tem = Fbitmap_spec_p (name);
1096 if (NILP (tem))
1097 wrong_type_argument (Qbitmap_spec_p, name);
1099 BLOCK_INPUT;
1100 if (CONSP (name))
1102 /* Decode a bitmap spec into a bitmap. */
1104 int h, w;
1105 Lisp_Object bits;
1107 w = XINT (Fcar (name));
1108 h = XINT (Fcar (Fcdr (name)));
1109 bits = Fcar (Fcdr (Fcdr (name)));
1111 bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data,
1112 w, h);
1114 else
1116 /* It must be a string -- a file name. */
1117 bitmap_id = x_create_bitmap_from_file (f, name);
1119 UNBLOCK_INPUT;
1121 if (bitmap_id < 0)
1123 add_to_log ("Invalid or undefined bitmap %s", name, Qnil);
1124 bitmap_id = 0;
1126 if (w_ptr)
1127 *w_ptr = 0;
1128 if (h_ptr)
1129 *h_ptr = 0;
1131 else
1133 #if GLYPH_DEBUG
1134 ++npixmaps_allocated;
1135 #endif
1136 if (w_ptr)
1137 *w_ptr = x_bitmap_width (f, bitmap_id);
1139 if (h_ptr)
1140 *h_ptr = x_bitmap_height (f, bitmap_id);
1143 return bitmap_id;
1146 #endif /* HAVE_WINDOW_SYSTEM */
1150 /***********************************************************************
1151 Minimum font bounds
1152 ***********************************************************************/
1154 #ifdef HAVE_WINDOW_SYSTEM
1156 /* Update the line_height of frame F. Return non-zero if line height
1157 changes. */
1160 frame_update_line_height (f)
1161 struct frame *f;
1163 int line_height, changed_p;
1165 line_height = FONT_HEIGHT (FRAME_FONT (f));
1166 changed_p = line_height != FRAME_LINE_HEIGHT (f);
1167 FRAME_LINE_HEIGHT (f) = line_height;
1168 return changed_p;
1171 #endif /* HAVE_WINDOW_SYSTEM */
1174 /***********************************************************************
1175 Fonts
1176 ***********************************************************************/
1178 #ifdef HAVE_WINDOW_SYSTEM
1180 /* Load font of face FACE which is used on frame F to display
1181 character C. The name of the font to load is determined by lface
1182 and fontset of FACE. */
1184 static void
1185 load_face_font (f, face, c)
1186 struct frame *f;
1187 struct face *face;
1188 int c;
1190 struct font_info *font_info = NULL;
1191 char *font_name;
1193 face->font_info_id = -1;
1194 face->font = NULL;
1196 font_name = choose_face_font (f, face->lface, face->fontset, c);
1197 if (!font_name)
1198 return;
1200 BLOCK_INPUT;
1201 font_info = FS_LOAD_FACE_FONT (f, c, font_name, face);
1202 UNBLOCK_INPUT;
1204 if (font_info)
1206 face->font_info_id = font_info->font_idx;
1207 face->font = font_info->font;
1208 face->font_name = font_info->full_name;
1209 if (face->gc)
1211 x_free_gc (f, face->gc);
1212 face->gc = 0;
1215 else
1216 add_to_log ("Unable to load font %s",
1217 build_string (font_name), Qnil);
1218 xfree (font_name);
1221 #endif /* HAVE_WINDOW_SYSTEM */
1225 /***********************************************************************
1226 X Colors
1227 ***********************************************************************/
1229 /* A version of defined_color for non-X frames. */
1232 tty_defined_color (f, color_name, color_def, alloc)
1233 struct frame *f;
1234 char *color_name;
1235 XColor *color_def;
1236 int alloc;
1238 Lisp_Object color_desc;
1239 unsigned long color_idx = FACE_TTY_DEFAULT_COLOR;
1240 unsigned long red = 0, green = 0, blue = 0;
1241 int status = 1;
1243 if (*color_name && !NILP (Ffboundp (Qtty_color_desc)))
1245 Lisp_Object frame;
1247 XSETFRAME (frame, f);
1248 status = 0;
1249 color_desc = call2 (Qtty_color_desc, build_string (color_name), frame);
1250 if (CONSP (color_desc) && CONSP (XCDR (color_desc)))
1252 color_idx = XINT (XCAR (XCDR (color_desc)));
1253 if (CONSP (XCDR (XCDR (color_desc))))
1255 red = XINT (XCAR (XCDR (XCDR (color_desc))));
1256 green = XINT (XCAR (XCDR (XCDR (XCDR (color_desc)))));
1257 blue = XINT (XCAR (XCDR (XCDR (XCDR (XCDR (color_desc))))));
1259 status = 1;
1261 else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist"))))
1262 /* We were called early during startup, and the colors are not
1263 yet set up in tty-defined-color-alist. Don't return a failure
1264 indication, since this produces the annoying "Unable to
1265 load color" messages in the *Messages* buffer. */
1266 status = 1;
1268 if (color_idx == FACE_TTY_DEFAULT_COLOR && *color_name)
1270 if (strcmp (color_name, "unspecified-fg") == 0)
1271 color_idx = FACE_TTY_DEFAULT_FG_COLOR;
1272 else if (strcmp (color_name, "unspecified-bg") == 0)
1273 color_idx = FACE_TTY_DEFAULT_BG_COLOR;
1276 if (color_idx != FACE_TTY_DEFAULT_COLOR)
1277 status = 1;
1279 color_def->pixel = color_idx;
1280 color_def->red = red;
1281 color_def->green = green;
1282 color_def->blue = blue;
1284 return status;
1288 /* Decide if color named COLOR_NAME is valid for the display
1289 associated with the frame F; if so, return the rgb values in
1290 COLOR_DEF. If ALLOC is nonzero, allocate a new colormap cell.
1292 This does the right thing for any type of frame. */
1295 defined_color (f, color_name, color_def, alloc)
1296 struct frame *f;
1297 char *color_name;
1298 XColor *color_def;
1299 int alloc;
1301 if (!FRAME_WINDOW_P (f))
1302 return tty_defined_color (f, color_name, color_def, alloc);
1303 #ifdef HAVE_X_WINDOWS
1304 else if (FRAME_X_P (f))
1305 return x_defined_color (f, color_name, color_def, alloc);
1306 #endif
1307 #ifdef WINDOWSNT
1308 else if (FRAME_W32_P (f))
1309 return w32_defined_color (f, color_name, color_def, alloc);
1310 #endif
1311 #ifdef macintosh
1312 else if (FRAME_MAC_P (f))
1313 /* FIXME: mac_defined_color doesn't exist! */
1314 return mac_defined_color (f, color_name, color_def, alloc);
1315 #endif
1316 else
1317 abort ();
1321 /* Given the index IDX of a tty color on frame F, return its name, a
1322 Lisp string. */
1324 Lisp_Object
1325 tty_color_name (f, idx)
1326 struct frame *f;
1327 int idx;
1329 if (idx >= 0 && !NILP (Ffboundp (Qtty_color_by_index)))
1331 Lisp_Object frame;
1332 Lisp_Object coldesc;
1334 XSETFRAME (frame, f);
1335 coldesc = call2 (Qtty_color_by_index, make_number (idx), frame);
1337 if (!NILP (coldesc))
1338 return XCAR (coldesc);
1340 #ifdef MSDOS
1341 /* We can have an MSDOG frame under -nw for a short window of
1342 opportunity before internal_terminal_init is called. DTRT. */
1343 if (FRAME_MSDOS_P (f) && !inhibit_window_system)
1344 return msdos_stdcolor_name (idx);
1345 #endif
1347 if (idx == FACE_TTY_DEFAULT_FG_COLOR)
1348 return build_string (unspecified_fg);
1349 if (idx == FACE_TTY_DEFAULT_BG_COLOR)
1350 return build_string (unspecified_bg);
1352 #ifdef WINDOWSNT
1353 return vga_stdcolor_name (idx);
1354 #endif
1356 return Qunspecified;
1360 /* Return non-zero if COLOR_NAME is a shade of gray (or white or
1361 black) on frame F. The algorithm is taken from 20.2 faces.el. */
1363 static int
1364 face_color_gray_p (f, color_name)
1365 struct frame *f;
1366 char *color_name;
1368 XColor color;
1369 int gray_p;
1371 if (defined_color (f, color_name, &color, 0))
1372 gray_p = ((abs (color.red - color.green)
1373 < max (color.red, color.green) / 20)
1374 && (abs (color.green - color.blue)
1375 < max (color.green, color.blue) / 20)
1376 && (abs (color.blue - color.red)
1377 < max (color.blue, color.red) / 20));
1378 else
1379 gray_p = 0;
1381 return gray_p;
1385 /* Return non-zero if color COLOR_NAME can be displayed on frame F.
1386 BACKGROUND_P non-zero means the color will be used as background
1387 color. */
1389 static int
1390 face_color_supported_p (f, color_name, background_p)
1391 struct frame *f;
1392 char *color_name;
1393 int background_p;
1395 Lisp_Object frame;
1396 XColor not_used;
1398 XSETFRAME (frame, f);
1399 return (FRAME_WINDOW_P (f)
1400 ? (!NILP (Fxw_display_color_p (frame))
1401 || xstricmp (color_name, "black") == 0
1402 || xstricmp (color_name, "white") == 0
1403 || (background_p
1404 && face_color_gray_p (f, color_name))
1405 || (!NILP (Fx_display_grayscale_p (frame))
1406 && face_color_gray_p (f, color_name)))
1407 : tty_defined_color (f, color_name, &not_used, 0));
1411 DEFUN ("color-gray-p", Fcolor_gray_p, Scolor_gray_p, 1, 2, 0,
1412 "Return non-nil if COLOR is a shade of gray (or white or black).\n\
1413 FRAME specifies the frame and thus the display for interpreting COLOR.\n\
1414 If FRAME is nil or omitted, use the selected frame.")
1415 (color, frame)
1416 Lisp_Object color, frame;
1418 struct frame *f;
1420 CHECK_FRAME (frame, 0);
1421 CHECK_STRING (color, 0);
1422 f = XFRAME (frame);
1423 return face_color_gray_p (f, XSTRING (color)->data) ? Qt : Qnil;
1427 DEFUN ("color-supported-p", Fcolor_supported_p,
1428 Scolor_supported_p, 2, 3, 0,
1429 "Return non-nil if COLOR can be displayed on FRAME.\n\
1430 BACKGROUND-P non-nil means COLOR is used as a background.\n\
1431 If FRAME is nil or omitted, use the selected frame.\n\
1432 COLOR must be a valid color name.")
1433 (color, frame, background_p)
1434 Lisp_Object frame, color, background_p;
1436 struct frame *f;
1438 CHECK_FRAME (frame, 0);
1439 CHECK_STRING (color, 0);
1440 f = XFRAME (frame);
1441 if (face_color_supported_p (f, XSTRING (color)->data, !NILP (background_p)))
1442 return Qt;
1443 return Qnil;
1447 /* Load color with name NAME for use by face FACE on frame F.
1448 TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
1449 LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
1450 LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX. Value is the
1451 pixel color. If color cannot be loaded, display a message, and
1452 return the foreground, background or underline color of F, but
1453 record that fact in flags of the face so that we don't try to free
1454 these colors. */
1456 unsigned long
1457 load_color (f, face, name, target_index)
1458 struct frame *f;
1459 struct face *face;
1460 Lisp_Object name;
1461 enum lface_attribute_index target_index;
1463 XColor color;
1465 xassert (STRINGP (name));
1466 xassert (target_index == LFACE_FOREGROUND_INDEX
1467 || target_index == LFACE_BACKGROUND_INDEX
1468 || target_index == LFACE_UNDERLINE_INDEX
1469 || target_index == LFACE_OVERLINE_INDEX
1470 || target_index == LFACE_STRIKE_THROUGH_INDEX
1471 || target_index == LFACE_BOX_INDEX);
1473 /* if the color map is full, defined_color will return a best match
1474 to the values in an existing cell. */
1475 if (!defined_color (f, XSTRING (name)->data, &color, 1))
1477 add_to_log ("Unable to load color \"%s\"", name, Qnil);
1479 switch (target_index)
1481 case LFACE_FOREGROUND_INDEX:
1482 face->foreground_defaulted_p = 1;
1483 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1484 break;
1486 case LFACE_BACKGROUND_INDEX:
1487 face->background_defaulted_p = 1;
1488 color.pixel = FRAME_BACKGROUND_PIXEL (f);
1489 break;
1491 case LFACE_UNDERLINE_INDEX:
1492 face->underline_defaulted_p = 1;
1493 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1494 break;
1496 case LFACE_OVERLINE_INDEX:
1497 face->overline_color_defaulted_p = 1;
1498 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1499 break;
1501 case LFACE_STRIKE_THROUGH_INDEX:
1502 face->strike_through_color_defaulted_p = 1;
1503 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1504 break;
1506 case LFACE_BOX_INDEX:
1507 face->box_color_defaulted_p = 1;
1508 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1509 break;
1511 default:
1512 abort ();
1515 #if GLYPH_DEBUG
1516 else
1517 ++ncolors_allocated;
1518 #endif
1520 return color.pixel;
1524 #ifdef HAVE_WINDOW_SYSTEM
1526 /* Load colors for face FACE which is used on frame F. Colors are
1527 specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
1528 of ATTRS. If the background color specified is not supported on F,
1529 try to emulate gray colors with a stipple from Vface_default_stipple. */
1531 static void
1532 load_face_colors (f, face, attrs)
1533 struct frame *f;
1534 struct face *face;
1535 Lisp_Object *attrs;
1537 Lisp_Object fg, bg;
1539 bg = attrs[LFACE_BACKGROUND_INDEX];
1540 fg = attrs[LFACE_FOREGROUND_INDEX];
1542 /* Swap colors if face is inverse-video. */
1543 if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
1545 Lisp_Object tmp;
1546 tmp = fg;
1547 fg = bg;
1548 bg = tmp;
1551 /* Check for support for foreground, not for background because
1552 face_color_supported_p is smart enough to know that grays are
1553 "supported" as background because we are supposed to use stipple
1554 for them. */
1555 if (!face_color_supported_p (f, XSTRING (bg)->data, 0)
1556 && !NILP (Fbitmap_spec_p (Vface_default_stipple)))
1558 x_destroy_bitmap (f, face->stipple);
1559 face->stipple = load_pixmap (f, Vface_default_stipple,
1560 &face->pixmap_w, &face->pixmap_h);
1563 face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
1564 face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
1568 /* Free color PIXEL on frame F. */
1570 void
1571 unload_color (f, pixel)
1572 struct frame *f;
1573 unsigned long pixel;
1575 #ifdef HAVE_X_WINDOWS
1576 BLOCK_INPUT;
1577 x_free_colors (f, &pixel, 1);
1578 UNBLOCK_INPUT;
1579 #endif
1583 /* Free colors allocated for FACE. */
1585 static void
1586 free_face_colors (f, face)
1587 struct frame *f;
1588 struct face *face;
1590 #ifdef HAVE_X_WINDOWS
1591 BLOCK_INPUT;
1593 if (!face->foreground_defaulted_p)
1595 x_free_colors (f, &face->foreground, 1);
1596 IF_DEBUG (--ncolors_allocated);
1599 if (!face->background_defaulted_p)
1601 x_free_colors (f, &face->background, 1);
1602 IF_DEBUG (--ncolors_allocated);
1605 if (face->underline_p
1606 && !face->underline_defaulted_p)
1608 x_free_colors (f, &face->underline_color, 1);
1609 IF_DEBUG (--ncolors_allocated);
1612 if (face->overline_p
1613 && !face->overline_color_defaulted_p)
1615 x_free_colors (f, &face->overline_color, 1);
1616 IF_DEBUG (--ncolors_allocated);
1619 if (face->strike_through_p
1620 && !face->strike_through_color_defaulted_p)
1622 x_free_colors (f, &face->strike_through_color, 1);
1623 IF_DEBUG (--ncolors_allocated);
1626 if (face->box != FACE_NO_BOX
1627 && !face->box_color_defaulted_p)
1629 x_free_colors (f, &face->box_color, 1);
1630 IF_DEBUG (--ncolors_allocated);
1633 UNBLOCK_INPUT;
1634 #endif /* HAVE_X_WINDOWS */
1637 #endif /* HAVE_WINDOW_SYSTEM */
1641 /***********************************************************************
1642 XLFD Font Names
1643 ***********************************************************************/
1645 /* An enumerator for each field of an XLFD font name. */
1647 enum xlfd_field
1649 XLFD_FOUNDRY,
1650 XLFD_FAMILY,
1651 XLFD_WEIGHT,
1652 XLFD_SLANT,
1653 XLFD_SWIDTH,
1654 XLFD_ADSTYLE,
1655 XLFD_PIXEL_SIZE,
1656 XLFD_POINT_SIZE,
1657 XLFD_RESX,
1658 XLFD_RESY,
1659 XLFD_SPACING,
1660 XLFD_AVGWIDTH,
1661 XLFD_REGISTRY,
1662 XLFD_ENCODING,
1663 XLFD_LAST
1666 /* An enumerator for each possible slant value of a font. Taken from
1667 the XLFD specification. */
1669 enum xlfd_slant
1671 XLFD_SLANT_UNKNOWN,
1672 XLFD_SLANT_ROMAN,
1673 XLFD_SLANT_ITALIC,
1674 XLFD_SLANT_OBLIQUE,
1675 XLFD_SLANT_REVERSE_ITALIC,
1676 XLFD_SLANT_REVERSE_OBLIQUE,
1677 XLFD_SLANT_OTHER
1680 /* Relative font weight according to XLFD documentation. */
1682 enum xlfd_weight
1684 XLFD_WEIGHT_UNKNOWN,
1685 XLFD_WEIGHT_ULTRA_LIGHT, /* 10 */
1686 XLFD_WEIGHT_EXTRA_LIGHT, /* 20 */
1687 XLFD_WEIGHT_LIGHT, /* 30 */
1688 XLFD_WEIGHT_SEMI_LIGHT, /* 40: SemiLight, Book, ... */
1689 XLFD_WEIGHT_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1690 XLFD_WEIGHT_SEMI_BOLD, /* 60: SemiBold, DemiBold, ... */
1691 XLFD_WEIGHT_BOLD, /* 70: Bold, ... */
1692 XLFD_WEIGHT_EXTRA_BOLD, /* 80: ExtraBold, Heavy, ... */
1693 XLFD_WEIGHT_ULTRA_BOLD /* 90: UltraBold, Black, ... */
1696 /* Relative proportionate width. */
1698 enum xlfd_swidth
1700 XLFD_SWIDTH_UNKNOWN,
1701 XLFD_SWIDTH_ULTRA_CONDENSED, /* 10 */
1702 XLFD_SWIDTH_EXTRA_CONDENSED, /* 20 */
1703 XLFD_SWIDTH_CONDENSED, /* 30: Condensed, Narrow, Compressed, ... */
1704 XLFD_SWIDTH_SEMI_CONDENSED, /* 40: semicondensed */
1705 XLFD_SWIDTH_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1706 XLFD_SWIDTH_SEMI_EXPANDED, /* 60: SemiExpanded, DemiExpanded, ... */
1707 XLFD_SWIDTH_EXPANDED, /* 70: Expanded... */
1708 XLFD_SWIDTH_EXTRA_EXPANDED, /* 80: ExtraExpanded, Wide... */
1709 XLFD_SWIDTH_ULTRA_EXPANDED /* 90: UltraExpanded... */
1712 /* Structure used for tables mapping XLFD weight, slant, and width
1713 names to numeric and symbolic values. */
1715 struct table_entry
1717 char *name;
1718 int numeric;
1719 Lisp_Object *symbol;
1722 /* Table of XLFD slant names and their numeric and symbolic
1723 representations. This table must be sorted by slant names in
1724 ascending order. */
1726 static struct table_entry slant_table[] =
1728 {"i", XLFD_SLANT_ITALIC, &Qitalic},
1729 {"o", XLFD_SLANT_OBLIQUE, &Qoblique},
1730 {"ot", XLFD_SLANT_OTHER, &Qitalic},
1731 {"r", XLFD_SLANT_ROMAN, &Qnormal},
1732 {"ri", XLFD_SLANT_REVERSE_ITALIC, &Qreverse_italic},
1733 {"ro", XLFD_SLANT_REVERSE_OBLIQUE, &Qreverse_oblique}
1736 /* Table of XLFD weight names. This table must be sorted by weight
1737 names in ascending order. */
1739 static struct table_entry weight_table[] =
1741 {"black", XLFD_WEIGHT_ULTRA_BOLD, &Qultra_bold},
1742 {"bold", XLFD_WEIGHT_BOLD, &Qbold},
1743 {"book", XLFD_WEIGHT_SEMI_LIGHT, &Qsemi_light},
1744 {"demibold", XLFD_WEIGHT_SEMI_BOLD, &Qsemi_bold},
1745 {"extralight", XLFD_WEIGHT_EXTRA_LIGHT, &Qextra_light},
1746 {"extrabold", XLFD_WEIGHT_EXTRA_BOLD, &Qextra_bold},
1747 {"heavy", XLFD_WEIGHT_EXTRA_BOLD, &Qextra_bold},
1748 {"light", XLFD_WEIGHT_LIGHT, &Qlight},
1749 {"medium", XLFD_WEIGHT_MEDIUM, &Qnormal},
1750 {"normal", XLFD_WEIGHT_MEDIUM, &Qnormal},
1751 {"regular", XLFD_WEIGHT_MEDIUM, &Qnormal},
1752 {"semibold", XLFD_WEIGHT_SEMI_BOLD, &Qsemi_bold},
1753 {"semilight", XLFD_WEIGHT_SEMI_LIGHT, &Qsemi_light},
1754 {"ultralight", XLFD_WEIGHT_ULTRA_LIGHT, &Qultra_light},
1755 {"ultrabold", XLFD_WEIGHT_ULTRA_BOLD, &Qultra_bold}
1758 /* Table of XLFD width names. This table must be sorted by width
1759 names in ascending order. */
1761 static struct table_entry swidth_table[] =
1763 {"compressed", XLFD_SWIDTH_CONDENSED, &Qcondensed},
1764 {"condensed", XLFD_SWIDTH_CONDENSED, &Qcondensed},
1765 {"demiexpanded", XLFD_SWIDTH_SEMI_EXPANDED, &Qsemi_expanded},
1766 {"expanded", XLFD_SWIDTH_EXPANDED, &Qexpanded},
1767 {"extracondensed", XLFD_SWIDTH_EXTRA_CONDENSED, &Qextra_condensed},
1768 {"extraexpanded", XLFD_SWIDTH_EXTRA_EXPANDED, &Qextra_expanded},
1769 {"medium", XLFD_SWIDTH_MEDIUM, &Qnormal},
1770 {"narrow", XLFD_SWIDTH_CONDENSED, &Qcondensed},
1771 {"normal", XLFD_SWIDTH_MEDIUM, &Qnormal},
1772 {"regular", XLFD_SWIDTH_MEDIUM, &Qnormal},
1773 {"semicondensed", XLFD_SWIDTH_SEMI_CONDENSED, &Qsemi_condensed},
1774 {"semiexpanded", XLFD_SWIDTH_SEMI_EXPANDED, &Qsemi_expanded},
1775 {"ultracondensed", XLFD_SWIDTH_ULTRA_CONDENSED, &Qultra_condensed},
1776 {"ultraexpanded", XLFD_SWIDTH_ULTRA_EXPANDED, &Qultra_expanded},
1777 {"wide", XLFD_SWIDTH_EXTRA_EXPANDED, &Qextra_expanded}
1780 /* Structure used to hold the result of splitting font names in XLFD
1781 format into their fields. */
1783 struct font_name
1785 /* The original name which is modified destructively by
1786 split_font_name. The pointer is kept here to be able to free it
1787 if it was allocated from the heap. */
1788 char *name;
1790 /* Font name fields. Each vector element points into `name' above.
1791 Fields are NUL-terminated. */
1792 char *fields[XLFD_LAST];
1794 /* Numeric values for those fields that interest us. See
1795 split_font_name for which these are. */
1796 int numeric[XLFD_LAST];
1799 /* The frame in effect when sorting font names. Set temporarily in
1800 sort_fonts so that it is available in font comparison functions. */
1802 static struct frame *font_frame;
1804 /* Order by which font selection chooses fonts. The default values
1805 mean `first, find a best match for the font width, then for the
1806 font height, then for weight, then for slant.' This variable can be
1807 set via set-face-font-sort-order. */
1809 static int font_sort_order[4];
1812 /* Look up FONT.fields[FIELD_INDEX] in TABLE which has DIM entries.
1813 TABLE must be sorted by TABLE[i]->name in ascending order. Value
1814 is a pointer to the matching table entry or null if no table entry
1815 matches. */
1817 static struct table_entry *
1818 xlfd_lookup_field_contents (table, dim, font, field_index)
1819 struct table_entry *table;
1820 int dim;
1821 struct font_name *font;
1822 int field_index;
1824 /* Function split_font_name converts fields to lower-case, so there
1825 is no need to use xstrlwr or xstricmp here. */
1826 char *s = font->fields[field_index];
1827 int low, mid, high, cmp;
1829 low = 0;
1830 high = dim - 1;
1832 while (low <= high)
1834 mid = (low + high) / 2;
1835 cmp = strcmp (table[mid].name, s);
1837 if (cmp < 0)
1838 low = mid + 1;
1839 else if (cmp > 0)
1840 high = mid - 1;
1841 else
1842 return table + mid;
1845 return NULL;
1849 /* Return a numeric representation for font name field
1850 FONT.fields[FIELD_INDEX]. The field is looked up in TABLE which
1851 has DIM entries. Value is the numeric value found or DFLT if no
1852 table entry matches. This function is used to translate weight,
1853 slant, and swidth names of XLFD font names to numeric values. */
1855 static INLINE int
1856 xlfd_numeric_value (table, dim, font, field_index, dflt)
1857 struct table_entry *table;
1858 int dim;
1859 struct font_name *font;
1860 int field_index;
1861 int dflt;
1863 struct table_entry *p;
1864 p = xlfd_lookup_field_contents (table, dim, font, field_index);
1865 return p ? p->numeric : dflt;
1869 /* Return a symbolic representation for font name field
1870 FONT.fields[FIELD_INDEX]. The field is looked up in TABLE which
1871 has DIM entries. Value is the symbolic value found or DFLT if no
1872 table entry matches. This function is used to translate weight,
1873 slant, and swidth names of XLFD font names to symbols. */
1875 static INLINE Lisp_Object
1876 xlfd_symbolic_value (table, dim, font, field_index, dflt)
1877 struct table_entry *table;
1878 int dim;
1879 struct font_name *font;
1880 int field_index;
1881 Lisp_Object dflt;
1883 struct table_entry *p;
1884 p = xlfd_lookup_field_contents (table, dim, font, field_index);
1885 return p ? *p->symbol : dflt;
1889 /* Return a numeric value for the slant of the font given by FONT. */
1891 static INLINE int
1892 xlfd_numeric_slant (font)
1893 struct font_name *font;
1895 return xlfd_numeric_value (slant_table, DIM (slant_table),
1896 font, XLFD_SLANT, XLFD_SLANT_ROMAN);
1900 /* Return a symbol representing the weight of the font given by FONT. */
1902 static INLINE Lisp_Object
1903 xlfd_symbolic_slant (font)
1904 struct font_name *font;
1906 return xlfd_symbolic_value (slant_table, DIM (slant_table),
1907 font, XLFD_SLANT, Qnormal);
1911 /* Return a numeric value for the weight of the font given by FONT. */
1913 static INLINE int
1914 xlfd_numeric_weight (font)
1915 struct font_name *font;
1917 return xlfd_numeric_value (weight_table, DIM (weight_table),
1918 font, XLFD_WEIGHT, XLFD_WEIGHT_MEDIUM);
1922 /* Return a symbol representing the slant of the font given by FONT. */
1924 static INLINE Lisp_Object
1925 xlfd_symbolic_weight (font)
1926 struct font_name *font;
1928 return xlfd_symbolic_value (weight_table, DIM (weight_table),
1929 font, XLFD_WEIGHT, Qnormal);
1933 /* Return a numeric value for the swidth of the font whose XLFD font
1934 name fields are found in FONT. */
1936 static INLINE int
1937 xlfd_numeric_swidth (font)
1938 struct font_name *font;
1940 return xlfd_numeric_value (swidth_table, DIM (swidth_table),
1941 font, XLFD_SWIDTH, XLFD_SWIDTH_MEDIUM);
1945 /* Return a symbolic value for the swidth of FONT. */
1947 static INLINE Lisp_Object
1948 xlfd_symbolic_swidth (font)
1949 struct font_name *font;
1951 return xlfd_symbolic_value (swidth_table, DIM (swidth_table),
1952 font, XLFD_SWIDTH, Qnormal);
1956 /* Look up the entry of SYMBOL in the vector TABLE which has DIM
1957 entries. Value is a pointer to the matching table entry or null if
1958 no element of TABLE contains SYMBOL. */
1960 static struct table_entry *
1961 face_value (table, dim, symbol)
1962 struct table_entry *table;
1963 int dim;
1964 Lisp_Object symbol;
1966 int i;
1968 xassert (SYMBOLP (symbol));
1970 for (i = 0; i < dim; ++i)
1971 if (EQ (*table[i].symbol, symbol))
1972 break;
1974 return i < dim ? table + i : NULL;
1978 /* Return a numeric value for SYMBOL in the vector TABLE which has DIM
1979 entries. Value is -1 if SYMBOL is not found in TABLE. */
1981 static INLINE int
1982 face_numeric_value (table, dim, symbol)
1983 struct table_entry *table;
1984 int dim;
1985 Lisp_Object symbol;
1987 struct table_entry *p = face_value (table, dim, symbol);
1988 return p ? p->numeric : -1;
1992 /* Return a numeric value representing the weight specified by Lisp
1993 symbol WEIGHT. Value is one of the enumerators of enum
1994 xlfd_weight. */
1996 static INLINE int
1997 face_numeric_weight (weight)
1998 Lisp_Object weight;
2000 return face_numeric_value (weight_table, DIM (weight_table), weight);
2004 /* Return a numeric value representing the slant specified by Lisp
2005 symbol SLANT. Value is one of the enumerators of enum xlfd_slant. */
2007 static INLINE int
2008 face_numeric_slant (slant)
2009 Lisp_Object slant;
2011 return face_numeric_value (slant_table, DIM (slant_table), slant);
2015 /* Return a numeric value representing the swidth specified by Lisp
2016 symbol WIDTH. Value is one of the enumerators of enum xlfd_swidth. */
2018 static int
2019 face_numeric_swidth (width)
2020 Lisp_Object width;
2022 return face_numeric_value (swidth_table, DIM (swidth_table), width);
2026 #ifdef HAVE_WINDOW_SYSTEM
2028 /* Return non-zero if FONT is the name of a fixed-pitch font. */
2030 static INLINE int
2031 xlfd_fixed_p (font)
2032 struct font_name *font;
2034 /* Function split_font_name converts fields to lower-case, so there
2035 is no need to use tolower here. */
2036 return *font->fields[XLFD_SPACING] != 'p';
2040 /* Return the point size of FONT on frame F, measured in 1/10 pt.
2042 The actual height of the font when displayed on F depends on the
2043 resolution of both the font and frame. For example, a 10pt font
2044 designed for a 100dpi display will display larger than 10pt on a
2045 75dpi display. (It's not unusual to use fonts not designed for the
2046 display one is using. For example, some intlfonts are available in
2047 72dpi versions, only.)
2049 Value is the real point size of FONT on frame F, or 0 if it cannot
2050 be determined. */
2052 static INLINE int
2053 xlfd_point_size (f, font)
2054 struct frame *f;
2055 struct font_name *font;
2057 double resy = FRAME_X_DISPLAY_INFO (f)->resy;
2058 double font_resy = atoi (font->fields[XLFD_RESY]);
2059 double font_pt = atoi (font->fields[XLFD_POINT_SIZE]);
2060 int real_pt;
2062 if (font_resy == 0 || font_pt == 0)
2063 real_pt = 0;
2064 else
2065 real_pt = (font_resy / resy) * font_pt + 0.5;
2067 return real_pt;
2071 /* Return point size of PIXEL dots while considering Y-resultion (DPI)
2072 of frame F. This function is used to guess a point size of font
2073 when only the pixel height of the font is available. */
2075 static INLINE int
2076 pixel_point_size (f, pixel)
2077 struct frame *f;
2078 int pixel;
2080 double resy = FRAME_X_DISPLAY_INFO (f)->resy;
2081 double real_pt;
2082 int int_pt;
2084 /* As one inch is 72 points, 72/RESY gives the point size of one dot. */
2085 real_pt = pixel * 72 / resy;
2086 int_pt = real_pt + 0.5;
2088 return int_pt;
2092 /* Split XLFD font name FONT->name destructively into NUL-terminated,
2093 lower-case fields in FONT->fields. NUMERIC_P non-zero means
2094 compute numeric values for fields XLFD_POINT_SIZE, XLFD_SWIDTH,
2095 XLFD_RESY, XLFD_SLANT, and XLFD_WEIGHT in FONT->numeric. Value is
2096 zero if the font name doesn't have the format we expect. The
2097 expected format is a font name that starts with a `-' and has
2098 XLFD_LAST fields separated by `-'. (The XLFD specification allows
2099 forms of font names where certain field contents are enclosed in
2100 square brackets. We don't support that, for now. */
2102 static int
2103 split_font_name (f, font, numeric_p)
2104 struct frame *f;
2105 struct font_name *font;
2106 int numeric_p;
2108 int i = 0;
2109 int success_p;
2111 if (*font->name == '-')
2113 char *p = xstrlwr (font->name) + 1;
2115 while (i < XLFD_LAST)
2117 font->fields[i] = p;
2118 ++i;
2120 while (*p && *p != '-')
2121 ++p;
2123 if (*p != '-')
2124 break;
2126 *p++ = 0;
2130 success_p = i == XLFD_LAST;
2132 /* If requested, and font name was in the expected format,
2133 compute numeric values for some fields. */
2134 if (numeric_p && success_p)
2136 font->numeric[XLFD_POINT_SIZE] = xlfd_point_size (f, font);
2137 font->numeric[XLFD_RESY] = atoi (font->fields[XLFD_RESY]);
2138 font->numeric[XLFD_SLANT] = xlfd_numeric_slant (font);
2139 font->numeric[XLFD_WEIGHT] = xlfd_numeric_weight (font);
2140 font->numeric[XLFD_SWIDTH] = xlfd_numeric_swidth (font);
2143 return success_p;
2147 /* Build an XLFD font name from font name fields in FONT. Value is a
2148 pointer to the font name, which is allocated via xmalloc. */
2150 static char *
2151 build_font_name (font)
2152 struct font_name *font;
2154 int i;
2155 int size = 100;
2156 char *font_name = (char *) xmalloc (size);
2157 int total_length = 0;
2159 for (i = 0; i < XLFD_LAST; ++i)
2161 /* Add 1 because of the leading `-'. */
2162 int len = strlen (font->fields[i]) + 1;
2164 /* Reallocate font_name if necessary. Add 1 for the final
2165 NUL-byte. */
2166 if (total_length + len + 1 >= size)
2168 int new_size = max (2 * size, size + len + 1);
2169 int sz = new_size * sizeof *font_name;
2170 font_name = (char *) xrealloc (font_name, sz);
2171 size = new_size;
2174 font_name[total_length] = '-';
2175 bcopy (font->fields[i], font_name + total_length + 1, len - 1);
2176 total_length += len;
2179 font_name[total_length] = 0;
2180 return font_name;
2184 /* Free an array FONTS of N font_name structures. This frees FONTS
2185 itself and all `name' fields in its elements. */
2187 static INLINE void
2188 free_font_names (fonts, n)
2189 struct font_name *fonts;
2190 int n;
2192 while (n)
2193 xfree (fonts[--n].name);
2194 xfree (fonts);
2198 /* Sort vector FONTS of font_name structures which contains NFONTS
2199 elements using qsort and comparison function CMPFN. F is the frame
2200 on which the fonts will be used. The global variable font_frame
2201 is temporarily set to F to make it available in CMPFN. */
2203 static INLINE void
2204 sort_fonts (f, fonts, nfonts, cmpfn)
2205 struct frame *f;
2206 struct font_name *fonts;
2207 int nfonts;
2208 int (*cmpfn) P_ ((const void *, const void *));
2210 font_frame = f;
2211 qsort (fonts, nfonts, sizeof *fonts, cmpfn);
2212 font_frame = NULL;
2216 /* Get fonts matching PATTERN on frame F. If F is null, use the first
2217 display in x_display_list. FONTS is a pointer to a vector of
2218 NFONTS font_name structures. TRY_ALTERNATIVES_P non-zero means try
2219 alternative patterns from Valternate_fontname_alist if no fonts are
2220 found matching PATTERN. SCALABLE_FONTS_P non-zero means include
2221 scalable fonts.
2223 For all fonts found, set FONTS[i].name to the name of the font,
2224 allocated via xmalloc, and split font names into fields. Ignore
2225 fonts that we can't parse. Value is the number of fonts found.
2227 This is similar to x_list_fonts. The differences are:
2229 1. It avoids consing.
2230 2. It never calls XLoadQueryFont. */
2232 static int
2233 x_face_list_fonts (f, pattern, fonts, nfonts, try_alternatives_p,
2234 scalable_fonts_p)
2235 struct frame *f;
2236 char *pattern;
2237 struct font_name *fonts;
2238 int nfonts, try_alternatives_p;
2239 int scalable_fonts_p;
2241 int n, i, j;
2242 char **names;
2243 #ifdef HAVE_X_WINDOWS
2244 Display *dpy = f ? FRAME_X_DISPLAY (f) : x_display_list->display;
2246 /* Get the list of fonts matching PATTERN from the X server. */
2247 BLOCK_INPUT;
2248 names = XListFonts (dpy, pattern, nfonts, &n);
2249 UNBLOCK_INPUT;
2250 #endif
2251 #ifdef WINDOWSNT
2252 /* NTEMACS_TODO : currently this uses w32_list_fonts, but it may be
2253 better to do it the other way around. */
2254 Lisp_Object lfonts;
2255 Lisp_Object lpattern, tem;
2257 n = 0;
2258 names = NULL;
2260 lpattern = build_string (pattern);
2262 /* Get the list of fonts matching PATTERN. */
2263 BLOCK_INPUT;
2264 lfonts = w32_list_fonts (f, lpattern, 0, nfonts);
2265 UNBLOCK_INPUT;
2267 /* Count fonts returned */
2268 for (tem = lfonts; CONSP (tem); tem = XCDR (tem))
2269 n++;
2271 /* Allocate array. */
2272 if (n)
2273 names = (char **) xmalloc (n * sizeof (char *));
2275 /* Extract font names into char * array. */
2276 tem = lfonts;
2277 for (i = 0; i < n; i++)
2279 names[i] = XSTRING (XCAR (tem))->data;
2280 tem = XCDR (tem);
2282 #endif
2284 if (names)
2286 /* Make a copy of the font names we got from X, and
2287 split them into fields. */
2288 for (i = j = 0; i < n; ++i)
2290 /* Make a copy of the font name. */
2291 fonts[j].name = xstrdup (names[i]);
2293 /* Ignore fonts having a name that we can't parse. */
2294 if (!split_font_name (f, fonts + j, 1))
2295 xfree (fonts[j].name);
2296 else if (font_scalable_p (fonts + j))
2298 #if SCALABLE_FONTS
2299 if (!scalable_fonts_p
2300 || !may_use_scalable_font_p (fonts + j, names[i]))
2301 xfree (fonts[j].name);
2302 else
2303 ++j;
2304 #else /* !SCALABLE_FONTS */
2305 /* Always ignore scalable fonts. */
2306 xfree (fonts[j].name);
2307 #endif /* !SCALABLE_FONTS */
2309 else
2310 ++j;
2313 n = j;
2315 #ifdef HAVE_X_WINDOWS
2316 /* Free font names. */
2317 BLOCK_INPUT;
2318 XFreeFontNames (names);
2319 UNBLOCK_INPUT;
2320 #endif
2324 /* If no fonts found, try patterns from Valternate_fontname_alist. */
2325 if (n == 0 && try_alternatives_p)
2327 Lisp_Object list = Valternate_fontname_alist;
2329 while (CONSP (list))
2331 Lisp_Object entry = XCAR (list);
2332 if (CONSP (entry)
2333 && STRINGP (XCAR (entry))
2334 && strcmp (XSTRING (XCAR (entry))->data, pattern) == 0)
2335 break;
2336 list = XCDR (list);
2339 if (CONSP (list))
2341 Lisp_Object patterns = XCAR (list);
2342 Lisp_Object name;
2344 while (CONSP (patterns)
2345 /* If list is screwed up, give up. */
2346 && (name = XCAR (patterns),
2347 STRINGP (name))
2348 /* Ignore patterns equal to PATTERN because we tried that
2349 already with no success. */
2350 && (strcmp (XSTRING (name)->data, pattern) == 0
2351 || (n = x_face_list_fonts (f, XSTRING (name)->data,
2352 fonts, nfonts, 0,
2353 scalable_fonts_p),
2354 n == 0)))
2355 patterns = XCDR (patterns);
2359 return n;
2363 /* Determine the first font matching PATTERN on frame F. Return in
2364 *FONT the matching font name, split into fields. Value is non-zero
2365 if a match was found. */
2367 static int
2368 first_font_matching (f, pattern, font)
2369 struct frame *f;
2370 char *pattern;
2371 struct font_name *font;
2373 int nfonts = 100;
2374 struct font_name *fonts;
2376 fonts = (struct font_name *) xmalloc (nfonts * sizeof *fonts);
2377 nfonts = x_face_list_fonts (f, pattern, fonts, nfonts, 1, 0);
2379 if (nfonts > 0)
2381 bcopy (&fonts[0], font, sizeof *font);
2383 fonts[0].name = NULL;
2384 free_font_names (fonts, nfonts);
2387 return nfonts > 0;
2391 /* Determine fonts matching PATTERN on frame F. Sort resulting fonts
2392 using comparison function CMPFN. Value is the number of fonts
2393 found. If value is non-zero, *FONTS is set to a vector of
2394 font_name structures allocated from the heap containing matching
2395 fonts. Each element of *FONTS contains a name member that is also
2396 allocated from the heap. Font names in these structures are split
2397 into fields. Use free_font_names to free such an array. */
2399 static int
2400 sorted_font_list (f, pattern, cmpfn, fonts)
2401 struct frame *f;
2402 char *pattern;
2403 int (*cmpfn) P_ ((const void *, const void *));
2404 struct font_name **fonts;
2406 int nfonts;
2408 /* Get the list of fonts matching pattern. 100 should suffice. */
2409 nfonts = DEFAULT_FONT_LIST_LIMIT;
2410 if (INTEGERP (Vfont_list_limit) && XINT (Vfont_list_limit) > 0)
2411 nfonts = XFASTINT (Vfont_list_limit);
2413 *fonts = (struct font_name *) xmalloc (nfonts * sizeof **fonts);
2414 #if SCALABLE_FONTS
2415 nfonts = x_face_list_fonts (f, pattern, *fonts, nfonts, 1, 1);
2416 #else
2417 nfonts = x_face_list_fonts (f, pattern, *fonts, nfonts, 1, 0);
2418 #endif
2420 /* Sort the resulting array and return it in *FONTS. If no
2421 fonts were found, make sure to set *FONTS to null. */
2422 if (nfonts)
2423 sort_fonts (f, *fonts, nfonts, cmpfn);
2424 else
2426 xfree (*fonts);
2427 *fonts = NULL;
2430 return nfonts;
2434 /* Compare two font_name structures *A and *B. Value is analogous to
2435 strcmp. Sort order is given by the global variable
2436 font_sort_order. Font names are sorted so that, everything else
2437 being equal, fonts with a resolution closer to that of the frame on
2438 which they are used are listed first. The global variable
2439 font_frame is the frame on which we operate. */
2441 static int
2442 cmp_font_names (a, b)
2443 const void *a, *b;
2445 struct font_name *x = (struct font_name *) a;
2446 struct font_name *y = (struct font_name *) b;
2447 int cmp;
2449 /* All strings have been converted to lower-case by split_font_name,
2450 so we can use strcmp here. */
2451 cmp = strcmp (x->fields[XLFD_FAMILY], y->fields[XLFD_FAMILY]);
2452 if (cmp == 0)
2454 int i;
2456 for (i = 0; i < DIM (font_sort_order) && cmp == 0; ++i)
2458 int j = font_sort_order[i];
2459 cmp = x->numeric[j] - y->numeric[j];
2462 if (cmp == 0)
2464 /* Everything else being equal, we prefer fonts with an
2465 y-resolution closer to that of the frame. */
2466 int resy = FRAME_X_DISPLAY_INFO (font_frame)->resy;
2467 int x_resy = x->numeric[XLFD_RESY];
2468 int y_resy = y->numeric[XLFD_RESY];
2469 cmp = abs (resy - x_resy) - abs (resy - y_resy);
2473 return cmp;
2477 /* Get a sorted list of fonts of family FAMILY on frame F. If PATTERN
2478 is non-nil list fonts matching that pattern. Otherwise, if
2479 REGISTRY is non-nil return only fonts with that registry, otherwise
2480 return fonts of any registry. Set *FONTS to a vector of font_name
2481 structures allocated from the heap containing the fonts found.
2482 Value is the number of fonts found. */
2484 static int
2485 font_list (f, pattern, family, registry, fonts)
2486 struct frame *f;
2487 Lisp_Object pattern, family, registry;
2488 struct font_name **fonts;
2490 char *pattern_str, *family_str, *registry_str;
2492 if (NILP (pattern))
2494 family_str = (NILP (family) ? "*" : (char *) XSTRING (family)->data);
2495 registry_str = (NILP (registry) ? "*" : (char *) XSTRING (registry)->data);
2497 pattern_str = (char *) alloca (strlen (family_str)
2498 + strlen (registry_str)
2499 + 10);
2500 strcpy (pattern_str, index (family_str, '-') ? "-" : "-*-");
2501 strcat (pattern_str, family_str);
2502 strcat (pattern_str, "-*-");
2503 strcat (pattern_str, registry_str);
2504 if (!index (registry_str, '-'))
2506 if (registry_str[strlen (registry_str) - 1] == '*')
2507 strcat (pattern_str, "-*");
2508 else
2509 strcat (pattern_str, "*-*");
2512 else
2513 pattern_str = (char *) XSTRING (pattern)->data;
2515 return sorted_font_list (f, pattern_str, cmp_font_names, fonts);
2519 /* Remove elements from LIST whose cars are `equal'. Called from
2520 x-family-fonts and x-font-family-list to remove duplicate font
2521 entries. */
2523 static void
2524 remove_duplicates (list)
2525 Lisp_Object list;
2527 Lisp_Object tail = list;
2529 while (!NILP (tail) && !NILP (XCDR (tail)))
2531 Lisp_Object next = XCDR (tail);
2532 if (!NILP (Fequal (XCAR (next), XCAR (tail))))
2533 XCDR (tail) = XCDR (next);
2534 else
2535 tail = XCDR (tail);
2540 DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0,
2541 "Return a list of available fonts of family FAMILY on FRAME.\n\
2542 If FAMILY is omitted or nil, list all families.\n\
2543 Otherwise, FAMILY must be a string, possibly containing wildcards\n\
2544 `?' and `*'.\n\
2545 If FRAME is omitted or nil, use the selected frame.\n\
2546 Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT\n\
2547 SLANT FIXED-P FULL REGISTRY-AND-ENCODING].\n\
2548 FAMILY is the font family name. POINT-SIZE is the size of the\n\
2549 font in 1/10 pt. WIDTH, WEIGHT, and SLANT are symbols describing the\n\
2550 width, weight and slant of the font. These symbols are the same as for\n\
2551 face attributes. FIXED-P is non-nil if the font is fixed-pitch.\n\
2552 FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string\n\
2553 giving the registry and encoding of the font.\n\
2554 The result list is sorted according to the current setting of\n\
2555 the face font sort order.")
2556 (family, frame)
2557 Lisp_Object family, frame;
2559 struct frame *f = check_x_frame (frame);
2560 struct font_name *fonts;
2561 int i, nfonts;
2562 Lisp_Object result;
2563 struct gcpro gcpro1;
2565 if (!NILP (family))
2566 CHECK_STRING (family, 1);
2568 result = Qnil;
2569 GCPRO1 (result);
2570 nfonts = font_list (f, Qnil, family, Qnil, &fonts);
2571 for (i = nfonts - 1; i >= 0; --i)
2573 Lisp_Object v = Fmake_vector (make_number (8), Qnil);
2574 char *tem;
2576 ASET (v, 0, build_string (fonts[i].fields[XLFD_FAMILY]));
2577 ASET (v, 1, xlfd_symbolic_swidth (fonts + i));
2578 ASET (v, 2, make_number (xlfd_point_size (f, fonts + i)));
2579 ASET (v, 3, xlfd_symbolic_weight (fonts + i));
2580 ASET (v, 4, xlfd_symbolic_slant (fonts + i));
2581 ASET (v, 5, xlfd_fixed_p (fonts + i) ? Qt : Qnil);
2582 tem = build_font_name (fonts + i);
2583 ASET (v, 6, build_string (tem));
2584 sprintf (tem, "%s-%s", fonts[i].fields[XLFD_REGISTRY],
2585 fonts[i].fields[XLFD_ENCODING]);
2586 ASET (v, 7, build_string (tem));
2587 xfree (tem);
2589 result = Fcons (v, result);
2592 remove_duplicates (result);
2593 free_font_names (fonts, nfonts);
2594 UNGCPRO;
2595 return result;
2599 DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
2600 0, 1, 0,
2601 "Return a list of available font families on FRAME.\n\
2602 If FRAME is omitted or nil, use the selected frame.\n\
2603 Value is a list of conses (FAMILY . FIXED-P) where FAMILY\n\
2604 is a font family, and FIXED-P is non-nil if fonts of that family\n\
2605 are fixed-pitch.")
2606 (frame)
2607 Lisp_Object frame;
2609 struct frame *f = check_x_frame (frame);
2610 int nfonts, i;
2611 struct font_name *fonts;
2612 Lisp_Object result;
2613 struct gcpro gcpro1;
2614 int count = specpdl_ptr - specpdl;
2615 int limit;
2617 /* Let's consider all fonts. Increase the limit for matching
2618 fonts until we have them all. */
2619 for (limit = 500;;)
2621 specbind (intern ("font-list-limit"), make_number (limit));
2622 nfonts = font_list (f, Qnil, Qnil, Qnil, &fonts);
2624 if (nfonts == limit)
2626 free_font_names (fonts, nfonts);
2627 limit *= 2;
2629 else
2630 break;
2633 result = Qnil;
2634 GCPRO1 (result);
2635 for (i = nfonts - 1; i >= 0; --i)
2636 result = Fcons (Fcons (build_string (fonts[i].fields[XLFD_FAMILY]),
2637 xlfd_fixed_p (fonts + i) ? Qt : Qnil),
2638 result);
2640 remove_duplicates (result);
2641 free_font_names (fonts, nfonts);
2642 UNGCPRO;
2643 return unbind_to (count, result);
2647 DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
2648 "Return a list of the names of available fonts matching PATTERN.\n\
2649 If optional arguments FACE and FRAME are specified, return only fonts\n\
2650 the same size as FACE on FRAME.\n\
2651 PATTERN is a string, perhaps with wildcard characters;\n\
2652 the * character matches any substring, and\n\
2653 the ? character matches any single character.\n\
2654 PATTERN is case-insensitive.\n\
2655 FACE is a face name--a symbol.\n\
2657 The return value is a list of strings, suitable as arguments to\n\
2658 set-face-font.\n\
2660 Fonts Emacs can't use may or may not be excluded\n\
2661 even if they match PATTERN and FACE.\n\
2662 The optional fourth argument MAXIMUM sets a limit on how many\n\
2663 fonts to match. The first MAXIMUM fonts are reported.\n\
2664 The optional fifth argument WIDTH, if specified, is a number of columns\n\
2665 occupied by a character of a font. In that case, return only fonts\n\
2666 the WIDTH times as wide as FACE on FRAME.")
2667 (pattern, face, frame, maximum, width)
2668 Lisp_Object pattern, face, frame, maximum, width;
2670 struct frame *f;
2671 int size;
2672 int maxnames;
2674 check_x ();
2675 CHECK_STRING (pattern, 0);
2677 if (NILP (maximum))
2678 maxnames = 2000;
2679 else
2681 CHECK_NATNUM (maximum, 0);
2682 maxnames = XINT (maximum);
2685 if (!NILP (width))
2686 CHECK_NUMBER (width, 4);
2688 /* We can't simply call check_x_frame because this function may be
2689 called before any frame is created. */
2690 f = frame_or_selected_frame (frame, 2);
2691 if (!FRAME_WINDOW_P (f))
2693 /* Perhaps we have not yet created any frame. */
2694 f = NULL;
2695 face = Qnil;
2698 /* Determine the width standard for comparison with the fonts we find. */
2700 if (NILP (face))
2701 size = 0;
2702 else
2704 /* This is of limited utility since it works with character
2705 widths. Keep it for compatibility. --gerd. */
2706 int face_id = lookup_named_face (f, face, 0);
2707 struct face *face = FACE_FROM_ID (f, face_id);
2709 if (face->font)
2710 size = FONT_WIDTH (face->font);
2711 else
2712 size = FONT_WIDTH (FRAME_FONT (f));
2714 if (!NILP (width))
2715 size *= XINT (width);
2719 Lisp_Object args[2];
2721 args[0] = x_list_fonts (f, pattern, size, maxnames);
2722 if (f == NULL)
2723 /* We don't have to check fontsets. */
2724 return args[0];
2725 args[1] = list_fontsets (f, pattern, size);
2726 return Fnconc (2, args);
2730 #endif /* HAVE_WINDOW_SYSTEM */
2734 /***********************************************************************
2735 Lisp Faces
2736 ***********************************************************************/
2738 /* Access face attributes of face FACE, a Lisp vector. */
2740 #define LFACE_FAMILY(LFACE) \
2741 XVECTOR (LFACE)->contents[LFACE_FAMILY_INDEX]
2742 #define LFACE_HEIGHT(LFACE) \
2743 XVECTOR (LFACE)->contents[LFACE_HEIGHT_INDEX]
2744 #define LFACE_WEIGHT(LFACE) \
2745 XVECTOR (LFACE)->contents[LFACE_WEIGHT_INDEX]
2746 #define LFACE_SLANT(LFACE) \
2747 XVECTOR (LFACE)->contents[LFACE_SLANT_INDEX]
2748 #define LFACE_UNDERLINE(LFACE) \
2749 XVECTOR (LFACE)->contents[LFACE_UNDERLINE_INDEX]
2750 #define LFACE_INVERSE(LFACE) \
2751 XVECTOR (LFACE)->contents[LFACE_INVERSE_INDEX]
2752 #define LFACE_FOREGROUND(LFACE) \
2753 XVECTOR (LFACE)->contents[LFACE_FOREGROUND_INDEX]
2754 #define LFACE_BACKGROUND(LFACE) \
2755 XVECTOR (LFACE)->contents[LFACE_BACKGROUND_INDEX]
2756 #define LFACE_STIPPLE(LFACE) \
2757 XVECTOR (LFACE)->contents[LFACE_STIPPLE_INDEX]
2758 #define LFACE_SWIDTH(LFACE) \
2759 XVECTOR (LFACE)->contents[LFACE_SWIDTH_INDEX]
2760 #define LFACE_OVERLINE(LFACE) \
2761 XVECTOR (LFACE)->contents[LFACE_OVERLINE_INDEX]
2762 #define LFACE_STRIKE_THROUGH(LFACE) \
2763 XVECTOR (LFACE)->contents[LFACE_STRIKE_THROUGH_INDEX]
2764 #define LFACE_BOX(LFACE) \
2765 XVECTOR (LFACE)->contents[LFACE_BOX_INDEX]
2766 #define LFACE_FONT(LFACE) \
2767 XVECTOR (LFACE)->contents[LFACE_FONT_INDEX]
2768 #define LFACE_INHERIT(LFACE) \
2769 XVECTOR (LFACE)->contents[LFACE_INHERIT_INDEX]
2771 /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size
2772 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */
2774 #define LFACEP(LFACE) \
2775 (VECTORP (LFACE) \
2776 && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE \
2777 && EQ (XVECTOR (LFACE)->contents[0], Qface))
2780 #if GLYPH_DEBUG
2782 /* Check consistency of Lisp face attribute vector ATTRS. */
2784 static void
2785 check_lface_attrs (attrs)
2786 Lisp_Object *attrs;
2788 xassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
2789 || STRINGP (attrs[LFACE_FAMILY_INDEX]));
2790 xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
2791 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
2792 xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
2793 || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
2794 || FLOATP (attrs[LFACE_HEIGHT_INDEX])
2795 || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX]));
2796 xassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
2797 || SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
2798 xassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
2799 || SYMBOLP (attrs[LFACE_SLANT_INDEX]));
2800 xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
2801 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
2802 || STRINGP (attrs[LFACE_UNDERLINE_INDEX]));
2803 xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
2804 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
2805 || STRINGP (attrs[LFACE_OVERLINE_INDEX]));
2806 xassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
2807 || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
2808 || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
2809 xassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
2810 || SYMBOLP (attrs[LFACE_BOX_INDEX])
2811 || STRINGP (attrs[LFACE_BOX_INDEX])
2812 || INTEGERP (attrs[LFACE_BOX_INDEX])
2813 || CONSP (attrs[LFACE_BOX_INDEX]));
2814 xassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
2815 || SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
2816 xassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
2817 || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
2818 xassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
2819 || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
2820 xassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX])
2821 || NILP (attrs[LFACE_INHERIT_INDEX])
2822 || SYMBOLP (attrs[LFACE_INHERIT_INDEX])
2823 || CONSP (attrs[LFACE_INHERIT_INDEX]));
2824 #ifdef HAVE_WINDOW_SYSTEM
2825 xassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
2826 || SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
2827 || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
2828 xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
2829 || NILP (attrs[LFACE_FONT_INDEX])
2830 || STRINGP (attrs[LFACE_FONT_INDEX]));
2831 #endif
2835 /* Check consistency of attributes of Lisp face LFACE (a Lisp vector). */
2837 static void
2838 check_lface (lface)
2839 Lisp_Object lface;
2841 if (!NILP (lface))
2843 xassert (LFACEP (lface));
2844 check_lface_attrs (XVECTOR (lface)->contents);
2848 #else /* GLYPH_DEBUG == 0 */
2850 #define check_lface_attrs(attrs) (void) 0
2851 #define check_lface(lface) (void) 0
2853 #endif /* GLYPH_DEBUG == 0 */
2856 /* Resolve face name FACE_NAME. If FACE_NAME is a string, intern it
2857 to make it a symvol. If FACE_NAME is an alias for another face,
2858 return that face's name. */
2860 static Lisp_Object
2861 resolve_face_name (face_name)
2862 Lisp_Object face_name;
2864 Lisp_Object aliased;
2866 if (STRINGP (face_name))
2867 face_name = intern (XSTRING (face_name)->data);
2869 for (;;)
2871 aliased = Fget (face_name, Qface_alias);
2872 if (NILP (aliased))
2873 break;
2874 else
2875 face_name = aliased;
2878 return face_name;
2882 /* Return the face definition of FACE_NAME on frame F. F null means
2883 return the global definition. FACE_NAME may be a string or a
2884 symbol (apparently Emacs 20.2 allows strings as face names in face
2885 text properties; ediff uses that). If FACE_NAME is an alias for
2886 another face, return that face's definition. If SIGNAL_P is
2887 non-zero, signal an error if FACE_NAME is not a valid face name.
2888 If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
2889 name. */
2891 static INLINE Lisp_Object
2892 lface_from_face_name (f, face_name, signal_p)
2893 struct frame *f;
2894 Lisp_Object face_name;
2895 int signal_p;
2897 Lisp_Object lface;
2899 face_name = resolve_face_name (face_name);
2901 if (f)
2902 lface = assq_no_quit (face_name, f->face_alist);
2903 else
2904 lface = assq_no_quit (face_name, Vface_new_frame_defaults);
2906 if (CONSP (lface))
2907 lface = XCDR (lface);
2908 else if (signal_p)
2909 signal_error ("Invalid face", face_name);
2911 check_lface (lface);
2912 return lface;
2916 /* Get face attributes of face FACE_NAME from frame-local faces on
2917 frame F. Store the resulting attributes in ATTRS which must point
2918 to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If SIGNAL_P
2919 is non-zero, signal an error if FACE_NAME does not name a face.
2920 Otherwise, value is zero if FACE_NAME is not a face. */
2922 static INLINE int
2923 get_lface_attributes (f, face_name, attrs, signal_p)
2924 struct frame *f;
2925 Lisp_Object face_name;
2926 Lisp_Object *attrs;
2927 int signal_p;
2929 Lisp_Object lface;
2930 int success_p;
2932 lface = lface_from_face_name (f, face_name, signal_p);
2933 if (!NILP (lface))
2935 bcopy (XVECTOR (lface)->contents, attrs,
2936 LFACE_VECTOR_SIZE * sizeof *attrs);
2937 success_p = 1;
2939 else
2940 success_p = 0;
2942 return success_p;
2946 /* Non-zero if all attributes in face attribute vector ATTRS are
2947 specified, i.e. are non-nil. */
2949 static int
2950 lface_fully_specified_p (attrs)
2951 Lisp_Object *attrs;
2953 int i;
2955 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2956 if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
2957 if (UNSPECIFIEDP (attrs[i]))
2958 break;
2960 return i == LFACE_VECTOR_SIZE;
2963 #ifdef HAVE_WINDOW_SYSTEM
2965 /* Set font-related attributes of Lisp face LFACE from the fullname of
2966 the font opened by FONTNAME. If FORCE_P is zero, set only
2967 unspecified attributes of LFACE. The exception is `font'
2968 attribute. It is set to FONTNAME as is regardless of FORCE_P.
2970 If FONTNAME is not available on frame F,
2971 return 0 if MAY_FAIL_P is non-zero, otherwise abort.
2972 If the fullname is not in a valid XLFD format,
2973 return 0 if MAY_FAIL_P is non-zero, otherwise set normal values
2974 in LFACE and return 1.
2975 Otherwise, return 1. */
2977 static int
2978 set_lface_from_font_name (f, lface, fontname, force_p, may_fail_p)
2979 struct frame *f;
2980 Lisp_Object lface;
2981 Lisp_Object fontname;
2982 int force_p, may_fail_p;
2984 struct font_name font;
2985 char *buffer;
2986 int pt;
2987 int have_xlfd_p;
2988 int fontset;
2989 char *font_name = XSTRING (fontname)->data;
2990 struct font_info *font_info;
2992 /* If FONTNAME is actually a fontset name, get ASCII font name of it. */
2993 fontset = fs_query_fontset (fontname, 0);
2994 if (fontset >= 0)
2995 font_name = XSTRING (fontset_ascii (fontset))->data;
2997 /* Check if FONT_NAME is surely available on the system. Usually
2998 FONT_NAME is already cached for the frame F and FS_LOAD_FONT
2999 returns quickly. But, even if FONT_NAME is not yet cached,
3000 caching it now is not futail because we anyway load the font
3001 later. */
3002 BLOCK_INPUT;
3003 font_info = FS_LOAD_FONT (f, 0, font_name, -1);
3004 UNBLOCK_INPUT;
3006 if (!font_info)
3008 if (may_fail_p)
3009 return 0;
3010 abort ();
3013 font.name = STRDUPA (font_info->full_name);
3014 have_xlfd_p = split_font_name (f, &font, 1);
3016 /* Set attributes only if unspecified, otherwise face defaults for
3017 new frames would never take effect. If we couldn't get a font
3018 name conforming to XLFD, set normal values. */
3020 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
3022 Lisp_Object val;
3023 if (have_xlfd_p)
3025 buffer = (char *) alloca (strlen (font.fields[XLFD_FAMILY])
3026 + strlen (font.fields[XLFD_FOUNDRY])
3027 + 2);
3028 sprintf (buffer, "%s-%s", font.fields[XLFD_FOUNDRY],
3029 font.fields[XLFD_FAMILY]);
3030 val = build_string (buffer);
3032 else
3033 val = build_string ("*");
3034 LFACE_FAMILY (lface) = val;
3037 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
3039 if (have_xlfd_p)
3040 pt = xlfd_point_size (f, &font);
3041 else
3042 pt = pixel_point_size (f, font_info->height * 10);
3043 xassert (pt > 0);
3044 LFACE_HEIGHT (lface) = make_number (pt);
3047 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
3048 LFACE_SWIDTH (lface)
3049 = have_xlfd_p ? xlfd_symbolic_swidth (&font) : Qnormal;
3051 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
3052 LFACE_WEIGHT (lface)
3053 = have_xlfd_p ? xlfd_symbolic_weight (&font) : Qnormal;
3055 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
3056 LFACE_SLANT (lface)
3057 = have_xlfd_p ? xlfd_symbolic_slant (&font) : Qnormal;
3059 LFACE_FONT (lface) = fontname;
3061 return 1;
3063 #endif /* HAVE_WINDOW_SYSTEM */
3066 /* Merges the face height FROM with the face height TO, and returns the
3067 merged height. If FROM is an invalid height, then INVALID is
3068 returned instead. FROM may be a either an absolute face height or a
3069 `relative' height, and TO must be an absolute height. The returned
3070 value is always an absolute height. GCPRO is a lisp value that will
3071 be protected from garbage-collection if this function makes a call
3072 into lisp. */
3074 Lisp_Object
3075 merge_face_heights (from, to, invalid, gcpro)
3076 Lisp_Object from, to, invalid, gcpro;
3078 int result = 0;
3080 if (INTEGERP (from))
3081 result = XINT (from);
3082 else if (NUMBERP (from))
3083 result = XFLOATINT (from) * XINT (to);
3084 #if 0 /* Probably not so useful. */
3085 else if (CONSP (from) && CONSP (XCDR (from)))
3087 if (EQ (XCAR(from), Qplus) || EQ (XCAR(from), Qminus))
3089 if (INTEGERP (XCAR (XCDR (from))))
3091 int inc = XINT (XCAR (XCDR (from)));
3092 if (EQ (XCAR (from), Qminus))
3093 inc = -inc;
3095 result = XFASTINT (to);
3096 if (result + inc > 0)
3097 /* Note that `underflows' don't mean FROM is invalid, so
3098 we just pin the result at TO if it would otherwise be
3099 negative or 0. */
3100 result += inc;
3104 #endif
3105 else if (FUNCTIONP (from))
3107 /* Call function with current height as argument.
3108 From is the new height. */
3109 Lisp_Object args[2], height;
3110 struct gcpro gcpro1;
3112 GCPRO1 (gcpro);
3114 args[0] = from;
3115 args[1] = to;
3116 height = call_function (2, args);
3118 UNGCPRO;
3120 if (NUMBERP (height))
3121 result = XFLOATINT (height);
3124 if (result > 0)
3125 return make_number (result);
3126 else
3127 return invalid;
3131 /* Default any unspecified face attributes in LFACE from DEFAULTS.
3132 Unlike merge_face_vectors, below, this function simply fills in any
3133 unspecified attributes in LFACE from the those in DEFAULTS, and will
3134 not do face inheritance or make relative attributes absolute. */
3136 static INLINE void
3137 default_face_vector (lface, defaults)
3138 Lisp_Object *lface, *defaults;
3140 int i;
3141 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3142 if (UNSPECIFIEDP (lface[i]))
3143 lface[i] = defaults[i];
3147 /* Merge two Lisp face attribute vectors on frame F, FROM and TO, and
3148 store the resulting attributes in TO, which must be already be
3149 completely specified and contain only absolute attributes. Every
3150 specified attribute of FROM overrides the corresponding attribute of
3151 TO; relative attributes in FROM are merged with the absolute value in
3152 TO and replace it. CYCLE_CHECK is used internally to detect loops in
3153 face inheritance; it should be Qnil when called from other places. */
3155 static INLINE void
3156 merge_face_vectors (f, from, to, cycle_check)
3157 struct frame *f;
3158 Lisp_Object *from, *to;
3159 Lisp_Object cycle_check;
3161 int i;
3163 /* If FROM inherits from some other faces, merge their attributes into
3164 TO before merging FROM's direct attributes. Note that an :inherit
3165 attribute of `unspecified' is the same as one of nil; we never
3166 merge :inherit attributes, so nil is more correct, but lots of
3167 other code uses `unspecified' as a generic value for face attributes. */
3168 if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
3169 && !NILP (from[LFACE_INHERIT_INDEX]))
3170 merge_face_inheritance (f, from[LFACE_INHERIT_INDEX], to, cycle_check);
3172 /* If TO specifies a :font attribute, and FROM specifies some
3173 font-related attribute, we need to clear TO's :font attribute
3174 (because it will be inconsistent with whatever FROM specifies, and
3175 FROM takes precedence). */
3176 if (!NILP (to[LFACE_FONT_INDEX])
3177 && (!UNSPECIFIEDP (from[LFACE_FAMILY_INDEX])
3178 || !UNSPECIFIEDP (from[LFACE_HEIGHT_INDEX])
3179 || !UNSPECIFIEDP (from[LFACE_WEIGHT_INDEX])
3180 || !UNSPECIFIEDP (from[LFACE_SLANT_INDEX])
3181 || !UNSPECIFIEDP (from[LFACE_SWIDTH_INDEX])))
3182 to[LFACE_FONT_INDEX] = Qnil;
3184 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3185 if (!UNSPECIFIEDP (from[i]))
3186 if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
3187 to[i] = merge_face_heights (from[i], to[i], to[i], cycle_check);
3188 else
3189 to[i] = from[i];
3191 /* TO is always an absolute face, which should inherit from nothing.
3192 We blindly copy the :inherit attribute above and fix it up here. */
3193 to[LFACE_INHERIT_INDEX] = Qnil;
3197 /* Checks the `cycle check' variable CHECK to see if it indicates that
3198 EL is part of a cycle; CHECK must be either Qnil or a value returned
3199 by an earlier use of CYCLE_CHECK. SUSPICIOUS is the number of
3200 elements after which a cycle might be suspected; after that many
3201 elements, this macro begins consing in order to keep more precise
3202 track of elements.
3204 Returns NIL if a cycle was detected, otherwise a new value for CHECK
3205 that includes EL.
3207 CHECK is evaluated multiple times, EL and SUSPICIOUS 0 or 1 times, so
3208 the caller should make sure that's ok. */
3210 #define CYCLE_CHECK(check, el, suspicious) \
3211 (NILP (check) \
3212 ? make_number (0) \
3213 : INTEGERP (check) \
3214 ? (XFASTINT (check) < (suspicious) \
3215 ? make_number (XFASTINT (check) + 1) \
3216 : Fcons (el, Qnil)) \
3217 : Fmemq ((el), (check)) \
3218 ? Qnil \
3219 : Fcons ((el), (check)))
3222 /* Merge face attributes from the face on frame F whose name is
3223 INHERITS, into the vector of face attributes TO; INHERITS may also be
3224 a list of face names, in which case they are applied in order.
3225 CYCLE_CHECK is used to detect loops in face inheritance.
3226 Returns true if any of the inherited attributes are `font-related'. */
3228 static void
3229 merge_face_inheritance (f, inherit, to, cycle_check)
3230 struct frame *f;
3231 Lisp_Object inherit;
3232 Lisp_Object *to;
3233 Lisp_Object cycle_check;
3235 if (SYMBOLP (inherit) && !EQ (inherit, Qunspecified))
3236 /* Inherit from the named face INHERIT. */
3238 Lisp_Object lface;
3240 /* Make sure we're not in an inheritance loop. */
3241 cycle_check = CYCLE_CHECK (cycle_check, inherit, 15);
3242 if (NILP (cycle_check))
3243 /* Cycle detected, ignore any further inheritance. */
3244 return;
3246 lface = lface_from_face_name (f, inherit, 0);
3247 if (!NILP (lface))
3248 merge_face_vectors (f, XVECTOR (lface)->contents, to, cycle_check);
3250 else if (CONSP (inherit))
3251 /* Handle a list of inherited faces by calling ourselves recursively
3252 on each element. Note that we only do so for symbol elements, so
3253 it's not possible to infinitely recurse. */
3255 while (CONSP (inherit))
3257 if (SYMBOLP (XCAR (inherit)))
3258 merge_face_inheritance (f, XCAR (inherit), to, cycle_check);
3260 /* Check for a circular inheritance list. */
3261 cycle_check = CYCLE_CHECK (cycle_check, inherit, 15);
3262 if (NILP (cycle_check))
3263 /* Cycle detected. */
3264 break;
3266 inherit = XCDR (inherit);
3272 /* Given a Lisp face attribute vector TO and a Lisp object PROP that
3273 is a face property, determine the resulting face attributes on
3274 frame F, and store them in TO. PROP may be a single face
3275 specification or a list of such specifications. Each face
3276 specification can be
3278 1. A symbol or string naming a Lisp face.
3280 2. A property list of the form (KEYWORD VALUE ...) where each
3281 KEYWORD is a face attribute name, and value is an appropriate value
3282 for that attribute.
3284 3. Conses or the form (FOREGROUND-COLOR . COLOR) or
3285 (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is
3286 for compatibility with 20.2.
3288 Face specifications earlier in lists take precedence over later
3289 specifications. */
3291 static void
3292 merge_face_vector_with_property (f, to, prop)
3293 struct frame *f;
3294 Lisp_Object *to;
3295 Lisp_Object prop;
3297 if (CONSP (prop))
3299 Lisp_Object first = XCAR (prop);
3301 if (EQ (first, Qforeground_color)
3302 || EQ (first, Qbackground_color))
3304 /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
3305 . COLOR). COLOR must be a string. */
3306 Lisp_Object color_name = XCDR (prop);
3307 Lisp_Object color = first;
3309 if (STRINGP (color_name))
3311 if (EQ (color, Qforeground_color))
3312 to[LFACE_FOREGROUND_INDEX] = color_name;
3313 else
3314 to[LFACE_BACKGROUND_INDEX] = color_name;
3316 else
3317 add_to_log ("Invalid face color", color_name, Qnil);
3319 else if (SYMBOLP (first)
3320 && *XSYMBOL (first)->name->data == ':')
3322 /* Assume this is the property list form. */
3323 while (CONSP (prop) && CONSP (XCDR (prop)))
3325 Lisp_Object keyword = XCAR (prop);
3326 Lisp_Object value = XCAR (XCDR (prop));
3328 if (EQ (keyword, QCfamily))
3330 if (STRINGP (value))
3331 to[LFACE_FAMILY_INDEX] = value;
3332 else
3333 add_to_log ("Invalid face font family", value, Qnil);
3335 else if (EQ (keyword, QCheight))
3337 Lisp_Object new_height =
3338 merge_face_heights (value, to[LFACE_HEIGHT_INDEX],
3339 Qnil, Qnil);
3341 if (NILP (new_height))
3342 add_to_log ("Invalid face font height", value, Qnil);
3343 else
3344 to[LFACE_HEIGHT_INDEX] = new_height;
3346 else if (EQ (keyword, QCweight))
3348 if (SYMBOLP (value)
3349 && face_numeric_weight (value) >= 0)
3350 to[LFACE_WEIGHT_INDEX] = value;
3351 else
3352 add_to_log ("Invalid face weight", value, Qnil);
3354 else if (EQ (keyword, QCslant))
3356 if (SYMBOLP (value)
3357 && face_numeric_slant (value) >= 0)
3358 to[LFACE_SLANT_INDEX] = value;
3359 else
3360 add_to_log ("Invalid face slant", value, Qnil);
3362 else if (EQ (keyword, QCunderline))
3364 if (EQ (value, Qt)
3365 || NILP (value)
3366 || STRINGP (value))
3367 to[LFACE_UNDERLINE_INDEX] = value;
3368 else
3369 add_to_log ("Invalid face underline", value, Qnil);
3371 else if (EQ (keyword, QCoverline))
3373 if (EQ (value, Qt)
3374 || NILP (value)
3375 || STRINGP (value))
3376 to[LFACE_OVERLINE_INDEX] = value;
3377 else
3378 add_to_log ("Invalid face overline", value, Qnil);
3380 else if (EQ (keyword, QCstrike_through))
3382 if (EQ (value, Qt)
3383 || NILP (value)
3384 || STRINGP (value))
3385 to[LFACE_STRIKE_THROUGH_INDEX] = value;
3386 else
3387 add_to_log ("Invalid face strike-through", value, Qnil);
3389 else if (EQ (keyword, QCbox))
3391 if (EQ (value, Qt))
3392 value = make_number (1);
3393 if (INTEGERP (value)
3394 || STRINGP (value)
3395 || CONSP (value)
3396 || NILP (value))
3397 to[LFACE_BOX_INDEX] = value;
3398 else
3399 add_to_log ("Invalid face box", value, Qnil);
3401 else if (EQ (keyword, QCinverse_video)
3402 || EQ (keyword, QCreverse_video))
3404 if (EQ (value, Qt) || NILP (value))
3405 to[LFACE_INVERSE_INDEX] = value;
3406 else
3407 add_to_log ("Invalid face inverse-video", value, Qnil);
3409 else if (EQ (keyword, QCforeground))
3411 if (STRINGP (value))
3412 to[LFACE_FOREGROUND_INDEX] = value;
3413 else
3414 add_to_log ("Invalid face foreground", value, Qnil);
3416 else if (EQ (keyword, QCbackground))
3418 if (STRINGP (value))
3419 to[LFACE_BACKGROUND_INDEX] = value;
3420 else
3421 add_to_log ("Invalid face background", value, Qnil);
3423 else if (EQ (keyword, QCstipple))
3425 #ifdef HAVE_X_WINDOWS
3426 Lisp_Object pixmap_p = Fbitmap_spec_p (value);
3427 if (!NILP (pixmap_p))
3428 to[LFACE_STIPPLE_INDEX] = value;
3429 else
3430 add_to_log ("Invalid face stipple", value, Qnil);
3431 #endif
3433 else if (EQ (keyword, QCwidth))
3435 if (SYMBOLP (value)
3436 && face_numeric_swidth (value) >= 0)
3437 to[LFACE_SWIDTH_INDEX] = value;
3438 else
3439 add_to_log ("Invalid face width", value, Qnil);
3441 else if (EQ (keyword, QCinherit))
3443 if (SYMBOLP (value))
3444 to[LFACE_INHERIT_INDEX] = value;
3445 else
3447 Lisp_Object tail;
3448 for (tail = value; CONSP (tail); tail = XCDR (tail))
3449 if (!SYMBOLP (XCAR (tail)))
3450 break;
3451 if (NILP (tail))
3452 to[LFACE_INHERIT_INDEX] = value;
3453 else
3454 add_to_log ("Invalid face inherit", value, Qnil);
3457 else
3458 add_to_log ("Invalid attribute %s in face property",
3459 keyword, Qnil);
3461 prop = XCDR (XCDR (prop));
3464 else
3466 /* This is a list of face specs. Specifications at the
3467 beginning of the list take precedence over later
3468 specifications, so we have to merge starting with the
3469 last specification. */
3470 Lisp_Object next = XCDR (prop);
3471 if (!NILP (next))
3472 merge_face_vector_with_property (f, to, next);
3473 merge_face_vector_with_property (f, to, first);
3476 else
3478 /* PROP ought to be a face name. */
3479 Lisp_Object lface = lface_from_face_name (f, prop, 0);
3480 if (NILP (lface))
3481 add_to_log ("Invalid face text property value: %s", prop, Qnil);
3482 else
3483 merge_face_vectors (f, XVECTOR (lface)->contents, to, Qnil);
3488 DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face,
3489 Sinternal_make_lisp_face, 1, 2, 0,
3490 "Make FACE, a symbol, a Lisp face with all attributes nil.\n\
3491 If FACE was not known as a face before, create a new one.\n\
3492 If optional argument FRAME is specified, make a frame-local face\n\
3493 for that frame. Otherwise operate on the global face definition.\n\
3494 Value is a vector of face attributes.")
3495 (face, frame)
3496 Lisp_Object face, frame;
3498 Lisp_Object global_lface, lface;
3499 struct frame *f;
3500 int i;
3502 CHECK_SYMBOL (face, 0);
3503 global_lface = lface_from_face_name (NULL, face, 0);
3505 if (!NILP (frame))
3507 CHECK_LIVE_FRAME (frame, 1);
3508 f = XFRAME (frame);
3509 lface = lface_from_face_name (f, face, 0);
3511 else
3512 f = NULL, lface = Qnil;
3514 /* Add a global definition if there is none. */
3515 if (NILP (global_lface))
3517 global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
3518 Qunspecified);
3519 XVECTOR (global_lface)->contents[0] = Qface;
3520 Vface_new_frame_defaults = Fcons (Fcons (face, global_lface),
3521 Vface_new_frame_defaults);
3523 /* Assign the new Lisp face a unique ID. The mapping from Lisp
3524 face id to Lisp face is given by the vector lface_id_to_name.
3525 The mapping from Lisp face to Lisp face id is given by the
3526 property `face' of the Lisp face name. */
3527 if (next_lface_id == lface_id_to_name_size)
3529 int new_size = max (50, 2 * lface_id_to_name_size);
3530 int sz = new_size * sizeof *lface_id_to_name;
3531 lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz);
3532 lface_id_to_name_size = new_size;
3535 lface_id_to_name[next_lface_id] = face;
3536 Fput (face, Qface, make_number (next_lface_id));
3537 ++next_lface_id;
3539 else if (f == NULL)
3540 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3541 XVECTOR (global_lface)->contents[i] = Qunspecified;
3543 /* Add a frame-local definition. */
3544 if (f)
3546 if (NILP (lface))
3548 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
3549 Qunspecified);
3550 XVECTOR (lface)->contents[0] = Qface;
3551 f->face_alist = Fcons (Fcons (face, lface), f->face_alist);
3553 else
3554 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3555 XVECTOR (lface)->contents[i] = Qunspecified;
3557 else
3558 lface = global_lface;
3560 xassert (LFACEP (lface));
3561 check_lface (lface);
3562 return lface;
3566 DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
3567 Sinternal_lisp_face_p, 1, 2, 0,
3568 "Return non-nil if FACE names a face.\n\
3569 If optional second parameter FRAME is non-nil, check for the\n\
3570 existence of a frame-local face with name FACE on that frame.\n\
3571 Otherwise check for the existence of a global face.")
3572 (face, frame)
3573 Lisp_Object face, frame;
3575 Lisp_Object lface;
3577 if (!NILP (frame))
3579 CHECK_LIVE_FRAME (frame, 1);
3580 lface = lface_from_face_name (XFRAME (frame), face, 0);
3582 else
3583 lface = lface_from_face_name (NULL, face, 0);
3585 return lface;
3589 DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
3590 Sinternal_copy_lisp_face, 4, 4, 0,
3591 "Copy face FROM to TO.\n\
3592 If FRAME it t, copy the global face definition of FROM to the\n\
3593 global face definition of TO. Otherwise, copy the frame-local\n\
3594 definition of FROM on FRAME to the frame-local definition of TO\n\
3595 on NEW-FRAME, or FRAME if NEW-FRAME is nil.\n\
3597 Value is TO.")
3598 (from, to, frame, new_frame)
3599 Lisp_Object from, to, frame, new_frame;
3601 Lisp_Object lface, copy;
3603 CHECK_SYMBOL (from, 0);
3604 CHECK_SYMBOL (to, 1);
3605 if (NILP (new_frame))
3606 new_frame = frame;
3608 if (EQ (frame, Qt))
3610 /* Copy global definition of FROM. We don't make copies of
3611 strings etc. because 20.2 didn't do it either. */
3612 lface = lface_from_face_name (NULL, from, 1);
3613 copy = Finternal_make_lisp_face (to, Qnil);
3615 else
3617 /* Copy frame-local definition of FROM. */
3618 CHECK_LIVE_FRAME (frame, 2);
3619 CHECK_LIVE_FRAME (new_frame, 3);
3620 lface = lface_from_face_name (XFRAME (frame), from, 1);
3621 copy = Finternal_make_lisp_face (to, new_frame);
3624 bcopy (XVECTOR (lface)->contents, XVECTOR (copy)->contents,
3625 LFACE_VECTOR_SIZE * sizeof (Lisp_Object));
3627 return to;
3631 DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
3632 Sinternal_set_lisp_face_attribute, 3, 4, 0,
3633 "Set attribute ATTR of FACE to VALUE.\n\
3634 If optional argument FRAME is given, set the face attribute of face FACE\n\
3635 on that frame. If FRAME is t, set the attribute of the default for face\n\
3636 FACE (for new frames). If FRAME is omitted or nil, use the selected\n\
3637 frame.")
3638 (face, attr, value, frame)
3639 Lisp_Object face, attr, value, frame;
3641 Lisp_Object lface;
3642 Lisp_Object old_value = Qnil;
3643 /* Set 1 if ATTR is QCfont. */
3644 int font_attr_p = 0;
3645 /* Set 1 if ATTR is one of font-related attributes other than QCfont. */
3646 int font_related_attr_p = 0;
3648 CHECK_SYMBOL (face, 0);
3649 CHECK_SYMBOL (attr, 1);
3651 face = resolve_face_name (face);
3653 /* Set lface to the Lisp attribute vector of FACE. */
3654 if (EQ (frame, Qt))
3655 lface = lface_from_face_name (NULL, face, 1);
3656 else
3658 if (NILP (frame))
3659 frame = selected_frame;
3661 CHECK_LIVE_FRAME (frame, 3);
3662 lface = lface_from_face_name (XFRAME (frame), face, 0);
3664 /* If a frame-local face doesn't exist yet, create one. */
3665 if (NILP (lface))
3666 lface = Finternal_make_lisp_face (face, frame);
3669 if (EQ (attr, QCfamily))
3671 if (!UNSPECIFIEDP (value))
3673 CHECK_STRING (value, 3);
3674 if (XSTRING (value)->size == 0)
3675 signal_error ("Invalid face family", value);
3677 old_value = LFACE_FAMILY (lface);
3678 LFACE_FAMILY (lface) = value;
3679 font_related_attr_p = 1;
3681 else if (EQ (attr, QCheight))
3683 if (!UNSPECIFIEDP (value))
3685 Lisp_Object test = Qnil;
3687 if (!EQ (face, Qdefault))
3688 /* The default face must have an absolute size, otherwise, we do
3689 a test merge with a random height to see if VALUE's ok. */
3690 test = merge_face_heights (value, make_number(10), Qnil, Qnil);
3692 if (!INTEGERP(test) || XINT(test) <= 0)
3693 signal_error ("Invalid face height", value);
3696 old_value = LFACE_HEIGHT (lface);
3697 LFACE_HEIGHT (lface) = value;
3698 font_related_attr_p = 1;
3700 else if (EQ (attr, QCweight))
3702 if (!UNSPECIFIEDP (value))
3704 CHECK_SYMBOL (value, 3);
3705 if (face_numeric_weight (value) < 0)
3706 signal_error ("Invalid face weight", value);
3708 old_value = LFACE_WEIGHT (lface);
3709 LFACE_WEIGHT (lface) = value;
3710 font_related_attr_p = 1;
3712 else if (EQ (attr, QCslant))
3714 if (!UNSPECIFIEDP (value))
3716 CHECK_SYMBOL (value, 3);
3717 if (face_numeric_slant (value) < 0)
3718 signal_error ("Invalid face slant", value);
3720 old_value = LFACE_SLANT (lface);
3721 LFACE_SLANT (lface) = value;
3722 font_related_attr_p = 1;
3724 else if (EQ (attr, QCunderline))
3726 if (!UNSPECIFIEDP (value))
3727 if ((SYMBOLP (value)
3728 && !EQ (value, Qt)
3729 && !EQ (value, Qnil))
3730 /* Underline color. */
3731 || (STRINGP (value)
3732 && XSTRING (value)->size == 0))
3733 signal_error ("Invalid face underline", value);
3735 old_value = LFACE_UNDERLINE (lface);
3736 LFACE_UNDERLINE (lface) = value;
3738 else if (EQ (attr, QCoverline))
3740 if (!UNSPECIFIEDP (value))
3741 if ((SYMBOLP (value)
3742 && !EQ (value, Qt)
3743 && !EQ (value, Qnil))
3744 /* Overline color. */
3745 || (STRINGP (value)
3746 && XSTRING (value)->size == 0))
3747 signal_error ("Invalid face overline", value);
3749 old_value = LFACE_OVERLINE (lface);
3750 LFACE_OVERLINE (lface) = value;
3752 else if (EQ (attr, QCstrike_through))
3754 if (!UNSPECIFIEDP (value))
3755 if ((SYMBOLP (value)
3756 && !EQ (value, Qt)
3757 && !EQ (value, Qnil))
3758 /* Strike-through color. */
3759 || (STRINGP (value)
3760 && XSTRING (value)->size == 0))
3761 signal_error ("Invalid face strike-through", value);
3763 old_value = LFACE_STRIKE_THROUGH (lface);
3764 LFACE_STRIKE_THROUGH (lface) = value;
3766 else if (EQ (attr, QCbox))
3768 int valid_p;
3770 /* Allow t meaning a simple box of width 1 in foreground color
3771 of the face. */
3772 if (EQ (value, Qt))
3773 value = make_number (1);
3775 if (UNSPECIFIEDP (value))
3776 valid_p = 1;
3777 else if (NILP (value))
3778 valid_p = 1;
3779 else if (INTEGERP (value))
3780 valid_p = XINT (value) > 0;
3781 else if (STRINGP (value))
3782 valid_p = XSTRING (value)->size > 0;
3783 else if (CONSP (value))
3785 Lisp_Object tem;
3787 tem = value;
3788 while (CONSP (tem))
3790 Lisp_Object k, v;
3792 k = XCAR (tem);
3793 tem = XCDR (tem);
3794 if (!CONSP (tem))
3795 break;
3796 v = XCAR (tem);
3797 tem = XCDR (tem);
3799 if (EQ (k, QCline_width))
3801 if (!INTEGERP (v) || XINT (v) <= 0)
3802 break;
3804 else if (EQ (k, QCcolor))
3806 if (!STRINGP (v) || XSTRING (v)->size == 0)
3807 break;
3809 else if (EQ (k, QCstyle))
3811 if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button))
3812 break;
3814 else
3815 break;
3818 valid_p = NILP (tem);
3820 else
3821 valid_p = 0;
3823 if (!valid_p)
3824 signal_error ("Invalid face box", value);
3826 old_value = LFACE_BOX (lface);
3827 LFACE_BOX (lface) = value;
3829 else if (EQ (attr, QCinverse_video)
3830 || EQ (attr, QCreverse_video))
3832 if (!UNSPECIFIEDP (value))
3834 CHECK_SYMBOL (value, 3);
3835 if (!EQ (value, Qt) && !NILP (value))
3836 signal_error ("Invalid inverse-video face attribute value", value);
3838 old_value = LFACE_INVERSE (lface);
3839 LFACE_INVERSE (lface) = value;
3841 else if (EQ (attr, QCforeground))
3843 if (!UNSPECIFIEDP (value))
3845 /* Don't check for valid color names here because it depends
3846 on the frame (display) whether the color will be valid
3847 when the face is realized. */
3848 CHECK_STRING (value, 3);
3849 if (XSTRING (value)->size == 0)
3850 signal_error ("Empty foreground color value", value);
3852 old_value = LFACE_FOREGROUND (lface);
3853 LFACE_FOREGROUND (lface) = value;
3855 else if (EQ (attr, QCbackground))
3857 if (!UNSPECIFIEDP (value))
3859 /* Don't check for valid color names here because it depends
3860 on the frame (display) whether the color will be valid
3861 when the face is realized. */
3862 CHECK_STRING (value, 3);
3863 if (XSTRING (value)->size == 0)
3864 signal_error ("Empty background color value", value);
3866 old_value = LFACE_BACKGROUND (lface);
3867 LFACE_BACKGROUND (lface) = value;
3869 else if (EQ (attr, QCstipple))
3871 #ifdef HAVE_X_WINDOWS
3872 if (!UNSPECIFIEDP (value)
3873 && !NILP (value)
3874 && NILP (Fbitmap_spec_p (value)))
3875 signal_error ("Invalid stipple attribute", value);
3876 old_value = LFACE_STIPPLE (lface);
3877 LFACE_STIPPLE (lface) = value;
3878 #endif /* HAVE_X_WINDOWS */
3880 else if (EQ (attr, QCwidth))
3882 if (!UNSPECIFIEDP (value))
3884 CHECK_SYMBOL (value, 3);
3885 if (face_numeric_swidth (value) < 0)
3886 signal_error ("Invalid face width", value);
3888 old_value = LFACE_SWIDTH (lface);
3889 LFACE_SWIDTH (lface) = value;
3890 font_related_attr_p = 1;
3892 else if (EQ (attr, QCfont))
3894 #ifdef HAVE_WINDOW_SYSTEM
3895 /* Set font-related attributes of the Lisp face from an
3896 XLFD font name. */
3897 struct frame *f;
3898 Lisp_Object tmp;
3900 CHECK_STRING (value, 3);
3901 if (EQ (frame, Qt))
3902 f = SELECTED_FRAME ();
3903 else
3904 f = check_x_frame (frame);
3906 /* VALUE may be a fontset name or an alias of fontset. In such
3907 a case, use the base fontset name. */
3908 tmp = Fquery_fontset (value, Qnil);
3909 if (!NILP (tmp))
3910 value = tmp;
3912 if (!set_lface_from_font_name (f, lface, value, 1, 1))
3913 signal_error ("Invalid font or fontset name", value);
3915 font_attr_p = 1;
3916 #endif /* HAVE_WINDOW_SYSTEM */
3918 else if (EQ (attr, QCinherit))
3920 Lisp_Object tail;
3921 if (SYMBOLP (value))
3922 tail = Qnil;
3923 else
3924 for (tail = value; CONSP (tail); tail = XCDR (tail))
3925 if (!SYMBOLP (XCAR (tail)))
3926 break;
3927 if (NILP (tail))
3928 LFACE_INHERIT (lface) = value;
3929 else
3930 signal_error ("Invalid face inheritance", value);
3932 else if (EQ (attr, QCbold))
3934 old_value = LFACE_WEIGHT (lface);
3935 LFACE_WEIGHT (lface) = NILP (value) ? Qnormal : Qbold;
3936 font_related_attr_p = 1;
3938 else if (EQ (attr, QCitalic))
3940 old_value = LFACE_SLANT (lface);
3941 LFACE_SLANT (lface) = NILP (value) ? Qnormal : Qitalic;
3942 font_related_attr_p = 1;
3944 else
3945 signal_error ("Invalid face attribute name", attr);
3947 if (font_related_attr_p
3948 && !UNSPECIFIEDP (value))
3949 /* If a font-related attribute other than QCfont is specified, the
3950 original `font' attribute nor that of default face is useless
3951 to determine a new font. Thus, we set it to nil so that font
3952 selection mechanism doesn't use it. */
3953 LFACE_FONT (lface) = Qnil;
3955 /* Changing a named face means that all realized faces depending on
3956 that face are invalid. Since we cannot tell which realized faces
3957 depend on the face, make sure they are all removed. This is done
3958 by incrementing face_change_count. The next call to
3959 init_iterator will then free realized faces. */
3960 if (!EQ (frame, Qt)
3961 && (EQ (attr, QCfont)
3962 || NILP (Fequal (old_value, value))))
3964 ++face_change_count;
3965 ++windows_or_buffers_changed;
3968 #ifdef HAVE_WINDOW_SYSTEM
3970 if (!EQ (frame, Qt)
3971 && !UNSPECIFIEDP (value)
3972 && NILP (Fequal (old_value, value)))
3974 Lisp_Object param;
3976 param = Qnil;
3978 if (EQ (face, Qdefault))
3980 /* Changed font-related attributes of the `default' face are
3981 reflected in changed `font' frame parameters. */
3982 if ((font_related_attr_p || font_attr_p)
3983 && lface_fully_specified_p (XVECTOR (lface)->contents))
3984 set_font_frame_param (frame, lface);
3985 else if (EQ (attr, QCforeground))
3986 param = Qforeground_color;
3987 else if (EQ (attr, QCbackground))
3988 param = Qbackground_color;
3990 #ifndef WINDOWSNT
3991 else if (EQ (face, Qscroll_bar))
3993 /* Changing the colors of `scroll-bar' sets frame parameters
3994 `scroll-bar-foreground' and `scroll-bar-background'. */
3995 if (EQ (attr, QCforeground))
3996 param = Qscroll_bar_foreground;
3997 else if (EQ (attr, QCbackground))
3998 param = Qscroll_bar_background;
4000 #endif
4001 else if (EQ (face, Qborder))
4003 /* Changing background color of `border' sets frame parameter
4004 `border-color'. */
4005 if (EQ (attr, QCbackground))
4006 param = Qborder_color;
4008 else if (EQ (face, Qcursor))
4010 /* Changing background color of `cursor' sets frame parameter
4011 `cursor-color'. */
4012 if (EQ (attr, QCbackground))
4013 param = Qcursor_color;
4015 else if (EQ (face, Qmouse))
4017 /* Changing background color of `mouse' sets frame parameter
4018 `mouse-color'. */
4019 if (EQ (attr, QCbackground))
4020 param = Qmouse_color;
4023 if (!NILP (param))
4024 Fmodify_frame_parameters (frame, Fcons (Fcons (param, value), Qnil));
4027 #endif /* HAVE_WINDOW_SYSTEM */
4029 return face;
4033 #ifdef HAVE_WINDOW_SYSTEM
4035 /* Set the `font' frame parameter of FRAME determined from `default'
4036 face attributes LFACE. If a face or fontset name is explicitely
4037 specfied in LFACE, use it as is. Otherwise, determine a font name
4038 from the other font-related atrributes of LFACE. In that case, if
4039 there's no matching font, signals an error. */
4041 static void
4042 set_font_frame_param (frame, lface)
4043 Lisp_Object frame, lface;
4045 struct frame *f = XFRAME (frame);
4046 Lisp_Object font_name;
4047 char *font;
4049 if (STRINGP (LFACE_FONT (lface)))
4050 font_name = LFACE_FONT (lface);
4051 else
4053 /* Choose a font name that reflects LFACE's attributes and has
4054 the registry and encoding pattern specified in the default
4055 fontset (3rd arg: -1) for ASCII characters (4th arg: 0). */
4056 font = choose_face_font (f, XVECTOR (lface)->contents, -1, 0);
4057 if (!font)
4058 error ("No font matches the specified attribute");
4059 font_name = build_string (font);
4060 xfree (font);
4062 store_frame_param (f, Qfont, font_name);
4066 /* Update the corresponding face when frame parameter PARAM on frame F
4067 has been assigned the value NEW_VALUE. */
4069 void
4070 update_face_from_frame_parameter (f, param, new_value)
4071 struct frame *f;
4072 Lisp_Object param, new_value;
4074 Lisp_Object lface;
4076 /* If there are no faces yet, give up. This is the case when called
4077 from Fx_create_frame, and we do the necessary things later in
4078 face-set-after-frame-defaults. */
4079 if (NILP (f->face_alist))
4080 return;
4082 if (EQ (param, Qforeground_color))
4084 lface = lface_from_face_name (f, Qdefault, 1);
4085 LFACE_FOREGROUND (lface) = (STRINGP (new_value)
4086 ? new_value : Qunspecified);
4087 realize_basic_faces (f);
4089 else if (EQ (param, Qbackground_color))
4091 Lisp_Object frame;
4093 /* Changing the background color might change the background
4094 mode, so that we have to load new defface specs. Call
4095 frame-update-face-colors to do that. */
4096 XSETFRAME (frame, f);
4097 call1 (Qframe_update_face_colors, frame);
4099 lface = lface_from_face_name (f, Qdefault, 1);
4100 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4101 ? new_value : Qunspecified);
4102 realize_basic_faces (f);
4104 if (EQ (param, Qborder_color))
4106 lface = lface_from_face_name (f, Qborder, 1);
4107 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4108 ? new_value : Qunspecified);
4110 else if (EQ (param, Qcursor_color))
4112 lface = lface_from_face_name (f, Qcursor, 1);
4113 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4114 ? new_value : Qunspecified);
4116 else if (EQ (param, Qmouse_color))
4118 lface = lface_from_face_name (f, Qmouse, 1);
4119 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4120 ? new_value : Qunspecified);
4125 /* Get the value of X resource RESOURCE, class CLASS for the display
4126 of frame FRAME. This is here because ordinary `x-get-resource'
4127 doesn't take a frame argument. */
4129 DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
4130 Sinternal_face_x_get_resource, 3, 3, 0, "")
4131 (resource, class, frame)
4132 Lisp_Object resource, class, frame;
4134 Lisp_Object value = Qnil;
4135 #ifndef WINDOWSNT
4136 CHECK_STRING (resource, 0);
4137 CHECK_STRING (class, 1);
4138 CHECK_LIVE_FRAME (frame, 2);
4139 BLOCK_INPUT;
4140 value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)),
4141 resource, class, Qnil, Qnil);
4142 UNBLOCK_INPUT;
4143 #endif
4144 return value;
4148 /* Return resource string VALUE as a boolean value, i.e. nil, or t.
4149 If VALUE is "on" or "true", return t. If VALUE is "off" or
4150 "false", return nil. Otherwise, if SIGNAL_P is non-zero, signal an
4151 error; if SIGNAL_P is zero, return 0. */
4153 static Lisp_Object
4154 face_boolean_x_resource_value (value, signal_p)
4155 Lisp_Object value;
4156 int signal_p;
4158 Lisp_Object result = make_number (0);
4160 xassert (STRINGP (value));
4162 if (xstricmp (XSTRING (value)->data, "on") == 0
4163 || xstricmp (XSTRING (value)->data, "true") == 0)
4164 result = Qt;
4165 else if (xstricmp (XSTRING (value)->data, "off") == 0
4166 || xstricmp (XSTRING (value)->data, "false") == 0)
4167 result = Qnil;
4168 else if (xstricmp (XSTRING (value)->data, "unspecified") == 0)
4169 result = Qunspecified;
4170 else if (signal_p)
4171 signal_error ("Invalid face attribute value from X resource", value);
4173 return result;
4177 DEFUN ("internal-set-lisp-face-attribute-from-resource",
4178 Finternal_set_lisp_face_attribute_from_resource,
4179 Sinternal_set_lisp_face_attribute_from_resource,
4180 3, 4, 0, "")
4181 (face, attr, value, frame)
4182 Lisp_Object face, attr, value, frame;
4184 CHECK_SYMBOL (face, 0);
4185 CHECK_SYMBOL (attr, 1);
4186 CHECK_STRING (value, 2);
4188 if (xstricmp (XSTRING (value)->data, "unspecified") == 0)
4189 value = Qunspecified;
4190 else if (EQ (attr, QCheight))
4192 value = Fstring_to_number (value, make_number (10));
4193 if (XINT (value) <= 0)
4194 signal_error ("Invalid face height from X resource", value);
4196 else if (EQ (attr, QCbold) || EQ (attr, QCitalic))
4197 value = face_boolean_x_resource_value (value, 1);
4198 else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
4199 value = intern (XSTRING (value)->data);
4200 else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
4201 value = face_boolean_x_resource_value (value, 1);
4202 else if (EQ (attr, QCunderline)
4203 || EQ (attr, QCoverline)
4204 || EQ (attr, QCstrike_through)
4205 || EQ (attr, QCbox))
4207 Lisp_Object boolean_value;
4209 /* If the result of face_boolean_x_resource_value is t or nil,
4210 VALUE does NOT specify a color. */
4211 boolean_value = face_boolean_x_resource_value (value, 0);
4212 if (SYMBOLP (boolean_value))
4213 value = boolean_value;
4216 return Finternal_set_lisp_face_attribute (face, attr, value, frame);
4219 #endif /* HAVE_WINDOW_SYSTEM */
4222 #ifdef HAVE_X_WINDOWS
4223 /***********************************************************************
4224 Menu face
4225 ***********************************************************************/
4227 #ifdef USE_X_TOOLKIT
4229 #include "../lwlib/lwlib-utils.h"
4231 /* Structure used to pass X resources to functions called via
4232 XtApplyToWidgets. */
4234 struct x_resources
4236 Arg *av;
4237 int ac;
4241 #ifdef USE_MOTIF
4243 static void xm_apply_resources P_ ((Widget, XtPointer));
4244 static void xm_set_menu_resources_from_menu_face P_ ((struct frame *, Widget));
4247 /* Set widget W's X resources from P which points to an x_resources
4248 structure. If W is a cascade button, apply resources to W's
4249 submenu. */
4251 static void
4252 xm_apply_resources (w, p)
4253 Widget w;
4254 XtPointer p;
4256 Widget submenu = 0;
4257 struct x_resources *res = (struct x_resources *) p;
4259 XtSetValues (w, res->av, res->ac);
4260 XtVaGetValues (w, XmNsubMenuId, &submenu, NULL);
4261 if (submenu)
4263 XtSetValues (submenu, res->av, res->ac);
4264 XtApplyToWidgets (submenu, xm_apply_resources, p);
4269 /* Set X resources of menu-widget WIDGET on frame F from face `menu'.
4270 This is the LessTif/Motif version. As of LessTif 0.88 it has the
4271 following problems:
4273 1. Setting the XmNfontList resource leads to an infinite loop
4274 somewhere in LessTif. */
4276 static void
4277 xm_set_menu_resources_from_menu_face (f, widget)
4278 struct frame *f;
4279 Widget widget;
4281 struct face *face;
4282 Lisp_Object lface;
4283 Arg av[3];
4284 int ac = 0;
4285 XmFontList fl = 0;
4287 lface = lface_from_face_name (f, Qmenu, 1);
4288 face = FACE_FROM_ID (f, MENU_FACE_ID);
4290 if (!UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
4292 XtSetArg (av[ac], XmNforeground, face->foreground);
4293 ++ac;
4296 if (!UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
4298 XtSetArg (av[ac], XmNbackground, face->background);
4299 ++ac;
4302 /* If any font-related attribute of `menu' is set, set the font. */
4303 if (face->font
4304 && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
4305 || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
4306 || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
4307 || !UNSPECIFIEDP (LFACE_SLANT (lface))
4308 || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
4310 #if 0 /* Setting the font leads to an infinite loop somewhere
4311 in LessTif during geometry computation. */
4312 XmFontListEntry fe;
4313 fe = XmFontListEntryCreate ("menu_font", XmFONT_IS_FONT, face->font);
4314 fl = XmFontListAppendEntry (NULL, fe);
4315 XtSetArg (av[ac], XmNfontList, fl);
4316 ++ac;
4317 #endif
4320 xassert (ac <= sizeof av / sizeof *av);
4322 if (ac)
4324 struct x_resources res;
4326 XtSetValues (widget, av, ac);
4327 res.av = av, res.ac = ac;
4328 XtApplyToWidgets (widget, xm_apply_resources, &res);
4329 if (fl)
4330 XmFontListFree (fl);
4335 #endif /* USE_MOTIF */
4337 #ifdef USE_LUCID
4339 static void xl_apply_resources P_ ((Widget, XtPointer));
4340 static void xl_set_menu_resources_from_menu_face P_ ((struct frame *, Widget));
4343 /* Set widget W's resources from P which points to an x_resources
4344 structure. */
4346 static void
4347 xl_apply_resources (widget, p)
4348 Widget widget;
4349 XtPointer p;
4351 struct x_resources *res = (struct x_resources *) p;
4352 XtSetValues (widget, res->av, res->ac);
4356 /* On frame F, set X resources of menu-widget WIDGET from face `menu'.
4357 This is the Lucid version. */
4359 static void
4360 xl_set_menu_resources_from_menu_face (f, widget)
4361 struct frame *f;
4362 Widget widget;
4364 struct face *face;
4365 Lisp_Object lface;
4366 Arg av[3];
4367 int ac = 0;
4369 lface = lface_from_face_name (f, Qmenu, 1);
4370 face = FACE_FROM_ID (f, MENU_FACE_ID);
4372 if (!UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
4374 XtSetArg (av[ac], XtNforeground, face->foreground);
4375 ++ac;
4378 if (!UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
4380 XtSetArg (av[ac], XtNbackground, face->background);
4381 ++ac;
4384 if (face->font
4385 && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
4386 || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
4387 || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
4388 || !UNSPECIFIEDP (LFACE_SLANT (lface))
4389 || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
4391 XtSetArg (av[ac], XtNfont, face->font);
4392 ++ac;
4395 if (ac)
4397 struct x_resources res;
4399 XtSetValues (widget, av, ac);
4401 /* We must do children here in case we're handling a pop-up menu
4402 in which case WIDGET is a popup shell. XtApplyToWidgets
4403 is a function from lwlib. */
4404 res.av = av, res.ac = ac;
4405 XtApplyToWidgets (widget, xl_apply_resources, &res);
4409 #endif /* USE_LUCID */
4412 /* On frame F, set X resources of menu-widget WIDGET from face `menu'. */
4414 void
4415 x_set_menu_resources_from_menu_face (f, widget)
4416 struct frame *f;
4417 Widget widget;
4419 /* Realized faces may have been removed on frame F, e.g. because of
4420 face attribute changes. Recompute them, if necessary, since we
4421 will need the `menu' face. */
4422 if (f->face_cache->used == 0)
4423 recompute_basic_faces (f);
4425 #ifdef USE_LUCID
4426 xl_set_menu_resources_from_menu_face (f, widget);
4427 #endif
4428 #ifdef USE_MOTIF
4429 xm_set_menu_resources_from_menu_face (f, widget);
4430 #endif
4433 #endif /* USE_X_TOOLKIT */
4435 #endif /* HAVE_X_WINDOWS */
4439 DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute,
4440 Sinternal_get_lisp_face_attribute,
4441 2, 3, 0,
4442 "Return face attribute KEYWORD of face SYMBOL.\n\
4443 If SYMBOL does not name a valid Lisp face or KEYWORD isn't a valid\n\
4444 face attribute name, signal an error.\n\
4445 If the optional argument FRAME is given, report on face FACE in that\n\
4446 frame. If FRAME is t, report on the defaults for face FACE (for new\n\
4447 frames). If FRAME is omitted or nil, use the selected frame.")
4448 (symbol, keyword, frame)
4449 Lisp_Object symbol, keyword, frame;
4451 Lisp_Object lface, value = Qnil;
4453 CHECK_SYMBOL (symbol, 0);
4454 CHECK_SYMBOL (keyword, 1);
4456 if (EQ (frame, Qt))
4457 lface = lface_from_face_name (NULL, symbol, 1);
4458 else
4460 if (NILP (frame))
4461 frame = selected_frame;
4462 CHECK_LIVE_FRAME (frame, 2);
4463 lface = lface_from_face_name (XFRAME (frame), symbol, 1);
4466 if (EQ (keyword, QCfamily))
4467 value = LFACE_FAMILY (lface);
4468 else if (EQ (keyword, QCheight))
4469 value = LFACE_HEIGHT (lface);
4470 else if (EQ (keyword, QCweight))
4471 value = LFACE_WEIGHT (lface);
4472 else if (EQ (keyword, QCslant))
4473 value = LFACE_SLANT (lface);
4474 else if (EQ (keyword, QCunderline))
4475 value = LFACE_UNDERLINE (lface);
4476 else if (EQ (keyword, QCoverline))
4477 value = LFACE_OVERLINE (lface);
4478 else if (EQ (keyword, QCstrike_through))
4479 value = LFACE_STRIKE_THROUGH (lface);
4480 else if (EQ (keyword, QCbox))
4481 value = LFACE_BOX (lface);
4482 else if (EQ (keyword, QCinverse_video)
4483 || EQ (keyword, QCreverse_video))
4484 value = LFACE_INVERSE (lface);
4485 else if (EQ (keyword, QCforeground))
4486 value = LFACE_FOREGROUND (lface);
4487 else if (EQ (keyword, QCbackground))
4488 value = LFACE_BACKGROUND (lface);
4489 else if (EQ (keyword, QCstipple))
4490 value = LFACE_STIPPLE (lface);
4491 else if (EQ (keyword, QCwidth))
4492 value = LFACE_SWIDTH (lface);
4493 else if (EQ (keyword, QCinherit))
4494 value = LFACE_INHERIT (lface);
4495 else if (EQ (keyword, QCfont))
4496 value = LFACE_FONT (lface);
4497 else
4498 signal_error ("Invalid face attribute name", keyword);
4500 return value;
4504 DEFUN ("internal-lisp-face-attribute-values",
4505 Finternal_lisp_face_attribute_values,
4506 Sinternal_lisp_face_attribute_values, 1, 1, 0,
4507 "Return a list of valid discrete values for face attribute ATTR.\n\
4508 Value is nil if ATTR doesn't have a discrete set of valid values.")
4509 (attr)
4510 Lisp_Object attr;
4512 Lisp_Object result = Qnil;
4514 CHECK_SYMBOL (attr, 0);
4516 if (EQ (attr, QCweight)
4517 || EQ (attr, QCslant)
4518 || EQ (attr, QCwidth))
4520 /* Extract permissible symbols from tables. */
4521 struct table_entry *table;
4522 int i, dim;
4524 if (EQ (attr, QCweight))
4525 table = weight_table, dim = DIM (weight_table);
4526 else if (EQ (attr, QCslant))
4527 table = slant_table, dim = DIM (slant_table);
4528 else
4529 table = swidth_table, dim = DIM (swidth_table);
4531 for (i = 0; i < dim; ++i)
4533 Lisp_Object symbol = *table[i].symbol;
4534 Lisp_Object tail = result;
4536 while (!NILP (tail)
4537 && !EQ (XCAR (tail), symbol))
4538 tail = XCDR (tail);
4540 if (NILP (tail))
4541 result = Fcons (symbol, result);
4544 else if (EQ (attr, QCunderline))
4545 result = Fcons (Qt, Fcons (Qnil, Qnil));
4546 else if (EQ (attr, QCoverline))
4547 result = Fcons (Qt, Fcons (Qnil, Qnil));
4548 else if (EQ (attr, QCstrike_through))
4549 result = Fcons (Qt, Fcons (Qnil, Qnil));
4550 else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
4551 result = Fcons (Qt, Fcons (Qnil, Qnil));
4553 return result;
4557 DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face,
4558 Sinternal_merge_in_global_face, 2, 2, 0,
4559 "Add attributes from frame-default definition of FACE to FACE on FRAME.")
4560 (face, frame)
4561 Lisp_Object face, frame;
4563 Lisp_Object global_lface, local_lface;
4564 CHECK_LIVE_FRAME (frame, 1);
4565 global_lface = lface_from_face_name (NULL, face, 1);
4566 local_lface = lface_from_face_name (XFRAME (frame), face, 0);
4567 if (NILP (local_lface))
4568 local_lface = Finternal_make_lisp_face (face, frame);
4569 default_face_vector (XVECTOR (local_lface)->contents,
4570 XVECTOR (global_lface)->contents);
4571 return face;
4575 /* The following function is implemented for compatibility with 20.2.
4576 The function is used in x-resolve-fonts when it is asked to
4577 return fonts with the same size as the font of a face. This is
4578 done in fontset.el. */
4580 DEFUN ("face-font", Fface_font, Sface_font, 1, 2, 0,
4581 "Return the font name of face FACE, or nil if it is unspecified.\n\
4582 If the optional argument FRAME is given, report on face FACE in that frame.\n\
4583 If FRAME is t, report on the defaults for face FACE (for new frames).\n\
4584 The font default for a face is either nil, or a list\n\
4585 of the form (bold), (italic) or (bold italic).\n\
4586 If FRAME is omitted or nil, use the selected frame.")
4587 (face, frame)
4588 Lisp_Object face, frame;
4590 if (EQ (frame, Qt))
4592 Lisp_Object result = Qnil;
4593 Lisp_Object lface = lface_from_face_name (NULL, face, 1);
4595 if (!UNSPECIFIEDP (LFACE_WEIGHT (lface))
4596 && !EQ (LFACE_WEIGHT (lface), Qnormal))
4597 result = Fcons (Qbold, result);
4599 if (!NILP (LFACE_SLANT (lface))
4600 && !EQ (LFACE_SLANT (lface), Qnormal))
4601 result = Fcons (Qitalic, result);
4603 return result;
4605 else
4607 struct frame *f = frame_or_selected_frame (frame, 1);
4608 int face_id = lookup_named_face (f, face, 0);
4609 struct face *face = FACE_FROM_ID (f, face_id);
4610 return build_string (face->font_name);
4615 /* Compare face vectors V1 and V2 for equality. Value is non-zero if
4616 all attributes are `equal'. Tries to be fast because this function
4617 is called quite often. */
4619 static INLINE int
4620 lface_equal_p (v1, v2)
4621 Lisp_Object *v1, *v2;
4623 int i, equal_p = 1;
4625 for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
4627 Lisp_Object a = v1[i];
4628 Lisp_Object b = v2[i];
4630 /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
4631 and the other is specified. */
4632 equal_p = XTYPE (a) == XTYPE (b);
4633 if (!equal_p)
4634 break;
4636 if (!EQ (a, b))
4638 switch (XTYPE (a))
4640 case Lisp_String:
4641 equal_p = ((STRING_BYTES (XSTRING (a))
4642 == STRING_BYTES (XSTRING (b)))
4643 && bcmp (XSTRING (a)->data, XSTRING (b)->data,
4644 STRING_BYTES (XSTRING (a))) == 0);
4645 break;
4647 case Lisp_Int:
4648 case Lisp_Symbol:
4649 equal_p = 0;
4650 break;
4652 default:
4653 equal_p = !NILP (Fequal (a, b));
4654 break;
4659 return equal_p;
4663 DEFUN ("internal-lisp-face-equal-p", Finternal_lisp_face_equal_p,
4664 Sinternal_lisp_face_equal_p, 2, 3, 0,
4665 "True if FACE1 and FACE2 are equal.\n\
4666 If the optional argument FRAME is given, report on face FACE in that frame.\n\
4667 If FRAME is t, report on the defaults for face FACE (for new frames).\n\
4668 If FRAME is omitted or nil, use the selected frame.")
4669 (face1, face2, frame)
4670 Lisp_Object face1, face2, frame;
4672 int equal_p;
4673 struct frame *f;
4674 Lisp_Object lface1, lface2;
4676 if (EQ (frame, Qt))
4677 f = NULL;
4678 else
4679 /* Don't use check_x_frame here because this function is called
4680 before X frames exist. At that time, if FRAME is nil,
4681 selected_frame will be used which is the frame dumped with
4682 Emacs. That frame is not an X frame. */
4683 f = frame_or_selected_frame (frame, 2);
4685 lface1 = lface_from_face_name (NULL, face1, 1);
4686 lface2 = lface_from_face_name (NULL, face2, 1);
4687 equal_p = lface_equal_p (XVECTOR (lface1)->contents,
4688 XVECTOR (lface2)->contents);
4689 return equal_p ? Qt : Qnil;
4693 DEFUN ("internal-lisp-face-empty-p", Finternal_lisp_face_empty_p,
4694 Sinternal_lisp_face_empty_p, 1, 2, 0,
4695 "True if FACE has no attribute specified.\n\
4696 If the optional argument FRAME is given, report on face FACE in that frame.\n\
4697 If FRAME is t, report on the defaults for face FACE (for new frames).\n\
4698 If FRAME is omitted or nil, use the selected frame.")
4699 (face, frame)
4700 Lisp_Object face, frame;
4702 struct frame *f;
4703 Lisp_Object lface;
4704 int i;
4706 if (NILP (frame))
4707 frame = selected_frame;
4708 CHECK_LIVE_FRAME (frame, 0);
4709 f = XFRAME (frame);
4711 if (EQ (frame, Qt))
4712 lface = lface_from_face_name (NULL, face, 1);
4713 else
4714 lface = lface_from_face_name (f, face, 1);
4716 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4717 if (!UNSPECIFIEDP (XVECTOR (lface)->contents[i]))
4718 break;
4720 return i == LFACE_VECTOR_SIZE ? Qt : Qnil;
4724 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
4725 0, 1, 0,
4726 "Return an alist of frame-local faces defined on FRAME.\n\
4727 For internal use only.")
4728 (frame)
4729 Lisp_Object frame;
4731 struct frame *f = frame_or_selected_frame (frame, 0);
4732 return f->face_alist;
4736 /* Return a hash code for Lisp string STRING with case ignored. Used
4737 below in computing a hash value for a Lisp face. */
4739 static INLINE unsigned
4740 hash_string_case_insensitive (string)
4741 Lisp_Object string;
4743 unsigned char *s;
4744 unsigned hash = 0;
4745 xassert (STRINGP (string));
4746 for (s = XSTRING (string)->data; *s; ++s)
4747 hash = (hash << 1) ^ tolower (*s);
4748 return hash;
4752 /* Return a hash code for face attribute vector V. */
4754 static INLINE unsigned
4755 lface_hash (v)
4756 Lisp_Object *v;
4758 return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
4759 ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
4760 ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
4761 ^ XFASTINT (v[LFACE_WEIGHT_INDEX])
4762 ^ XFASTINT (v[LFACE_SLANT_INDEX])
4763 ^ XFASTINT (v[LFACE_SWIDTH_INDEX])
4764 ^ XFASTINT (v[LFACE_HEIGHT_INDEX]));
4768 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without
4769 considering charsets/registries). They do if they specify the same
4770 family, point size, weight, width, slant, and fontset. Both LFACE1
4771 and LFACE2 must be fully-specified. */
4773 static INLINE int
4774 lface_same_font_attributes_p (lface1, lface2)
4775 Lisp_Object *lface1, *lface2;
4777 xassert (lface_fully_specified_p (lface1)
4778 && lface_fully_specified_p (lface2));
4779 return (xstricmp (XSTRING (lface1[LFACE_FAMILY_INDEX])->data,
4780 XSTRING (lface2[LFACE_FAMILY_INDEX])->data) == 0
4781 && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
4782 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
4783 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
4784 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX])
4785 && (EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
4786 || (STRINGP (lface1[LFACE_FONT_INDEX])
4787 && STRINGP (lface2[LFACE_FONT_INDEX])
4788 && xstricmp (XSTRING (lface1[LFACE_FONT_INDEX])->data,
4789 XSTRING (lface2[LFACE_FONT_INDEX])->data))));
4794 /***********************************************************************
4795 Realized Faces
4796 ***********************************************************************/
4798 /* Allocate and return a new realized face for Lisp face attribute
4799 vector ATTR. */
4801 static struct face *
4802 make_realized_face (attr)
4803 Lisp_Object *attr;
4805 struct face *face = (struct face *) xmalloc (sizeof *face);
4806 bzero (face, sizeof *face);
4807 face->ascii_face = face;
4808 bcopy (attr, face->lface, sizeof face->lface);
4809 return face;
4813 /* Free realized face FACE, including its X resources. FACE may
4814 be null. */
4816 static void
4817 free_realized_face (f, face)
4818 struct frame *f;
4819 struct face *face;
4821 if (face)
4823 #ifdef HAVE_WINDOW_SYSTEM
4824 if (FRAME_WINDOW_P (f))
4826 /* Free fontset of FACE if it is ASCII face. */
4827 if (face->fontset >= 0 && face == face->ascii_face)
4828 free_face_fontset (f, face);
4829 if (face->gc)
4831 x_free_gc (f, face->gc);
4832 face->gc = 0;
4835 free_face_colors (f, face);
4836 x_destroy_bitmap (f, face->stipple);
4838 #endif /* HAVE_WINDOW_SYSTEM */
4840 xfree (face);
4845 /* Prepare face FACE for subsequent display on frame F. This
4846 allocated GCs if they haven't been allocated yet or have been freed
4847 by clearing the face cache. */
4849 void
4850 prepare_face_for_display (f, face)
4851 struct frame *f;
4852 struct face *face;
4854 #ifdef HAVE_WINDOW_SYSTEM
4855 xassert (FRAME_WINDOW_P (f));
4857 if (face->gc == 0)
4859 XGCValues xgcv;
4860 unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
4862 xgcv.foreground = face->foreground;
4863 xgcv.background = face->background;
4864 #ifdef HAVE_X_WINDOWS
4865 xgcv.graphics_exposures = False;
4866 #endif
4867 /* The font of FACE may be null if we couldn't load it. */
4868 if (face->font)
4870 #ifdef HAVE_X_WINDOWS
4871 xgcv.font = face->font->fid;
4872 #endif
4873 #ifdef WINDOWSNT
4874 xgcv.font = face->font;
4875 #endif
4876 mask |= GCFont;
4879 BLOCK_INPUT;
4880 #ifdef HAVE_X_WINDOWS
4881 if (face->stipple)
4883 xgcv.fill_style = FillOpaqueStippled;
4884 xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
4885 mask |= GCFillStyle | GCStipple;
4887 #endif
4888 face->gc = x_create_gc (f, mask, &xgcv);
4889 UNBLOCK_INPUT;
4891 #endif /* HAVE_WINDOW_SYSTEM */
4895 /***********************************************************************
4896 Face Cache
4897 ***********************************************************************/
4899 /* Return a new face cache for frame F. */
4901 static struct face_cache *
4902 make_face_cache (f)
4903 struct frame *f;
4905 struct face_cache *c;
4906 int size;
4908 c = (struct face_cache *) xmalloc (sizeof *c);
4909 bzero (c, sizeof *c);
4910 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4911 c->buckets = (struct face **) xmalloc (size);
4912 bzero (c->buckets, size);
4913 c->size = 50;
4914 c->faces_by_id = (struct face **) xmalloc (c->size * sizeof *c->faces_by_id);
4915 c->f = f;
4916 return c;
4920 /* Clear out all graphics contexts for all realized faces, except for
4921 the basic faces. This should be done from time to time just to avoid
4922 keeping too many graphics contexts that are no longer needed. */
4924 static void
4925 clear_face_gcs (c)
4926 struct face_cache *c;
4928 if (c && FRAME_WINDOW_P (c->f))
4930 #ifdef HAVE_WINDOW_SYSTEM
4931 int i;
4932 for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
4934 struct face *face = c->faces_by_id[i];
4935 if (face && face->gc)
4937 x_free_gc (c->f, face->gc);
4938 face->gc = 0;
4941 #endif /* HAVE_WINDOW_SYSTEM */
4946 /* Free all realized faces in face cache C, including basic faces. C
4947 may be null. If faces are freed, make sure the frame's current
4948 matrix is marked invalid, so that a display caused by an expose
4949 event doesn't try to use faces we destroyed. */
4951 static void
4952 free_realized_faces (c)
4953 struct face_cache *c;
4955 if (c && c->used)
4957 int i, size;
4958 struct frame *f = c->f;
4960 /* We must block input here because we can't process X events
4961 safely while only some faces are freed, or when the frame's
4962 current matrix still references freed faces. */
4963 BLOCK_INPUT;
4965 for (i = 0; i < c->used; ++i)
4967 free_realized_face (f, c->faces_by_id[i]);
4968 c->faces_by_id[i] = NULL;
4971 c->used = 0;
4972 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4973 bzero (c->buckets, size);
4975 /* Must do a thorough redisplay the next time. Mark current
4976 matrices as invalid because they will reference faces freed
4977 above. This function is also called when a frame is
4978 destroyed. In this case, the root window of F is nil. */
4979 if (WINDOWP (f->root_window))
4981 clear_current_matrices (f);
4982 ++windows_or_buffers_changed;
4985 UNBLOCK_INPUT;
4990 /* Free all faces realized for multibyte characters on frame F that
4991 has FONTSET. */
4993 void
4994 free_realized_multibyte_face (f, fontset)
4995 struct frame *f;
4996 int fontset;
4998 struct face_cache *cache = FRAME_FACE_CACHE (f);
4999 struct face *face;
5000 int i;
5002 /* We must block input here because we can't process X events safely
5003 while only some faces are freed, or when the frame's current
5004 matrix still references freed faces. */
5005 BLOCK_INPUT;
5007 for (i = 0; i < cache->used; i++)
5009 face = cache->faces_by_id[i];
5010 if (face
5011 && face != face->ascii_face
5012 && face->fontset == fontset)
5014 uncache_face (cache, face);
5015 free_realized_face (f, face);
5019 /* Must do a thorough redisplay the next time. Mark current
5020 matrices as invalid because they will reference faces freed
5021 above. This function is also called when a frame is destroyed.
5022 In this case, the root window of F is nil. */
5023 if (WINDOWP (f->root_window))
5025 clear_current_matrices (f);
5026 ++windows_or_buffers_changed;
5029 UNBLOCK_INPUT;
5033 /* Free all realized faces on FRAME or on all frames if FRAME is nil.
5034 This is done after attributes of a named face have been changed,
5035 because we can't tell which realized faces depend on that face. */
5037 void
5038 free_all_realized_faces (frame)
5039 Lisp_Object frame;
5041 if (NILP (frame))
5043 Lisp_Object rest;
5044 FOR_EACH_FRAME (rest, frame)
5045 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
5047 else
5048 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
5052 /* Free face cache C and faces in it, including their X resources. */
5054 static void
5055 free_face_cache (c)
5056 struct face_cache *c;
5058 if (c)
5060 free_realized_faces (c);
5061 xfree (c->buckets);
5062 xfree (c->faces_by_id);
5063 xfree (c);
5068 /* Cache realized face FACE in face cache C. HASH is the hash value
5069 of FACE. If FACE->fontset >= 0, add the new face to the end of the
5070 collision list of the face hash table of C. This is done because
5071 otherwise lookup_face would find FACE for every character, even if
5072 faces with the same attributes but for specific characters exist. */
5074 static void
5075 cache_face (c, face, hash)
5076 struct face_cache *c;
5077 struct face *face;
5078 unsigned hash;
5080 int i = hash % FACE_CACHE_BUCKETS_SIZE;
5082 face->hash = hash;
5084 if (face->fontset >= 0)
5086 struct face *last = c->buckets[i];
5087 if (last)
5089 while (last->next)
5090 last = last->next;
5091 last->next = face;
5092 face->prev = last;
5093 face->next = NULL;
5095 else
5097 c->buckets[i] = face;
5098 face->prev = face->next = NULL;
5101 else
5103 face->prev = NULL;
5104 face->next = c->buckets[i];
5105 if (face->next)
5106 face->next->prev = face;
5107 c->buckets[i] = face;
5110 /* Find a free slot in C->faces_by_id and use the index of the free
5111 slot as FACE->id. */
5112 for (i = 0; i < c->used; ++i)
5113 if (c->faces_by_id[i] == NULL)
5114 break;
5115 face->id = i;
5117 /* Maybe enlarge C->faces_by_id. */
5118 if (i == c->used && c->used == c->size)
5120 int new_size = 2 * c->size;
5121 int sz = new_size * sizeof *c->faces_by_id;
5122 c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
5123 c->size = new_size;
5126 #if GLYPH_DEBUG
5127 /* Check that FACE got a unique id. */
5129 int j, n;
5130 struct face *face;
5132 for (j = n = 0; j < FACE_CACHE_BUCKETS_SIZE; ++j)
5133 for (face = c->buckets[j]; face; face = face->next)
5134 if (face->id == i)
5135 ++n;
5137 xassert (n == 1);
5139 #endif /* GLYPH_DEBUG */
5141 c->faces_by_id[i] = face;
5142 if (i == c->used)
5143 ++c->used;
5147 /* Remove face FACE from cache C. */
5149 static void
5150 uncache_face (c, face)
5151 struct face_cache *c;
5152 struct face *face;
5154 int i = face->hash % FACE_CACHE_BUCKETS_SIZE;
5156 if (face->prev)
5157 face->prev->next = face->next;
5158 else
5159 c->buckets[i] = face->next;
5161 if (face->next)
5162 face->next->prev = face->prev;
5164 c->faces_by_id[face->id] = NULL;
5165 if (face->id == c->used)
5166 --c->used;
5170 /* Look up a realized face with face attributes ATTR in the face cache
5171 of frame F. The face will be used to display character C. Value
5172 is the ID of the face found. If no suitable face is found, realize
5173 a new one. In that case, if C is a multibyte character, BASE_FACE
5174 is a face that has the same attributes. */
5176 INLINE int
5177 lookup_face (f, attr, c, base_face)
5178 struct frame *f;
5179 Lisp_Object *attr;
5180 int c;
5181 struct face *base_face;
5183 struct face_cache *cache = FRAME_FACE_CACHE (f);
5184 unsigned hash;
5185 int i;
5186 struct face *face;
5188 xassert (cache != NULL);
5189 check_lface_attrs (attr);
5191 /* Look up ATTR in the face cache. */
5192 hash = lface_hash (attr);
5193 i = hash % FACE_CACHE_BUCKETS_SIZE;
5195 for (face = cache->buckets[i]; face; face = face->next)
5196 if (face->hash == hash
5197 && (!FRAME_WINDOW_P (f)
5198 || FACE_SUITABLE_FOR_CHAR_P (face, c))
5199 && lface_equal_p (face->lface, attr))
5200 break;
5202 /* If not found, realize a new face. */
5203 if (face == NULL)
5204 face = realize_face (cache, attr, c, base_face, -1);
5206 #if GLYPH_DEBUG
5207 xassert (face == FACE_FROM_ID (f, face->id));
5209 /* When this function is called from face_for_char (in this case, C is
5210 a multibyte character), a fontset of a face returned by
5211 realize_face is not yet set, i.e. FACE_SUITABLE_FOR_CHAR_P (FACE,
5212 C) is not sutisfied. The fontset is set for this face by
5213 face_for_char later. */
5214 #if 0
5215 if (FRAME_WINDOW_P (f))
5216 xassert (FACE_SUITABLE_FOR_CHAR_P (face, c));
5217 #endif
5218 #endif /* GLYPH_DEBUG */
5220 return face->id;
5224 /* Return the face id of the realized face for named face SYMBOL on
5225 frame F suitable for displaying character C. */
5228 lookup_named_face (f, symbol, c)
5229 struct frame *f;
5230 Lisp_Object symbol;
5231 int c;
5233 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5234 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
5235 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5237 get_lface_attributes (f, symbol, symbol_attrs, 1);
5238 bcopy (default_face->lface, attrs, sizeof attrs);
5239 merge_face_vectors (f, symbol_attrs, attrs, Qnil);
5240 return lookup_face (f, attrs, c, NULL);
5244 /* Return the ID of the realized ASCII face of Lisp face with ID
5245 LFACE_ID on frame F. Value is -1 if LFACE_ID isn't valid. */
5248 ascii_face_of_lisp_face (f, lface_id)
5249 struct frame *f;
5250 int lface_id;
5252 int face_id;
5254 if (lface_id >= 0 && lface_id < lface_id_to_name_size)
5256 Lisp_Object face_name = lface_id_to_name[lface_id];
5257 face_id = lookup_named_face (f, face_name, 0);
5259 else
5260 face_id = -1;
5262 return face_id;
5266 /* Return a face for charset ASCII that is like the face with id
5267 FACE_ID on frame F, but has a font that is STEPS steps smaller.
5268 STEPS < 0 means larger. Value is the id of the face. */
5271 smaller_face (f, face_id, steps)
5272 struct frame *f;
5273 int face_id, steps;
5275 #ifdef HAVE_WINDOW_SYSTEM
5276 struct face *face;
5277 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5278 int pt, last_pt, last_height;
5279 int delta;
5280 int new_face_id;
5281 struct face *new_face;
5283 /* If not called for an X frame, just return the original face. */
5284 if (FRAME_TERMCAP_P (f))
5285 return face_id;
5287 /* Try in increments of 1/2 pt. */
5288 delta = steps < 0 ? 5 : -5;
5289 steps = abs (steps);
5291 face = FACE_FROM_ID (f, face_id);
5292 bcopy (face->lface, attrs, sizeof attrs);
5293 pt = last_pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
5294 new_face_id = face_id;
5295 last_height = FONT_HEIGHT (face->font);
5297 while (steps
5298 && pt + delta > 0
5299 /* Give up if we cannot find a font within 10pt. */
5300 && abs (last_pt - pt) < 100)
5302 /* Look up a face for a slightly smaller/larger font. */
5303 pt += delta;
5304 attrs[LFACE_HEIGHT_INDEX] = make_number (pt);
5305 new_face_id = lookup_face (f, attrs, 0, NULL);
5306 new_face = FACE_FROM_ID (f, new_face_id);
5308 /* If height changes, count that as one step. */
5309 if (FONT_HEIGHT (new_face->font) != last_height)
5311 --steps;
5312 last_height = FONT_HEIGHT (new_face->font);
5313 last_pt = pt;
5317 return new_face_id;
5319 #else /* not HAVE_WINDOW_SYSTEM */
5321 return face_id;
5323 #endif /* not HAVE_WINDOW_SYSTEM */
5327 /* Return a face for charset ASCII that is like the face with id
5328 FACE_ID on frame F, but has height HEIGHT. */
5331 face_with_height (f, face_id, height)
5332 struct frame *f;
5333 int face_id;
5334 int height;
5336 #ifdef HAVE_WINDOW_SYSTEM
5337 struct face *face;
5338 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5340 if (FRAME_TERMCAP_P (f)
5341 || height <= 0)
5342 return face_id;
5344 face = FACE_FROM_ID (f, face_id);
5345 bcopy (face->lface, attrs, sizeof attrs);
5346 attrs[LFACE_HEIGHT_INDEX] = make_number (height);
5347 face_id = lookup_face (f, attrs, 0, NULL);
5348 #endif /* HAVE_WINDOW_SYSTEM */
5350 return face_id;
5353 /* Return the face id of the realized face for named face SYMBOL on
5354 frame F suitable for displaying character C, and use attributes of
5355 the face FACE_ID for attributes that aren't completely specified by
5356 SYMBOL. This is like lookup_named_face, except that the default
5357 attributes come from FACE_ID, not from the default face. FACE_ID
5358 is assumed to be already realized. */
5361 lookup_derived_face (f, symbol, c, face_id)
5362 struct frame *f;
5363 Lisp_Object symbol;
5364 int c;
5365 int face_id;
5367 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5368 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
5369 struct face *default_face = FACE_FROM_ID (f, face_id);
5371 if (!default_face)
5372 abort ();
5374 get_lface_attributes (f, symbol, symbol_attrs, 1);
5375 bcopy (default_face->lface, attrs, sizeof attrs);
5376 merge_face_vectors (f, symbol_attrs, attrs, Qnil);
5377 return lookup_face (f, attrs, c, default_face);
5382 /***********************************************************************
5383 Font selection
5384 ***********************************************************************/
5386 DEFUN ("internal-set-font-selection-order",
5387 Finternal_set_font_selection_order,
5388 Sinternal_set_font_selection_order, 1, 1, 0,
5389 "Set font selection order for face font selection to ORDER.\n\
5390 ORDER must be a list of length 4 containing the symbols `:width',\n\
5391 `:height', `:weight', and `:slant'. Face attributes appearing\n\
5392 first in ORDER are matched first, e.g. if `:height' appears before\n\
5393 `:weight' in ORDER, font selection first tries to find a font with\n\
5394 a suitable height, and then tries to match the font weight.\n\
5395 Value is ORDER.")
5396 (order)
5397 Lisp_Object order;
5399 Lisp_Object list;
5400 int i;
5401 int indices[4];
5403 CHECK_LIST (order, 0);
5404 bzero (indices, sizeof indices);
5405 i = 0;
5407 for (list = order;
5408 CONSP (list) && i < DIM (indices);
5409 list = XCDR (list), ++i)
5411 Lisp_Object attr = XCAR (list);
5412 int xlfd;
5414 if (EQ (attr, QCwidth))
5415 xlfd = XLFD_SWIDTH;
5416 else if (EQ (attr, QCheight))
5417 xlfd = XLFD_POINT_SIZE;
5418 else if (EQ (attr, QCweight))
5419 xlfd = XLFD_WEIGHT;
5420 else if (EQ (attr, QCslant))
5421 xlfd = XLFD_SLANT;
5422 else
5423 break;
5425 if (indices[i] != 0)
5426 break;
5427 indices[i] = xlfd;
5430 if (!NILP (list)
5431 || i != DIM (indices)
5432 || indices[0] == 0
5433 || indices[1] == 0
5434 || indices[2] == 0
5435 || indices[3] == 0)
5436 signal_error ("Invalid font sort order", order);
5438 if (bcmp (indices, font_sort_order, sizeof indices) != 0)
5440 bcopy (indices, font_sort_order, sizeof font_sort_order);
5441 free_all_realized_faces (Qnil);
5444 return Qnil;
5448 DEFUN ("internal-set-alternative-font-family-alist",
5449 Finternal_set_alternative_font_family_alist,
5450 Sinternal_set_alternative_font_family_alist, 1, 1, 0,
5451 "Define alternative font families to try in face font selection.\n\
5452 ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.\n\
5453 Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can\n\
5454 be found. Value is ALIST.")
5455 (alist)
5456 Lisp_Object alist;
5458 CHECK_LIST (alist, 0);
5459 Vface_alternative_font_family_alist = alist;
5460 free_all_realized_faces (Qnil);
5461 return alist;
5465 #ifdef HAVE_WINDOW_SYSTEM
5467 /* Value is non-zero if FONT is the name of a scalable font. The
5468 X11R6 XLFD spec says that point size, pixel size, and average width
5469 are zero for scalable fonts. Intlfonts contain at least one
5470 scalable font ("*-muleindian-1") for which this isn't true, so we
5471 just test average width. */
5473 static int
5474 font_scalable_p (font)
5475 struct font_name *font;
5477 char *s = font->fields[XLFD_AVGWIDTH];
5478 return (*s == '0' && *(s + 1) == '\0')
5479 #ifdef WINDOWSNT
5480 /* Windows implementation of XLFD is slightly broken for backward
5481 compatibility with previous broken versions, so test for
5482 wildcards as well as 0. */
5483 || *s == '*'
5484 #endif
5489 /* Value is non-zero if FONT1 is a better match for font attributes
5490 VALUES than FONT2. VALUES is an array of face attribute values in
5491 font sort order. COMPARE_PT_P zero means don't compare point
5492 sizes. */
5494 static int
5495 better_font_p (values, font1, font2, compare_pt_p)
5496 int *values;
5497 struct font_name *font1, *font2;
5498 int compare_pt_p;
5500 int i;
5502 for (i = 0; i < 4; ++i)
5504 int xlfd_idx = font_sort_order[i];
5506 if (compare_pt_p || xlfd_idx != XLFD_POINT_SIZE)
5508 int delta1 = abs (values[i] - font1->numeric[xlfd_idx]);
5509 int delta2 = abs (values[i] - font2->numeric[xlfd_idx]);
5511 if (delta1 > delta2)
5512 return 0;
5513 else if (delta1 < delta2)
5514 return 1;
5515 else
5517 /* The difference may be equal because, e.g., the face
5518 specifies `italic' but we have only `regular' and
5519 `oblique'. Prefer `oblique' in this case. */
5520 if ((xlfd_idx == XLFD_WEIGHT || xlfd_idx == XLFD_SLANT)
5521 && font1->numeric[xlfd_idx] > values[i]
5522 && font2->numeric[xlfd_idx] < values[i])
5523 return 1;
5528 return 0;
5532 #if SCALABLE_FONTS
5534 /* Value is non-zero if FONT is an exact match for face attributes in
5535 SPECIFIED. SPECIFIED is an array of face attribute values in font
5536 sort order. */
5538 static int
5539 exact_face_match_p (specified, font)
5540 int *specified;
5541 struct font_name *font;
5543 int i;
5545 for (i = 0; i < 4; ++i)
5546 if (specified[i] != font->numeric[font_sort_order[i]])
5547 break;
5549 return i == 4;
5553 /* Value is the name of a scaled font, generated from scalable font
5554 FONT on frame F. SPECIFIED_PT is the point-size to scale FONT to.
5555 Value is allocated from heap. */
5557 static char *
5558 build_scalable_font_name (f, font, specified_pt)
5559 struct frame *f;
5560 struct font_name *font;
5561 int specified_pt;
5563 char point_size[20], pixel_size[20];
5564 int pixel_value;
5565 double resy = FRAME_X_DISPLAY_INFO (f)->resy;
5566 double pt;
5568 /* If scalable font is for a specific resolution, compute
5569 the point size we must specify from the resolution of
5570 the display and the specified resolution of the font. */
5571 if (font->numeric[XLFD_RESY] != 0)
5573 pt = resy / font->numeric[XLFD_RESY] * specified_pt + 0.5;
5574 pixel_value = font->numeric[XLFD_RESY] / 720.0 * pt;
5576 else
5578 pt = specified_pt;
5579 pixel_value = resy / 720.0 * pt;
5582 /* Set point size of the font. */
5583 sprintf (point_size, "%d", (int) pt);
5584 font->fields[XLFD_POINT_SIZE] = point_size;
5585 font->numeric[XLFD_POINT_SIZE] = pt;
5587 /* Set pixel size. */
5588 sprintf (pixel_size, "%d", pixel_value);
5589 font->fields[XLFD_PIXEL_SIZE] = pixel_size;
5590 font->numeric[XLFD_PIXEL_SIZE] = pixel_value;
5592 /* If font doesn't specify its resolution, use the
5593 resolution of the display. */
5594 if (font->numeric[XLFD_RESY] == 0)
5596 char buffer[20];
5597 sprintf (buffer, "%d", (int) resy);
5598 font->fields[XLFD_RESY] = buffer;
5599 font->numeric[XLFD_RESY] = resy;
5602 if (strcmp (font->fields[XLFD_RESX], "0") == 0)
5604 char buffer[20];
5605 int resx = FRAME_X_DISPLAY_INFO (f)->resx;
5606 sprintf (buffer, "%d", resx);
5607 font->fields[XLFD_RESX] = buffer;
5608 font->numeric[XLFD_RESX] = resx;
5611 return build_font_name (font);
5615 /* Value is non-zero if we are allowed to use scalable font FONT. We
5616 can't run a Lisp function here since this function may be called
5617 with input blocked. */
5619 static int
5620 may_use_scalable_font_p (font, name)
5621 struct font_name *font;
5622 char *name;
5624 if (EQ (Vscalable_fonts_allowed, Qt))
5625 return 1;
5626 else if (CONSP (Vscalable_fonts_allowed))
5628 Lisp_Object tail, regexp;
5630 for (tail = Vscalable_fonts_allowed; CONSP (tail); tail = XCDR (tail))
5632 regexp = XCAR (tail);
5633 if (STRINGP (regexp)
5634 && fast_c_string_match_ignore_case (regexp, name) >= 0)
5635 return 1;
5639 return 0;
5642 #endif /* SCALABLE_FONTS != 0 */
5645 /* Return the name of the best matching font for face attributes
5646 ATTRS in the array of font_name structures FONTS which contains
5647 NFONTS elements. Value is a font name which is allocated from
5648 the heap. FONTS is freed by this function. */
5650 static char *
5651 best_matching_font (f, attrs, fonts, nfonts)
5652 struct frame *f;
5653 Lisp_Object *attrs;
5654 struct font_name *fonts;
5655 int nfonts;
5657 char *font_name;
5658 struct font_name *best;
5659 int i, pt;
5660 int specified[4];
5661 int exact_p;
5663 if (nfonts == 0)
5664 return NULL;
5666 /* Make specified font attributes available in `specified',
5667 indexed by sort order. */
5668 for (i = 0; i < DIM (font_sort_order); ++i)
5670 int xlfd_idx = font_sort_order[i];
5672 if (xlfd_idx == XLFD_SWIDTH)
5673 specified[i] = face_numeric_swidth (attrs[LFACE_SWIDTH_INDEX]);
5674 else if (xlfd_idx == XLFD_POINT_SIZE)
5675 specified[i] = pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
5676 else if (xlfd_idx == XLFD_WEIGHT)
5677 specified[i] = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
5678 else if (xlfd_idx == XLFD_SLANT)
5679 specified[i] = face_numeric_slant (attrs[LFACE_SLANT_INDEX]);
5680 else
5681 abort ();
5684 #if SCALABLE_FONTS
5686 /* Set to 1 */
5687 exact_p = 0;
5689 /* Start with the first non-scalable font in the list. */
5690 for (i = 0; i < nfonts; ++i)
5691 if (!font_scalable_p (fonts + i))
5692 break;
5694 /* Find the best match among the non-scalable fonts. */
5695 if (i < nfonts)
5697 best = fonts + i;
5699 for (i = 1; i < nfonts; ++i)
5700 if (!font_scalable_p (fonts + i)
5701 && better_font_p (specified, fonts + i, best, 1))
5703 best = fonts + i;
5705 exact_p = exact_face_match_p (specified, best);
5706 if (exact_p)
5707 break;
5711 else
5712 best = NULL;
5714 /* Unless we found an exact match among non-scalable fonts, see if
5715 we can find a better match among scalable fonts. */
5716 if (!exact_p)
5718 /* A scalable font is better if
5720 1. its weight, slant, swidth attributes are better, or.
5722 2. the best non-scalable font doesn't have the required
5723 point size, and the scalable fonts weight, slant, swidth
5724 isn't worse. */
5726 int non_scalable_has_exact_height_p;
5728 if (best && best->numeric[XLFD_POINT_SIZE] == pt)
5729 non_scalable_has_exact_height_p = 1;
5730 else
5731 non_scalable_has_exact_height_p = 0;
5733 for (i = 0; i < nfonts; ++i)
5734 if (font_scalable_p (fonts + i))
5736 if (best == NULL
5737 || better_font_p (specified, fonts + i, best, 0)
5738 || (!non_scalable_has_exact_height_p
5739 && !better_font_p (specified, best, fonts + i, 0)))
5740 best = fonts + i;
5744 if (font_scalable_p (best))
5745 font_name = build_scalable_font_name (f, best, pt);
5746 else
5747 font_name = build_font_name (best);
5749 #else /* !SCALABLE_FONTS */
5751 /* Find the best non-scalable font. */
5752 best = fonts;
5754 for (i = 1; i < nfonts; ++i)
5756 xassert (!font_scalable_p (fonts + i));
5757 if (better_font_p (specified, fonts + i, best, 1))
5758 best = fonts + i;
5761 font_name = build_font_name (best);
5763 #endif /* !SCALABLE_FONTS */
5765 /* Free font_name structures. */
5766 free_font_names (fonts, nfonts);
5768 return font_name;
5772 /* Try to get a list of fonts on frame F with font family FAMILY and
5773 registry/encoding REGISTRY. Return in *FONTS a pointer to a vector
5774 of font_name structures for the fonts matched. Value is the number
5775 of fonts found. */
5777 static int
5778 try_font_list (f, attrs, pattern, family, registry, fonts)
5779 struct frame *f;
5780 Lisp_Object *attrs;
5781 Lisp_Object pattern, family, registry;
5782 struct font_name **fonts;
5784 int nfonts;
5786 if (NILP (family) && STRINGP (attrs[LFACE_FAMILY_INDEX]))
5787 family = attrs[LFACE_FAMILY_INDEX];
5789 nfonts = font_list (f, pattern, family, registry, fonts);
5791 if (nfonts == 0 && !NILP (family))
5793 Lisp_Object alter;
5795 /* Try alternative font families from
5796 Vface_alternative_font_family_alist. */
5797 alter = Fassoc (family, Vface_alternative_font_family_alist);
5798 if (CONSP (alter))
5799 for (alter = XCDR (alter);
5800 CONSP (alter) && nfonts == 0;
5801 alter = XCDR (alter))
5803 if (STRINGP (XCAR (alter)))
5804 nfonts = font_list (f, Qnil, XCAR (alter), registry, fonts);
5807 /* Try font family of the default face or "fixed". */
5808 if (nfonts == 0)
5810 struct face *dflt = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5811 if (dflt)
5812 family = dflt->lface[LFACE_FAMILY_INDEX];
5813 else
5814 family = build_string ("fixed");
5815 nfonts = font_list (f, Qnil, family, registry, fonts);
5818 /* Try any family with the given registry. */
5819 if (nfonts == 0)
5820 nfonts = font_list (f, Qnil, Qnil, registry, fonts);
5823 return nfonts;
5827 /* Return the fontset id of the base fontset name or alias name given
5828 by the fontset attribute of ATTRS. Value is -1 if the fontset
5829 attribute of ATTRS doesn't name a fontset. */
5831 static int
5832 face_fontset (attrs)
5833 Lisp_Object *attrs;
5835 Lisp_Object name;
5836 int fontset;
5838 name = attrs[LFACE_FONT_INDEX];
5839 if (!STRINGP (name))
5840 return -1;
5841 return fs_query_fontset (name, 0);
5845 /* Choose a name of font to use on frame F to display character C with
5846 Lisp face attributes specified by ATTRS. The font name is
5847 determined by the font-related attributes in ATTRS and the name
5848 pattern for C in FONTSET. Value is the font name which is
5849 allocated from the heap and must be freed by the caller, or NULL if
5850 we can get no information about the font name of C. It is assured
5851 that we always get some information for a single byte
5852 character. */
5854 static char *
5855 choose_face_font (f, attrs, fontset, c)
5856 struct frame *f;
5857 Lisp_Object *attrs;
5858 int fontset, c;
5860 Lisp_Object pattern;
5861 char *font_name = NULL;
5862 struct font_name *fonts;
5863 int nfonts;
5865 /* Get (foundry and) family name and registry (and encoding) name of
5866 a font for C. */
5867 pattern = fontset_font_pattern (f, fontset, c);
5868 if (NILP (pattern))
5870 xassert (!SINGLE_BYTE_CHAR_P (c));
5871 return NULL;
5873 /* If what we got is a name pattern, return it. */
5874 if (STRINGP (pattern))
5875 return xstrdup (XSTRING (pattern)->data);
5877 /* Family name may be specified both in ATTRS and car part of
5878 PATTERN. The former has higher priority if C is a single byte
5879 character. */
5880 if (STRINGP (attrs[LFACE_FAMILY_INDEX])
5881 && SINGLE_BYTE_CHAR_P (c))
5882 XCAR (pattern) = Qnil;
5884 /* Get a list of fonts matching that pattern and choose the
5885 best match for the specified face attributes from it. */
5886 nfonts = try_font_list (f, attrs, Qnil, XCAR (pattern), XCDR (pattern),
5887 &fonts);
5888 font_name = best_matching_font (f, attrs, fonts, nfonts);
5889 return font_name;
5892 #endif /* HAVE_WINDOW_SYSTEM */
5896 /***********************************************************************
5897 Face Realization
5898 ***********************************************************************/
5900 /* Realize basic faces on frame F. Value is zero if frame parameters
5901 of F don't contain enough information needed to realize the default
5902 face. */
5904 static int
5905 realize_basic_faces (f)
5906 struct frame *f;
5908 int success_p = 0;
5910 /* Block input there so that we won't be surprised by an X expose
5911 event, for instance without having the faces set up. */
5912 BLOCK_INPUT;
5914 if (realize_default_face (f))
5916 realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
5917 realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
5918 realize_named_face (f, Qfringe, BITMAP_AREA_FACE_ID);
5919 realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID);
5920 realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID);
5921 realize_named_face (f, Qborder, BORDER_FACE_ID);
5922 realize_named_face (f, Qcursor, CURSOR_FACE_ID);
5923 realize_named_face (f, Qmouse, MOUSE_FACE_ID);
5924 realize_named_face (f, Qmenu, MENU_FACE_ID);
5925 success_p = 1;
5928 UNBLOCK_INPUT;
5929 return success_p;
5933 /* Realize the default face on frame F. If the face is not fully
5934 specified, make it fully-specified. Attributes of the default face
5935 that are not explicitly specified are taken from frame parameters. */
5937 static int
5938 realize_default_face (f)
5939 struct frame *f;
5941 struct face_cache *c = FRAME_FACE_CACHE (f);
5942 Lisp_Object lface;
5943 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5944 Lisp_Object frame_font;
5945 struct face *face;
5946 int fontset;
5948 /* If the `default' face is not yet known, create it. */
5949 lface = lface_from_face_name (f, Qdefault, 0);
5950 if (NILP (lface))
5952 Lisp_Object frame;
5953 XSETFRAME (frame, f);
5954 lface = Finternal_make_lisp_face (Qdefault, frame);
5957 #ifdef HAVE_WINDOW_SYSTEM
5958 if (FRAME_WINDOW_P (f))
5960 /* Set frame_font to the value of the `font' frame parameter. */
5961 frame_font = Fassq (Qfont, f->param_alist);
5962 xassert (CONSP (frame_font) && STRINGP (XCDR (frame_font)));
5963 frame_font = XCDR (frame_font);
5964 set_lface_from_font_name (f, lface, frame_font, 0, 1);
5966 #endif /* HAVE_WINDOW_SYSTEM */
5968 if (!FRAME_WINDOW_P (f))
5970 LFACE_FAMILY (lface) = build_string ("default");
5971 LFACE_SWIDTH (lface) = Qnormal;
5972 LFACE_HEIGHT (lface) = make_number (1);
5973 LFACE_WEIGHT (lface) = Qnormal;
5974 LFACE_SLANT (lface) = Qnormal;
5977 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
5978 LFACE_UNDERLINE (lface) = Qnil;
5980 if (UNSPECIFIEDP (LFACE_OVERLINE (lface)))
5981 LFACE_OVERLINE (lface) = Qnil;
5983 if (UNSPECIFIEDP (LFACE_STRIKE_THROUGH (lface)))
5984 LFACE_STRIKE_THROUGH (lface) = Qnil;
5986 if (UNSPECIFIEDP (LFACE_BOX (lface)))
5987 LFACE_BOX (lface) = Qnil;
5989 if (UNSPECIFIEDP (LFACE_INVERSE (lface)))
5990 LFACE_INVERSE (lface) = Qnil;
5992 if (UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
5994 /* This function is called so early that colors are not yet
5995 set in the frame parameter list. */
5996 Lisp_Object color = Fassq (Qforeground_color, f->param_alist);
5998 if (CONSP (color) && STRINGP (XCDR (color)))
5999 LFACE_FOREGROUND (lface) = XCDR (color);
6000 else if (FRAME_WINDOW_P (f))
6001 return 0;
6002 else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
6003 LFACE_FOREGROUND (lface) = build_string (unspecified_fg);
6004 else
6005 abort ();
6008 if (UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
6010 /* This function is called so early that colors are not yet
6011 set in the frame parameter list. */
6012 Lisp_Object color = Fassq (Qbackground_color, f->param_alist);
6013 if (CONSP (color) && STRINGP (XCDR (color)))
6014 LFACE_BACKGROUND (lface) = XCDR (color);
6015 else if (FRAME_WINDOW_P (f))
6016 return 0;
6017 else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
6018 LFACE_BACKGROUND (lface) = build_string (unspecified_bg);
6019 else
6020 abort ();
6023 if (UNSPECIFIEDP (LFACE_STIPPLE (lface)))
6024 LFACE_STIPPLE (lface) = Qnil;
6026 /* Realize the face; it must be fully-specified now. */
6027 xassert (lface_fully_specified_p (XVECTOR (lface)->contents));
6028 check_lface (lface);
6029 bcopy (XVECTOR (lface)->contents, attrs, sizeof attrs);
6030 face = realize_face (c, attrs, 0, NULL, DEFAULT_FACE_ID);
6031 return 1;
6035 /* Realize basic faces other than the default face in face cache C.
6036 SYMBOL is the face name, ID is the face id the realized face must
6037 have. The default face must have been realized already. */
6039 static void
6040 realize_named_face (f, symbol, id)
6041 struct frame *f;
6042 Lisp_Object symbol;
6043 int id;
6045 struct face_cache *c = FRAME_FACE_CACHE (f);
6046 Lisp_Object lface = lface_from_face_name (f, symbol, 0);
6047 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6048 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
6049 struct face *new_face;
6051 /* The default face must exist and be fully specified. */
6052 get_lface_attributes (f, Qdefault, attrs, 1);
6053 check_lface_attrs (attrs);
6054 xassert (lface_fully_specified_p (attrs));
6056 /* If SYMBOL isn't know as a face, create it. */
6057 if (NILP (lface))
6059 Lisp_Object frame;
6060 XSETFRAME (frame, f);
6061 lface = Finternal_make_lisp_face (symbol, frame);
6064 /* Merge SYMBOL's face with the default face. */
6065 get_lface_attributes (f, symbol, symbol_attrs, 1);
6066 merge_face_vectors (f, symbol_attrs, attrs, Qnil);
6068 /* Realize the face. */
6069 new_face = realize_face (c, attrs, 0, NULL, id);
6073 /* Realize the fully-specified face with attributes ATTRS in face
6074 cache CACHE for character C. If C is a multibyte character,
6075 BASE_FACE is a face that has the same attributes. Otherwise,
6076 BASE_FACE is ignored. If FORMER_FACE_ID is non-negative, it is an
6077 ID of face to remove before caching the new face. Value is a
6078 pointer to the newly created realized face. */
6080 static struct face *
6081 realize_face (cache, attrs, c, base_face, former_face_id)
6082 struct face_cache *cache;
6083 Lisp_Object *attrs;
6084 int c;
6085 struct face *base_face;
6086 int former_face_id;
6088 struct face *face;
6090 /* LFACE must be fully specified. */
6091 xassert (cache != NULL);
6092 check_lface_attrs (attrs);
6094 if (former_face_id >= 0 && cache->used > former_face_id)
6096 /* Remove the former face. */
6097 struct face *former_face = cache->faces_by_id[former_face_id];
6098 uncache_face (cache, former_face);
6099 free_realized_face (cache->f, former_face);
6102 if (FRAME_WINDOW_P (cache->f))
6103 face = realize_x_face (cache, attrs, c, base_face);
6104 else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
6105 face = realize_tty_face (cache, attrs, c);
6106 else
6107 abort ();
6109 /* Insert the new face. */
6110 cache_face (cache, face, lface_hash (attrs));
6111 #ifdef HAVE_WINDOW_SYSTEM
6112 if (FRAME_WINDOW_P (cache->f) && face->font == NULL)
6113 load_face_font (cache->f, face, c);
6114 #endif /* HAVE_WINDOW_SYSTEM */
6115 return face;
6119 /* Realize the fully-specified face with attributes ATTRS in face
6120 cache CACHE for character C. Do it for X frame CACHE->f. If C is
6121 a multibyte character, BASE_FACE is a face that has the same
6122 attributes. Otherwise, BASE_FACE is ignored. If the new face
6123 doesn't share font with the default face, a fontname is allocated
6124 from the heap and set in `font_name' of the new face, but it is not
6125 yet loaded here. Value is a pointer to the newly created realized
6126 face. */
6128 static struct face *
6129 realize_x_face (cache, attrs, c, base_face)
6130 struct face_cache *cache;
6131 Lisp_Object *attrs;
6132 int c;
6133 struct face *base_face;
6135 #ifdef HAVE_WINDOW_SYSTEM
6136 struct face *face, *default_face;
6137 struct frame *f;
6138 Lisp_Object stipple, overline, strike_through, box;
6140 xassert (FRAME_WINDOW_P (cache->f));
6141 xassert (SINGLE_BYTE_CHAR_P (c)
6142 || base_face);
6144 /* Allocate a new realized face. */
6145 face = make_realized_face (attrs);
6147 f = cache->f;
6149 /* If C is a multibyte character, we share all face attirbutes with
6150 BASE_FACE including the realized fontset. But, we must load a
6151 different font. */
6152 if (!SINGLE_BYTE_CHAR_P (c))
6154 bcopy (base_face, face, sizeof *face);
6155 face->gc = 0;
6157 /* Don't try to free the colors copied bitwise from BASE_FACE. */
6158 face->foreground_defaulted_p = 1;
6159 face->background_defaulted_p = 1;
6160 face->underline_defaulted_p = 1;
6161 face->overline_color_defaulted_p = 1;
6162 face->strike_through_color_defaulted_p = 1;
6163 face->box_color_defaulted_p = 1;
6165 /* to force realize_face to load font */
6166 face->font = NULL;
6167 return face;
6170 /* Now we are realizing a face for ASCII (and unibyte) characters. */
6172 /* Determine the font to use. Most of the time, the font will be
6173 the same as the font of the default face, so try that first. */
6174 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6175 if (default_face
6176 && FACE_SUITABLE_FOR_CHAR_P (default_face, c)
6177 && lface_same_font_attributes_p (default_face->lface, attrs))
6179 face->font = default_face->font;
6180 face->fontset = default_face->fontset;
6181 face->font_info_id = default_face->font_info_id;
6182 face->font_name = default_face->font_name;
6183 face->ascii_face = face;
6185 /* But, as we can't share the fontset, make a new realized
6186 fontset that has the same base fontset as of the default
6187 face. */
6188 face->fontset
6189 = make_fontset_for_ascii_face (f, default_face->fontset);
6191 else
6193 /* If the face attribute ATTRS specifies a fontset, use it as
6194 the base of a new realized fontset. Otherwise, use the same
6195 base fontset as of the default face. The base determines
6196 registry and encoding of a font. It may also determine
6197 foundry and family. The other fields of font name pattern
6198 are constructed from ATTRS. */
6199 int fontset = face_fontset (attrs);
6201 if ((fontset == -1) && default_face)
6202 fontset = default_face->fontset;
6203 face->fontset = make_fontset_for_ascii_face (f, fontset);
6204 face->font = NULL; /* to force realize_face to load font */
6207 /* Load colors, and set remaining attributes. */
6209 load_face_colors (f, face, attrs);
6211 /* Set up box. */
6212 box = attrs[LFACE_BOX_INDEX];
6213 if (STRINGP (box))
6215 /* A simple box of line width 1 drawn in color given by
6216 the string. */
6217 face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
6218 LFACE_BOX_INDEX);
6219 face->box = FACE_SIMPLE_BOX;
6220 face->box_line_width = 1;
6222 else if (INTEGERP (box))
6224 /* Simple box of specified line width in foreground color of the
6225 face. */
6226 xassert (XINT (box) > 0);
6227 face->box = FACE_SIMPLE_BOX;
6228 face->box_line_width = XFASTINT (box);
6229 face->box_color = face->foreground;
6230 face->box_color_defaulted_p = 1;
6232 else if (CONSP (box))
6234 /* `(:width WIDTH :color COLOR :shadow SHADOW)'. SHADOW
6235 being one of `raised' or `sunken'. */
6236 face->box = FACE_SIMPLE_BOX;
6237 face->box_color = face->foreground;
6238 face->box_color_defaulted_p = 1;
6239 face->box_line_width = 1;
6241 while (CONSP (box))
6243 Lisp_Object keyword, value;
6245 keyword = XCAR (box);
6246 box = XCDR (box);
6248 if (!CONSP (box))
6249 break;
6250 value = XCAR (box);
6251 box = XCDR (box);
6253 if (EQ (keyword, QCline_width))
6255 if (INTEGERP (value) && XINT (value) > 0)
6256 face->box_line_width = XFASTINT (value);
6258 else if (EQ (keyword, QCcolor))
6260 if (STRINGP (value))
6262 face->box_color = load_color (f, face, value,
6263 LFACE_BOX_INDEX);
6264 face->use_box_color_for_shadows_p = 1;
6267 else if (EQ (keyword, QCstyle))
6269 if (EQ (value, Qreleased_button))
6270 face->box = FACE_RAISED_BOX;
6271 else if (EQ (value, Qpressed_button))
6272 face->box = FACE_SUNKEN_BOX;
6277 /* Text underline, overline, strike-through. */
6279 if (EQ (attrs[LFACE_UNDERLINE_INDEX], Qt))
6281 /* Use default color (same as foreground color). */
6282 face->underline_p = 1;
6283 face->underline_defaulted_p = 1;
6284 face->underline_color = 0;
6286 else if (STRINGP (attrs[LFACE_UNDERLINE_INDEX]))
6288 /* Use specified color. */
6289 face->underline_p = 1;
6290 face->underline_defaulted_p = 0;
6291 face->underline_color
6292 = load_color (f, face, attrs[LFACE_UNDERLINE_INDEX],
6293 LFACE_UNDERLINE_INDEX);
6295 else if (NILP (attrs[LFACE_UNDERLINE_INDEX]))
6297 face->underline_p = 0;
6298 face->underline_defaulted_p = 0;
6299 face->underline_color = 0;
6302 overline = attrs[LFACE_OVERLINE_INDEX];
6303 if (STRINGP (overline))
6305 face->overline_color
6306 = load_color (f, face, attrs[LFACE_OVERLINE_INDEX],
6307 LFACE_OVERLINE_INDEX);
6308 face->overline_p = 1;
6310 else if (EQ (overline, Qt))
6312 face->overline_color = face->foreground;
6313 face->overline_color_defaulted_p = 1;
6314 face->overline_p = 1;
6317 strike_through = attrs[LFACE_STRIKE_THROUGH_INDEX];
6318 if (STRINGP (strike_through))
6320 face->strike_through_color
6321 = load_color (f, face, attrs[LFACE_STRIKE_THROUGH_INDEX],
6322 LFACE_STRIKE_THROUGH_INDEX);
6323 face->strike_through_p = 1;
6325 else if (EQ (strike_through, Qt))
6327 face->strike_through_color = face->foreground;
6328 face->strike_through_color_defaulted_p = 1;
6329 face->strike_through_p = 1;
6332 stipple = attrs[LFACE_STIPPLE_INDEX];
6333 if (!NILP (stipple))
6334 face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
6336 xassert (FACE_SUITABLE_FOR_CHAR_P (face, c));
6337 return face;
6338 #endif /* HAVE_WINDOW_SYSTEM */
6342 /* Map a specified color of face FACE on frame F to a tty color index.
6343 IDX is either LFACE_FOREGROUND_INDEX or LFACE_BACKGROUND_INDEX, and
6344 specifies which color to map. Set *DEFAULTED to 1 if mapping to the
6345 default foreground/background colors. */
6347 static void
6348 map_tty_color (f, face, idx, defaulted)
6349 struct frame *f;
6350 struct face *face;
6351 enum lface_attribute_index idx;
6352 int *defaulted;
6354 Lisp_Object frame, color, def;
6355 int foreground_p = idx == LFACE_FOREGROUND_INDEX;
6356 unsigned long default_pixel, default_other_pixel, pixel;
6358 xassert (idx == LFACE_FOREGROUND_INDEX || idx == LFACE_BACKGROUND_INDEX);
6360 if (foreground_p)
6362 pixel = default_pixel = FACE_TTY_DEFAULT_FG_COLOR;
6363 default_other_pixel = FACE_TTY_DEFAULT_BG_COLOR;
6365 else
6367 pixel = default_pixel = FACE_TTY_DEFAULT_BG_COLOR;
6368 default_other_pixel = FACE_TTY_DEFAULT_FG_COLOR;
6371 XSETFRAME (frame, f);
6372 color = face->lface[idx];
6374 if (STRINGP (color)
6375 && XSTRING (color)->size
6376 && CONSP (Vtty_defined_color_alist)
6377 && (def = assq_no_quit (color, call1 (Qtty_color_alist, frame)),
6378 CONSP (def)))
6380 /* Associations in tty-defined-color-alist are of the form
6381 (NAME INDEX R G B). We need the INDEX part. */
6382 pixel = XINT (XCAR (XCDR (def)));
6385 if (pixel == default_pixel && STRINGP (color))
6387 pixel = load_color (f, face, color, idx);
6389 #if defined (MSDOS) || defined (WINDOWSNT)
6390 /* If the foreground of the default face is the default color,
6391 use the foreground color defined by the frame. */
6392 #ifdef MSDOS
6393 if (FRAME_MSDOS_P (f))
6395 #endif /* MSDOS */
6396 if (pixel == default_pixel
6397 || pixel == FACE_TTY_DEFAULT_COLOR)
6399 if (foreground_p)
6400 pixel = FRAME_FOREGROUND_PIXEL (f);
6401 else
6402 pixel = FRAME_BACKGROUND_PIXEL (f);
6403 face->lface[idx] = tty_color_name (f, pixel);
6404 *defaulted = 1;
6406 else if (pixel == default_other_pixel)
6408 if (foreground_p)
6409 pixel = FRAME_BACKGROUND_PIXEL (f);
6410 else
6411 pixel = FRAME_FOREGROUND_PIXEL (f);
6412 face->lface[idx] = tty_color_name (f, pixel);
6413 *defaulted = 1;
6415 #ifdef MSDOS
6417 #endif
6418 #endif /* MSDOS or WINDOWSNT */
6421 if (foreground_p)
6422 face->foreground = pixel;
6423 else
6424 face->background = pixel;
6428 /* Realize the fully-specified face with attributes ATTRS in face
6429 cache CACHE for character C. Do it for TTY frame CACHE->f. Value is a
6430 pointer to the newly created realized face. */
6432 static struct face *
6433 realize_tty_face (cache, attrs, c)
6434 struct face_cache *cache;
6435 Lisp_Object *attrs;
6436 int c;
6438 struct face *face;
6439 int weight, slant;
6440 int face_colors_defaulted = 0;
6441 struct frame *f = cache->f;
6443 /* Frame must be a termcap frame. */
6444 xassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f));
6446 /* Allocate a new realized face. */
6447 face = make_realized_face (attrs);
6448 face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty";
6450 /* Map face attributes to TTY appearances. We map slant to
6451 dimmed text because we want italic text to appear differently
6452 and because dimmed text is probably used infrequently. */
6453 weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
6454 slant = face_numeric_slant (attrs[LFACE_SLANT_INDEX]);
6456 if (weight > XLFD_WEIGHT_MEDIUM)
6457 face->tty_bold_p = 1;
6458 if (weight < XLFD_WEIGHT_MEDIUM || slant != XLFD_SLANT_ROMAN)
6459 face->tty_dim_p = 1;
6460 if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
6461 face->tty_underline_p = 1;
6462 if (!NILP (attrs[LFACE_INVERSE_INDEX]))
6463 face->tty_reverse_p = 1;
6465 /* Map color names to color indices. */
6466 map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
6467 map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted);
6469 /* Swap colors if face is inverse-video. If the colors are taken
6470 from the frame colors, they are already inverted, since the
6471 frame-creation function calls x-handle-reverse-video. */
6472 if (face->tty_reverse_p && !face_colors_defaulted)
6474 unsigned long tem = face->foreground;
6475 face->foreground = face->background;
6476 face->background = tem;
6479 if (tty_suppress_bold_inverse_default_colors_p
6480 && face->tty_bold_p
6481 && face->background == FACE_TTY_DEFAULT_FG_COLOR
6482 && face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
6483 face->tty_bold_p = 0;
6485 return face;
6489 DEFUN ("tty-suppress-bold-inverse-default-colors",
6490 Ftty_suppress_bold_inverse_default_colors,
6491 Stty_suppress_bold_inverse_default_colors, 1, 1, 0,
6492 "Suppress/allow boldness of faces with inverse default colors.\n\
6493 SUPPRESS non-nil means suppress it.\n\
6494 This affects bold faces on TTYs whose foreground is the default background\n\
6495 color of the display and whose background is the default foreground color.\n\
6496 For such faces, the bold face attribute is ignored if this variable\n\
6497 is non-nil.")
6498 (suppress)
6499 Lisp_Object suppress;
6501 tty_suppress_bold_inverse_default_colors_p = !NILP (suppress);
6502 ++face_change_count;
6503 return suppress;
6508 /***********************************************************************
6509 Computing Faces
6510 ***********************************************************************/
6512 /* Return the ID of the face to use to display character CH with face
6513 property PROP on frame F in current_buffer. */
6516 compute_char_face (f, ch, prop)
6517 struct frame *f;
6518 int ch;
6519 Lisp_Object prop;
6521 int face_id;
6523 if (NILP (current_buffer->enable_multibyte_characters))
6524 ch = -1;
6526 if (NILP (prop))
6528 struct face *face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6529 face_id = FACE_FOR_CHAR (f, face, ch);
6531 else
6533 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6534 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6535 bcopy (default_face->lface, attrs, sizeof attrs);
6536 merge_face_vector_with_property (f, attrs, prop);
6537 face_id = lookup_face (f, attrs, ch, NULL);
6540 return face_id;
6544 /* Return the face ID associated with buffer position POS for
6545 displaying ASCII characters. Return in *ENDPTR the position at
6546 which a different face is needed, as far as text properties and
6547 overlays are concerned. W is a window displaying current_buffer.
6549 REGION_BEG, REGION_END delimit the region, so it can be
6550 highlighted.
6552 LIMIT is a position not to scan beyond. That is to limit the time
6553 this function can take.
6555 If MOUSE is non-zero, use the character's mouse-face, not its face.
6557 The face returned is suitable for displaying ASCII characters. */
6560 face_at_buffer_position (w, pos, region_beg, region_end,
6561 endptr, limit, mouse)
6562 struct window *w;
6563 int pos;
6564 int region_beg, region_end;
6565 int *endptr;
6566 int limit;
6567 int mouse;
6569 struct frame *f = XFRAME (w->frame);
6570 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6571 Lisp_Object prop, position;
6572 int i, noverlays;
6573 Lisp_Object *overlay_vec;
6574 Lisp_Object frame;
6575 int endpos;
6576 Lisp_Object propname = mouse ? Qmouse_face : Qface;
6577 Lisp_Object limit1, end;
6578 struct face *default_face;
6579 int multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
6581 /* W must display the current buffer. We could write this function
6582 to use the frame and buffer of W, but right now it doesn't. */
6583 /* xassert (XBUFFER (w->buffer) == current_buffer); */
6585 XSETFRAME (frame, f);
6586 XSETFASTINT (position, pos);
6588 endpos = ZV;
6589 if (pos < region_beg && region_beg < endpos)
6590 endpos = region_beg;
6592 /* Get the `face' or `mouse_face' text property at POS, and
6593 determine the next position at which the property changes. */
6594 prop = Fget_text_property (position, propname, w->buffer);
6595 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6596 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
6597 if (INTEGERP (end))
6598 endpos = XINT (end);
6600 /* Look at properties from overlays. */
6602 int next_overlay;
6603 int len;
6605 /* First try with room for 40 overlays. */
6606 len = 40;
6607 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6608 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
6609 &next_overlay, NULL, 0);
6611 /* If there are more than 40, make enough space for all, and try
6612 again. */
6613 if (noverlays > len)
6615 len = noverlays;
6616 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6617 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
6618 &next_overlay, NULL, 0);
6621 if (next_overlay < endpos)
6622 endpos = next_overlay;
6625 *endptr = endpos;
6627 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6629 /* Optimize common cases where we can use the default face. */
6630 if (noverlays == 0
6631 && NILP (prop)
6632 && !(pos >= region_beg && pos < region_end))
6633 return DEFAULT_FACE_ID;
6635 /* Begin with attributes from the default face. */
6636 bcopy (default_face->lface, attrs, sizeof attrs);
6638 /* Merge in attributes specified via text properties. */
6639 if (!NILP (prop))
6640 merge_face_vector_with_property (f, attrs, prop);
6642 /* Now merge the overlay data. */
6643 noverlays = sort_overlays (overlay_vec, noverlays, w);
6644 for (i = 0; i < noverlays; i++)
6646 Lisp_Object oend;
6647 int oendpos;
6649 prop = Foverlay_get (overlay_vec[i], propname);
6650 if (!NILP (prop))
6651 merge_face_vector_with_property (f, attrs, prop);
6653 oend = OVERLAY_END (overlay_vec[i]);
6654 oendpos = OVERLAY_POSITION (oend);
6655 if (oendpos < endpos)
6656 endpos = oendpos;
6659 /* If in the region, merge in the region face. */
6660 if (pos >= region_beg && pos < region_end)
6662 Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
6663 merge_face_vectors (f, XVECTOR (region_face)->contents, attrs, Qnil);
6665 if (region_end < endpos)
6666 endpos = region_end;
6669 *endptr = endpos;
6671 /* Look up a realized face with the given face attributes,
6672 or realize a new one for ASCII characters. */
6673 return lookup_face (f, attrs, 0, NULL);
6677 /* Compute the face at character position POS in Lisp string STRING on
6678 window W, for ASCII characters.
6680 If STRING is an overlay string, it comes from position BUFPOS in
6681 current_buffer, otherwise BUFPOS is zero to indicate that STRING is
6682 not an overlay string. W must display the current buffer.
6683 REGION_BEG and REGION_END give the start and end positions of the
6684 region; both are -1 if no region is visible. BASE_FACE_ID is the
6685 id of the basic face to merge with. It is usually equal to
6686 DEFAULT_FACE_ID but can be MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID
6687 for strings displayed in the mode or top line.
6689 Set *ENDPTR to the next position where to check for faces in
6690 STRING; -1 if the face is constant from POS to the end of the
6691 string.
6693 Value is the id of the face to use. The face returned is suitable
6694 for displaying ASCII characters. */
6697 face_at_string_position (w, string, pos, bufpos, region_beg,
6698 region_end, endptr, base_face_id)
6699 struct window *w;
6700 Lisp_Object string;
6701 int pos, bufpos;
6702 int region_beg, region_end;
6703 int *endptr;
6704 enum face_id base_face_id;
6706 Lisp_Object prop, position, end, limit;
6707 struct frame *f = XFRAME (WINDOW_FRAME (w));
6708 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6709 struct face *base_face;
6710 int multibyte_p = STRING_MULTIBYTE (string);
6712 /* Get the value of the face property at the current position within
6713 STRING. Value is nil if there is no face property. */
6714 XSETFASTINT (position, pos);
6715 prop = Fget_text_property (position, Qface, string);
6717 /* Get the next position at which to check for faces. Value of end
6718 is nil if face is constant all the way to the end of the string.
6719 Otherwise it is a string position where to check faces next.
6720 Limit is the maximum position up to which to check for property
6721 changes in Fnext_single_property_change. Strings are usually
6722 short, so set the limit to the end of the string. */
6723 XSETFASTINT (limit, XSTRING (string)->size);
6724 end = Fnext_single_property_change (position, Qface, string, limit);
6725 if (INTEGERP (end))
6726 *endptr = XFASTINT (end);
6727 else
6728 *endptr = -1;
6730 base_face = FACE_FROM_ID (f, base_face_id);
6731 xassert (base_face);
6733 /* Optimize the default case that there is no face property and we
6734 are not in the region. */
6735 if (NILP (prop)
6736 && (base_face_id != DEFAULT_FACE_ID
6737 /* BUFPOS <= 0 means STRING is not an overlay string, so
6738 that the region doesn't have to be taken into account. */
6739 || bufpos <= 0
6740 || bufpos < region_beg
6741 || bufpos >= region_end)
6742 && (multibyte_p
6743 /* We can't realize faces for different charsets differently
6744 if we don't have fonts, so we can stop here if not working
6745 on a window-system frame. */
6746 || !FRAME_WINDOW_P (f)
6747 || FACE_SUITABLE_FOR_CHAR_P (base_face, 0)))
6748 return base_face->id;
6750 /* Begin with attributes from the base face. */
6751 bcopy (base_face->lface, attrs, sizeof attrs);
6753 /* Merge in attributes specified via text properties. */
6754 if (!NILP (prop))
6755 merge_face_vector_with_property (f, attrs, prop);
6757 /* If in the region, merge in the region face. */
6758 if (bufpos
6759 && bufpos >= region_beg
6760 && bufpos < region_end)
6762 Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
6763 merge_face_vectors (f, XVECTOR (region_face)->contents, attrs, Qnil);
6766 /* Look up a realized face with the given face attributes,
6767 or realize a new one for ASCII characters. */
6768 return lookup_face (f, attrs, 0, NULL);
6773 /***********************************************************************
6774 Tests
6775 ***********************************************************************/
6777 #if GLYPH_DEBUG
6779 /* Print the contents of the realized face FACE to stderr. */
6781 static void
6782 dump_realized_face (face)
6783 struct face *face;
6785 fprintf (stderr, "ID: %d\n", face->id);
6786 #ifdef HAVE_X_WINDOWS
6787 fprintf (stderr, "gc: %d\n", (int) face->gc);
6788 #endif
6789 fprintf (stderr, "foreground: 0x%lx (%s)\n",
6790 face->foreground,
6791 XSTRING (face->lface[LFACE_FOREGROUND_INDEX])->data);
6792 fprintf (stderr, "background: 0x%lx (%s)\n",
6793 face->background,
6794 XSTRING (face->lface[LFACE_BACKGROUND_INDEX])->data);
6795 fprintf (stderr, "font_name: %s (%s)\n",
6796 face->font_name,
6797 XSTRING (face->lface[LFACE_FAMILY_INDEX])->data);
6798 #ifdef HAVE_X_WINDOWS
6799 fprintf (stderr, "font = %p\n", face->font);
6800 #endif
6801 fprintf (stderr, "font_info_id = %d\n", face->font_info_id);
6802 fprintf (stderr, "fontset: %d\n", face->fontset);
6803 fprintf (stderr, "underline: %d (%s)\n",
6804 face->underline_p,
6805 XSTRING (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))->data);
6806 fprintf (stderr, "hash: %d\n", face->hash);
6807 fprintf (stderr, "charset: %d\n", face->charset);
6811 DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, "")
6813 Lisp_Object n;
6815 if (NILP (n))
6817 int i;
6819 fprintf (stderr, "font selection order: ");
6820 for (i = 0; i < DIM (font_sort_order); ++i)
6821 fprintf (stderr, "%d ", font_sort_order[i]);
6822 fprintf (stderr, "\n");
6824 fprintf (stderr, "alternative fonts: ");
6825 debug_print (Vface_alternative_font_family_alist);
6826 fprintf (stderr, "\n");
6828 for (i = 0; i < FRAME_FACE_CACHE (SELECTED_FRAME ())->used; ++i)
6829 Fdump_face (make_number (i));
6831 else
6833 struct face *face;
6834 CHECK_NUMBER (n, 0);
6835 face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
6836 if (face == NULL)
6837 error ("Not a valid face");
6838 dump_realized_face (face);
6841 return Qnil;
6845 DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
6846 0, 0, 0, "")
6849 fprintf (stderr, "number of colors = %d\n", ncolors_allocated);
6850 fprintf (stderr, "number of pixmaps = %d\n", npixmaps_allocated);
6851 fprintf (stderr, "number of GCs = %d\n", ngcs);
6852 return Qnil;
6855 #endif /* GLYPH_DEBUG != 0 */
6859 /***********************************************************************
6860 Initialization
6861 ***********************************************************************/
6863 void
6864 syms_of_xfaces ()
6866 Qface = intern ("face");
6867 staticpro (&Qface);
6868 Qbitmap_spec_p = intern ("bitmap-spec-p");
6869 staticpro (&Qbitmap_spec_p);
6870 Qframe_update_face_colors = intern ("frame-update-face-colors");
6871 staticpro (&Qframe_update_face_colors);
6873 /* Lisp face attribute keywords. */
6874 QCfamily = intern (":family");
6875 staticpro (&QCfamily);
6876 QCheight = intern (":height");
6877 staticpro (&QCheight);
6878 QCweight = intern (":weight");
6879 staticpro (&QCweight);
6880 QCslant = intern (":slant");
6881 staticpro (&QCslant);
6882 QCunderline = intern (":underline");
6883 staticpro (&QCunderline);
6884 QCinverse_video = intern (":inverse-video");
6885 staticpro (&QCinverse_video);
6886 QCreverse_video = intern (":reverse-video");
6887 staticpro (&QCreverse_video);
6888 QCforeground = intern (":foreground");
6889 staticpro (&QCforeground);
6890 QCbackground = intern (":background");
6891 staticpro (&QCbackground);
6892 QCstipple = intern (":stipple");;
6893 staticpro (&QCstipple);
6894 QCwidth = intern (":width");
6895 staticpro (&QCwidth);
6896 QCfont = intern (":font");
6897 staticpro (&QCfont);
6898 QCbold = intern (":bold");
6899 staticpro (&QCbold);
6900 QCitalic = intern (":italic");
6901 staticpro (&QCitalic);
6902 QCoverline = intern (":overline");
6903 staticpro (&QCoverline);
6904 QCstrike_through = intern (":strike-through");
6905 staticpro (&QCstrike_through);
6906 QCbox = intern (":box");
6907 staticpro (&QCbox);
6908 QCinherit = intern (":inherit");
6909 staticpro (&QCinherit);
6911 /* Symbols used for Lisp face attribute values. */
6912 QCcolor = intern (":color");
6913 staticpro (&QCcolor);
6914 QCline_width = intern (":line-width");
6915 staticpro (&QCline_width);
6916 QCstyle = intern (":style");
6917 staticpro (&QCstyle);
6918 Qreleased_button = intern ("released-button");
6919 staticpro (&Qreleased_button);
6920 Qpressed_button = intern ("pressed-button");
6921 staticpro (&Qpressed_button);
6922 Qnormal = intern ("normal");
6923 staticpro (&Qnormal);
6924 Qultra_light = intern ("ultra-light");
6925 staticpro (&Qultra_light);
6926 Qextra_light = intern ("extra-light");
6927 staticpro (&Qextra_light);
6928 Qlight = intern ("light");
6929 staticpro (&Qlight);
6930 Qsemi_light = intern ("semi-light");
6931 staticpro (&Qsemi_light);
6932 Qsemi_bold = intern ("semi-bold");
6933 staticpro (&Qsemi_bold);
6934 Qbold = intern ("bold");
6935 staticpro (&Qbold);
6936 Qextra_bold = intern ("extra-bold");
6937 staticpro (&Qextra_bold);
6938 Qultra_bold = intern ("ultra-bold");
6939 staticpro (&Qultra_bold);
6940 Qoblique = intern ("oblique");
6941 staticpro (&Qoblique);
6942 Qitalic = intern ("italic");
6943 staticpro (&Qitalic);
6944 Qreverse_oblique = intern ("reverse-oblique");
6945 staticpro (&Qreverse_oblique);
6946 Qreverse_italic = intern ("reverse-italic");
6947 staticpro (&Qreverse_italic);
6948 Qultra_condensed = intern ("ultra-condensed");
6949 staticpro (&Qultra_condensed);
6950 Qextra_condensed = intern ("extra-condensed");
6951 staticpro (&Qextra_condensed);
6952 Qcondensed = intern ("condensed");
6953 staticpro (&Qcondensed);
6954 Qsemi_condensed = intern ("semi-condensed");
6955 staticpro (&Qsemi_condensed);
6956 Qsemi_expanded = intern ("semi-expanded");
6957 staticpro (&Qsemi_expanded);
6958 Qexpanded = intern ("expanded");
6959 staticpro (&Qexpanded);
6960 Qextra_expanded = intern ("extra-expanded");
6961 staticpro (&Qextra_expanded);
6962 Qultra_expanded = intern ("ultra-expanded");
6963 staticpro (&Qultra_expanded);
6964 Qbackground_color = intern ("background-color");
6965 staticpro (&Qbackground_color);
6966 Qforeground_color = intern ("foreground-color");
6967 staticpro (&Qforeground_color);
6968 Qunspecified = intern ("unspecified");
6969 staticpro (&Qunspecified);
6971 Qface_alias = intern ("face-alias");
6972 staticpro (&Qface_alias);
6973 Qdefault = intern ("default");
6974 staticpro (&Qdefault);
6975 Qtool_bar = intern ("tool-bar");
6976 staticpro (&Qtool_bar);
6977 Qregion = intern ("region");
6978 staticpro (&Qregion);
6979 Qfringe = intern ("fringe");
6980 staticpro (&Qfringe);
6981 Qheader_line = intern ("header-line");
6982 staticpro (&Qheader_line);
6983 Qscroll_bar = intern ("scroll-bar");
6984 staticpro (&Qscroll_bar);
6985 Qmenu = intern ("menu");
6986 staticpro (&Qmenu);
6987 Qcursor = intern ("cursor");
6988 staticpro (&Qcursor);
6989 Qborder = intern ("border");
6990 staticpro (&Qborder);
6991 Qmouse = intern ("mouse");
6992 staticpro (&Qmouse);
6993 Qtty_color_desc = intern ("tty-color-desc");
6994 staticpro (&Qtty_color_desc);
6995 Qtty_color_by_index = intern ("tty-color-by-index");
6996 staticpro (&Qtty_color_by_index);
6997 Qtty_color_alist = intern ("tty-color-alist");
6998 staticpro (&Qtty_color_alist);
7000 Vface_alternative_font_family_alist = Qnil;
7001 staticpro (&Vface_alternative_font_family_alist);
7003 defsubr (&Sinternal_make_lisp_face);
7004 defsubr (&Sinternal_lisp_face_p);
7005 defsubr (&Sinternal_set_lisp_face_attribute);
7006 #ifdef HAVE_WINDOW_SYSTEM
7007 defsubr (&Sinternal_set_lisp_face_attribute_from_resource);
7008 #endif
7009 defsubr (&Scolor_gray_p);
7010 defsubr (&Scolor_supported_p);
7011 defsubr (&Sinternal_get_lisp_face_attribute);
7012 defsubr (&Sinternal_lisp_face_attribute_values);
7013 defsubr (&Sinternal_lisp_face_equal_p);
7014 defsubr (&Sinternal_lisp_face_empty_p);
7015 defsubr (&Sinternal_copy_lisp_face);
7016 defsubr (&Sinternal_merge_in_global_face);
7017 defsubr (&Sface_font);
7018 defsubr (&Sframe_face_alist);
7019 defsubr (&Sinternal_set_font_selection_order);
7020 defsubr (&Sinternal_set_alternative_font_family_alist);
7021 #if GLYPH_DEBUG
7022 defsubr (&Sdump_face);
7023 defsubr (&Sshow_face_resources);
7024 #endif /* GLYPH_DEBUG */
7025 defsubr (&Sclear_face_cache);
7026 defsubr (&Stty_suppress_bold_inverse_default_colors);
7028 #if defined DEBUG_X_COLORS && defined HAVE_X_WINDOWS
7029 defsubr (&Sdump_colors);
7030 #endif
7032 DEFVAR_LISP ("font-list-limit", &Vfont_list_limit,
7033 "*Limit for font matching.\n\
7034 If an integer > 0, font matching functions won't load more than\n\
7035 that number of fonts when searching for a matching font.");
7036 Vfont_list_limit = make_number (DEFAULT_FONT_LIST_LIMIT);
7038 DEFVAR_LISP ("face-new-frame-defaults", &Vface_new_frame_defaults,
7039 "List of global face definitions (for internal use only.)");
7040 Vface_new_frame_defaults = Qnil;
7042 DEFVAR_LISP ("face-default-stipple", &Vface_default_stipple,
7043 "*Default stipple pattern used on monochrome displays.\n\
7044 This stipple pattern is used on monochrome displays\n\
7045 instead of shades of gray for a face background color.\n\
7046 See `set-face-stipple' for possible values for this variable.");
7047 Vface_default_stipple = build_string ("gray3");
7049 DEFVAR_LISP ("tty-defined-color-alist", &Vtty_defined_color_alist,
7050 "An alist of defined terminal colors and their RGB values.");
7051 Vtty_defined_color_alist = Qnil;
7053 #if SCALABLE_FONTS
7055 DEFVAR_LISP ("scalable-fonts-allowed", &Vscalable_fonts_allowed,
7056 "Allowed scalable fonts.\n\
7057 A value of nil means don't allow any scalable fonts.\n\
7058 A value of t means allow any scalable font.\n\
7059 Otherwise, value must be a list of regular expressions. A font may be\n\
7060 scaled if its name matches a regular expression in the list.");
7061 #ifdef WINDOWSNT
7062 /* Windows uses mainly truetype fonts, so disallowing scalable fonts
7063 by default limits the fonts available severely. */
7064 Vscalable_fonts_allowed = Qt;
7065 #else
7066 Vscalable_fonts_allowed = Qnil;
7067 #endif
7068 #endif /* SCALABLE_FONTS */
7070 #ifdef HAVE_WINDOW_SYSTEM
7071 defsubr (&Sbitmap_spec_p);
7072 defsubr (&Sx_list_fonts);
7073 defsubr (&Sinternal_face_x_get_resource);
7074 defsubr (&Sx_family_fonts);
7075 defsubr (&Sx_font_family_list);
7076 #endif /* HAVE_WINDOW_SYSTEM */